cstage+selfhost+test: refuse same-block let / param redecl (#32)
cmd/wcc/check.c silently accepted `let a; let a;` in the same block and similar redecls. Pre-#27 the localoff dedup masked it; post-#27 last-write-wins via head-first localfind. Surfaced by worker-27 during the #27 review. Cstage: 5 guard sites (check_scope_define-NULL → err) covering N_LET block-bind, N_MLET tuple binders (incl. same-tuple `let (a,a)`), N_FORRANGE tuple binders, top-level let, fn param. Voice: "<kind> '<name>' redeclared in same scope" for inner; "duplicate let %s" for top-let, matching the existing "duplicate <kind>" idiom at 1812/1851/1872. Wwstage: TODO(#11) comments at the 4 mirror sites (installdecl, N_FORRANGE, N_LET, installparams). Full enforcement waits on the checkfile pass per rob. **Unmasked by #32 (worth flagging):** selfhost/cmd/wcc/cgenexpr.ww cgcall had `let callee: *node = n.lhs;` twice at fn-body scope (copy-paste, identical value). Pre-fix silent-redecl absorbed it; post-fix the new guard rejects. Removed the second decl — outer `callee` stays visible across the intermediate block. Test 712 (redecl): 10 rows (6 neg + 4 pos), cstage-only per rob. Negative rows cover all 5 guard sites + same-tuple-dup. Positive rows pin the legal counter-shapes (cross-block, name-only bucket, forrange body, mcase-per-arm). Test 300 row 34 ("shadowing in inner scope; same scope flagged") was incorrectly asserting the bug; flipped to expect "redeclared" and added a sibling row pinning cross-block shadow stays ok. Test 709's `same_block_redecl_pin` canary (explicitly documented as flipping under #32) removed; pointer to 712 left in its place.
This commit is contained in:
@@ -3064,7 +3064,9 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
let callee: *node = n.lhs;
|
||||
// `callee` is already in scope from line 2827; reuse it. Pre-#32
|
||||
// silent-redecl masked the second `let callee` here as a no-op
|
||||
// (same value, same fn-body scope post-#27).
|
||||
let calleename: str;
|
||||
calleename.ptr = nil; calleename.len = 0;
|
||||
// Detect fn-pointer field call: `w.emit(args)` where `w` is
|
||||
|
||||
Reference in New Issue
Block a user