cstage+selfhost+test: refuse let/param shadow of imported module (#19)
When `use fmt;` is in scope and a local/param named `fmt` shadows it, `fmt.X` in the body silently resolved to the str-typed value sym and emitted `CALL AX` through str.ptr → runtime crash. Surfaced during #15 (lib/log's printfln family); worked around by renaming the param `fmt`→`format`. Per rob + user, option (C): "value names and module names are disjoint." Refuse the shadow at the decl site. Single rule, no non-local reasoning, no silent footgun if a future lib/X exports a new leaf. cstage: src_imports walks file->list for N_USE entries (skipping self-imports where u->module == u->str — same-module fixtures like lib/fmt/fmttest.ww carry these); check_module_shadow runs before each SK_PARAM / SK_VAR scope_define (param, clet, mlet, forrange single + tuple, mcase). Wwstage mirror in check.ww; wwdump-only diagnostic today, full enforcement waits on #11 checkfile pass. Bootstrap byte-id holds — no codegen change. One source patch in selfhost/cmd/w6a/main.ww renames an outer `let asm: asm_;` to `s` to sidestep task #27 (cstage localoff scope-blind dedup); unrelated to #19 but the new rule's first run flagged it as a self-shadow. Test 708 (param_shadow_mod): 4 rows — neg_param (param shadow errs at fn decl line), neg_let (let shadow errs at let decl), pos_rename (rename compiles + runs), pos_selfimp (in-module use is skipped). 4 wired sites without dedicated rows deferred to task #28. Follow-up: lib/log can revert format→fmt now that the silent crash is impossible.
This commit is contained in:
@@ -2965,13 +2965,13 @@ export fn main(argc: i32, argv: **u8) i32 = {
|
||||
};
|
||||
|
||||
let ar: *arena = newarena();
|
||||
let asm: asm_;
|
||||
let s: asm_;
|
||||
let nlen: u64 = cstrlen(src);
|
||||
let fname: str = astrndup(ar, src, nlen);
|
||||
init(&asm, ar, fname, buf, blen);
|
||||
init(&s, ar, fname, buf, blen);
|
||||
|
||||
if (parse(&asm) != 0) { return 1; };
|
||||
if (encode(&asm) != 0) { return 1; };
|
||||
if (parse(&s) != 0) { return 1; };
|
||||
if (encode(&s) != 0) { return 1; };
|
||||
|
||||
// Open output for write.
|
||||
let fd: i32 = os.open(out, os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644
|
||||
@@ -2979,7 +2979,7 @@ export fn main(argc: i32, argv: **u8) i32 = {
|
||||
os.write(2, "w6a: cannot open output\n".ptr, 23u64);
|
||||
return 1;
|
||||
};
|
||||
let rc: i32 = emitelf(&asm, fd);
|
||||
let rc: i32 = emitelf(&s, fd);
|
||||
os.close(fd);
|
||||
return rc;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user