Skip to content

fix(hy-check): track user-defined methods and receiver/struct sharing (#120) - #121

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
Bounty track: #5

Summary

Closes the hy-check soundness gap where user-defined methods (fn (r T) method(...)) were dropped during table construction and method receivers (callee = Expr::Field { base, .. }), reference-bearing composite arguments (extract(h)), multi-value unpacks (n, m := h.pair()), and ?-unwrapped calls (Expr::Try) bypassed A1b alias/may-share freeze and non_owned_origin propagation.

What Changed

  1. compiler/crates/hy-check/src/model.rs & compiler/crates/hy-check/src/lib.rs:
    • Added methods: HashMap<(String, String), &'a FnDecl> to Checker<'a>.
    • Indexed user-defined methods (f.receiver.is_some()) by (receiver_struct_name, method_name) in build_tables while keeping top-level functions in ck.fns.
  2. compiler/crates/hy-check/src/shape.rs:
    • Added lookup_user_method (resolving both value S and pointer *S struct receivers) and resolve_call_decl.
    • Updated call_shape, ty_of_expr, multi_value_shapes, and multi_value_tys to resolve user-defined method return shapes and types.
  3. compiler/crates/hy-check/src/loans.rs:
    • In process_call (Resolved::Method), lent handle arguments for user-defined method calls (lend_handle_args, A7 borrow-by-default).
    • Added unwrap_parens_and_try, link_share, call_source_roots, and record_call_sharing to link non-moved method receivers (callee = Expr::Field { base, .. }) and call arguments (binding_may_share) into st.may_share / st.aliases and propagate non_owned_origin across single-value defines, rebinds, multi-value unpacks (n, m := h.pair(), n, m = h.pair()), and ?-unwrapped calls (m := h.try_data()?).
  4. Unit Tests (compiler/crates/hy-check/src/lib.rs):
    • user_method_call_extracting_map_freezes_receiver_on_move_e3003
    • user_method_call_rebind_and_ascribed_define_freeze_receiver_e3003
    • toplevel_fn_extracting_map_from_struct_freezes_arg_on_move_e3003
    • non_owned_receiver_and_param_extractions_reject_move_e3004
    • multi_return_and_try_calls_track_sharing_and_freeze_e3003

Verification

  • cargo test --manifest-path compiler/Cargo.toml --workspace: all tests pass (including 5 new unit tests in hy-check).
  • cargo clippy --manifest-path compiler/Cargo.toml --workspace --tests -- -D warnings: 0 warnings.
  • python3 tools/corpus_harness.py: 27/27 verdict agreement, tripwire not fired.
  • python3 tools/differential_loop.py: 10/10 accept-side, 17/17 reject-side, FULL AGREEMENT.
  • Reproducer method_repro.hy from [soundness] User-defined method calls, struct-to-reference extractions, and ?-unwrapped calls bypass A1b freeze #120 is now rejected with HYB-E3003 (tier0_rule: "A1b").

Payout / Wallet Addresses (Bounty Track #5)

  • USDT (TRC20): TCQwxbpYVdRWYNDs1JbnKyVHNRVaRJg1io
  • USDT / USDC (ERC20 / BEP20): 0x76d1c4283a2ff662ccf85c1f57655c29b4256756
  • USDC (Solana): 6dX8oqvvHj6Q936PVyTjVYKVk45soNpJ234aVqMm6ZJm

@limitlessprojects

Copy link
Copy Markdown
Owner

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. No action needed from you.

@sonson0910

Copy link
Copy Markdown
Contributor Author

Thank you for the triage note! Heads-up: GitHub automatically closed this PR (#121) at 10:18:15Z because commit 6344d496 (Merge pr-122 (honru09, fixes #121)) had a typo in fixes #121, and GitHub does not allow non-collaborators to reopen a commit-closed PR.

I have rebased fix/method-call-soundness cleanly onto main (c09e992 / pr-162's collect_ref_roots) and opened replacement PR #197 (#197) for issue #120 so it stays visible in gh pr list --state open.

@limitlessprojects

Copy link
Copy Markdown
Owner

Confirmed and thank you for the precise diagnosis (and for opening #197 with the rebase already done — exactly the right move). The fixes #121 string in pr-122's merge message was a typo on the maintainer side; this PR closed itself as a side effect, and the conveyor now reserves closing keywords for issue numbers only, so this cannot recur. #197 is the live successor and inherits this PR's queued slot and bounty standing for #120 — its triage lands with the current wave. Keeping this closed with a pointer to #197 so the open list stays honest.

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