Skip to content

fix(hy-check): reject non-lowered map-slot borrow positions with HYB-E3104 (closes #1423) - #1441

Merged
limitlessprojects merged 1 commit into
limitlessprojects:mainfrom
Dimank92:fix/issue-1423-non-lowered-slot-loans
Oct 24, 2026
Merged

limitlessprojects merged 1 commit into
limitlessprojects:mainfrom
Dimank92:fix/issue-1423-non-lowered-slot-loans

Conversation

@Dimank92

Copy link
Copy Markdown
Contributor

Summary of Changes

Closes #1423.

This PR fixes multiple soundness bypasses where non-lowered O8 map-slot borrow expressions (&m[k]) bypassed HYB-E3104:

  1. compiler/crates/hy-check/src/addr_loan.rs:
    • check_stmt_addr_of_loan_projections:
      • Stmt::Local: Only passes allow_slot_loan = true when matches!(l.kind, LocalKind::Define | LocalKind::Let) && l.ty.is_none() && l.names.len() == l.values.len(). LocalKind::Var and type-ascribed declarations cannot lower slot loans and now correctly reject &m[k] with HYB-E3104.
      • Stmt::Assign: Only passes allow_slot_loan = true when *op == AssignOp::Assign && targets.len() == values.len() && targets.iter().all(|t| matches!(&t.kind, PlaceKind::Ident(_))). Index and mixed assignments cannot lower slot loans and now reject &m[k] with HYB-E3104.
    • mark_slot_loans_local & mark_slot_loans_assign:
      • Restricted marking to lowered define/let declarations and all-identifier assignments, aligning the checker state with hy-emit lowering.
    • walk_addr_of_loan_projections (Expr::StructLit):
      • Removed unconditional skip of map_slot_borrow_span on struct literal fields. Fields of type any or generic parameters that were not previously caught by A6 (HYB-E3103) now properly reject unlowered &m[k] with HYB-E3104 (while emit_map_slot_borrow_diag already deduplicates against prior A6 diagnostics).

Maintainer Scorecard & Verification

  • Code Quality: Clean alignment with hy-emit O8 slot loan lowering conditions in compiler/crates/hy-emit/src/stmt.rs.
  • Tests:
    • compiler/crates/hy-check/tests/slot_loan_callarg_positions.rs: added non_lowered_map_slot_borrow_positions_rejected_issue_1423 verifying all 4 repro cases:
      1. var declaration (var p = &m["a"]) -> rejects with HYB-E3104.
      2. Index assignment target (ptrs[0] = &m["a"]) -> rejects with HYB-E3104.
      3. Mixed-target parallel assignment (q, arr[0] = &m["a"], 1) -> rejects with HYB-E3104.
      4. any-typed struct-literal field (box{p: &m["a"]}) -> rejects with HYB-E3104.
  • Pass Rate:
    • cargo test -p hy-check: 100% pass across all tests.

Payout / Bounty Address (Polygon/Base/Arbitrum/Ethereum USDC):
0xC345C07229307d4f1c7935aD2cAe48e390215808

@limitlessprojects

Copy link
Copy Markdown
Owner

Landed on main as a two-parent merge onto the post-#1432 tip (17d2962): your position gates + #1432's loan-preservation semantics, doc-comment conflict resolved in favor of both. Battery on the merged tree: workspace 1775/0, corpus tripwire clear, differential FULL 40+86; over-reach controls (plain-local &n, loan re-loan, non-loan rebind) all stay ACCEPT, and #1424's five non-lowered-position shapes reject E3104.

Clean, well-documented diff — the LocalKind gating and the all-ident-targets condition on mark_slot_loans_assign are exactly the right restriction to what hy-emit lowers. Thanks @Dimank92.

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

Labels

None yet

Projects

None yet

2 participants