Skip to content

fix(hy-check): enforce T24 index projection, closure slot-loan rebind & nested borrow_bindings escape (HYB-E3104) (#1445) - #1720

Open
ubelai wants to merge 1 commit into
limitlessprojects:mainfrom
ubelai:fix/slot-loan-t24-rebind-and-escape-e3104
Open

ubelai wants to merge 1 commit into
limitlessprojects:mainfrom
ubelai:fix/slot-loan-t24-rebind-and-escape-e3104

Conversation

@ubelai

@ubelai ubelai commented Oct 25, 2026

Copy link
Copy Markdown

Fixes #1445

Summary

Closes three HYB-E3104 (T24 / O8 / O2 LOAN-ESCAPE) soundness and buildable-Go gaps on map-slot loans (n := &m[k]):

  1. compiler/crates/hy-check/src/addr_loan.rs (walk_addr_of_loan_projections, line 337):
    • Match Expr::Field { .. } | Expr::Index { .. } (matching the existing docstring at addr_loan.rs:153-156) so taking the address of an array or slice index projection rooted at a map-slot loan (&n.arr[0], &n.fixed[0]) is rejected with HYB-E3104 (T24).
  2. compiler/crates/hy-check/src/emit_guard.rs (check_stmt_emit_guard_inner, line 156):
    • Invoke self.check_slot_loan_rebind(st, stmt) before self.mark_slot_loans_assign(st, targets, *op, values) when deep == true so re-binding a closure-local map-slot loan to a general pointer (s = &other) or nil (s = nil) is rejected with HYB-E3104 (T24), matching top-level check_fn_body.
  3. compiler/crates/hy-check/src/closures.rs (check_one_closure, line 217):
    • Propagate borrow_bindings: st.borrow_bindings.clone() into cst so returning a captured borrow or map-slot loan from a nested closure is rejected with HYB-E3104 (O2 LOAN-ESCAPE).
  4. Regression Tests (compiler/crates/hy-check/src/closures.rs):
    • reject_addr_of_index_projection_on_slot_loan_t24
    • reject_closure_slot_loan_rebind_to_general_pointer_or_nil_t24
    • All 175/175 hy-check unit tests + 65/65 integration test suites (240/240 total) pass with 0 failures.

Payout wallet (EVM / USDC): 0x1d74c4F8655ca2b7BCA7D41C60320ebB23990eA3

@github-actions github-actions Bot added bot:land-candidate Shepherd: fresh, gate-clean, verifiable (set from classify()) bot:dup-of:#1790 Shepherd W4: superseded by cluster survivor labels Oct 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Shepherd (Phase A — propose only): this PR's changed-file set overlaps >=0.6 Jaccard with #1790, which carries the larger take. Proposing close as superseded.

This is a proposal, not a close — nothing auto-closes while this comment is fresh. If this PR has unique content (a different rule, extra tests, a different fix), say so or push, and the label comes off. Cluster signal is a file-set heuristic; the verdict stays human.

@ubelai
ubelai force-pushed the fix/slot-loan-t24-rebind-and-escape-e3104 branch from 4bc0c6c to 1e36ed8 Compare November 9, 2026 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:conflict Shepherd: merge conflicts vs main bot:dup-of:#1790 Shepherd W4: superseded by cluster survivor bot:land-candidate Shepherd: fresh, gate-clean, verifiable (set from classify()) bot:stale-base Shepherd: behind main beyond threshold

Projects

None yet

1 participant