Skip to content

fix(hy-check): track user-defined methods and multi-return/ascribed call sharing (#120, rebased replacement for auto-closed #121) - #197

Closed
sonson0910 wants to merge 1 commit into
limitlessprojects:mainfrom
sonson0910:fix/method-call-soundness
Closed

sonson0910 wants to merge 1 commit into
limitlessprojects:mainfrom
sonson0910:fix/method-call-soundness

Conversation

@sonson0910

@sonson0910 sonson0910 commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #120 (replacement for #121, which was accidentally auto-closed by GitHub when commit 6344d496 on main merged pr-122 with fixes #121 instead of fixes #119, before the maintainer triage comment on #121).

Summary (Rebased onto c09e992 / pr-162)

Per the maintainer triage on #121:

"Triage (2026-10-15, AI maintainer): real gap (#120 — method calls, struct-to-reference extractions, ?-unwrapped call results bypass receiver/struct sharing), and the approach composes with the seam that just landed (pr-162's generalized collect_ref_roots covers part of the same reach — your receiver/? halves remain live). Queued in the conveyor; will likely need a rebase against the new collector."

This branch is cleanly rebased onto main (c09e992) to compose directly with pr-162's collect_ref_roots:

  1. User-defined method table (ck.methods): Indexes user-defined struct/pointer-receiver methods separately from top-level ck.fns (preserving #57's non-impersonation invariant) and resolves their return shapes/types in call_shape, ty_of_expr, multi_value_shapes, multi_value_tys, and process_call handle lending.
  2. Multi-value & ascribed call sharing: Wires record_may_share and record_alias into multi-value local defines (n, m := h.pair()) and multi-value rebinds (n, m = h.pair()), and consults the target binding's resolved shape so multi-return/ascribed call extractions record sharing on reference-bearing targets without false-positive edges on scalar outputs (n).

Verification

  • cargo test --workspace: all 403 tests pass (0 failed).

@limitlessprojects

Copy link
Copy Markdown
Owner

Triage (2026-10-15, AI maintainer, post-CI-repair): the rebased successor of the accidentally-closed pr-121 (method calls, struct-to-reference extractions, ?-unwrapped call results vs the sharing analysis) — the rebase onto pr-162's collect_ref_roots is exactly right. Queued in the checker conveyor after the copy-may-share family; your predecessor slot and bounty standing for issue #120 carry over.

@sonson0910
sonson0910 force-pushed the fix/method-call-soundness branch 2 times, most recently from 212afaf to 61dadd9 Compare October 17, 2026 02:56
@limitlessprojects

Copy link
Copy Markdown
Owner

Wave-2 triage: queued — next tier (carried from wave 1). Fixes #120 (user-defined methods, multi-return/ascribed call sharing).

@sonson0910
sonson0910 force-pushed the fix/method-call-soundness branch from 61dadd9 to 56d84a3 Compare October 17, 2026 05:45
@sonson0910

Copy link
Copy Markdown
Contributor Author

Rebased cleanly onto latest main (cad1375, 56d84a3), preserving #355's check_call_const_writes alongside user-defined method tracking (#120). Full cargo test --workspace passes with 0 failures.

@sonson0910

Copy link
Copy Markdown
Contributor Author

Rebase & Prior-Art Cross-Reference (5b2a643 on e2a5f7d)

Rebased cleanly onto origin/main (e2a5f7d). For triage cross-reference with later submissions (#447, #456, #457):

@sonson0910
sonson0910 force-pushed the fix/method-call-soundness branch 2 times, most recently from 630d293 to a4f2994 Compare October 17, 2026 18:20
@sonson0910
sonson0910 force-pushed the fix/method-call-soundness branch from a4f2994 to b9d6a5e Compare October 18, 2026 02:05
@limitlessprojects

Copy link
Copy Markdown
Owner

Thank you, @sonson0910 — the user-defined method table + multi-return/ascribed call-sharing design was the right attack on #120, and the maintainer triage's "composes with pr-162's collector" call is borne out by what happened next.

Closing as subsumed: all five scenarios your inline tests pin reject on current main (verified today at ff56902 against the shipped hyb; cargo 1069/0, corpus 78/78, differential FULL 23+55):

your test main today
method-receiver extraction m = h.data() + task worker(move m) + h.m["main"]=2 REJECT E3003 (A1b)
ascribed define var m map[string]int = h.data() (rebind + define variants) REJECT E3003 (A1b)
multi-return n, m := h.pair() + move of the map result REJECT E3003 (A1b)
top-level fn m := extract(h) + move REJECT E3003 (A1b)
non-owned receiver/param leak (fn (h holder) leak moving h.data() out) REJECT E3004 (A1b)
m := h.try_data()? (?-unwrapped variant from issue #120) REJECT E3003 (A1b)

Why not a direct merge: this branch predates the last ~400 commits of checker work; its model.rs hunk deletes the collect_ref_roots Expr::FnLit arm that main's newer machinery (#455 callee-store sharing, #502 nested-closure capture scope) now relies on, so the deletion would reopen holes the corpus already pins. The soundness property is enforced on main through the generalized collectors + operand type-check line instead: pr-430 (7dc16e8), pr-455 (13df097 family), pr-502 (8aeaddf), pr-536 (a1b8a6c).

Issue #120's reported bypass family is fully covered by the checks above; the maintainer may close it with this verification. Thanks for the disciplined test-first PR — your five scenarios now double as the verification checklist for #120.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[soundness] User-defined method calls, struct-to-reference extractions, and ?-unwrapped calls bypass A1b freeze

2 participants