wcc: cgdot/cgident dead-end paths are loud (rule 7)
cgdot's local-ident arm silently emitted nothing for a receiver whose local record carries no type node (inference miss upstream), leaving the consumer reading stale AX. cgident's tail silently emitted nothing for any ident that resolved to no local/fn/def/let; that silence is load-bearing ONLY for the #140 !void error-singleton value (tag-only, the widen arm stamps the tag) -- keep exactly that case, mirroring the cstage #140 guard, and hard-stop the rest.
This commit is contained in:
@@ -1388,7 +1388,19 @@ fn cgident(c: *cgen, n: *syntax.node) void = {
|
||||
};
|
||||
return;
|
||||
};
|
||||
return;
|
||||
// #140: a `!void` error-singleton spelled as a VALUE (`return
|
||||
// toolong;`) is tag-only — the void payload has size 0 and no
|
||||
// storage, so it is neither a local, def, nor let. Emit NOTHING;
|
||||
// the enclosing widen arm stamps the variant tag. Mirrors cstage
|
||||
// cgen.c N_IDENT #140 guard. Every other unresolvable ident is
|
||||
// checker-rejected upstream — loud, never the old silent return.
|
||||
{
|
||||
let vu: *syntax.tinfo = tichase(n.type_: *syntax.tinfo);
|
||||
if (vu != nil && vu.kind == syntax.tykind.TY_VOID) { return; };
|
||||
};
|
||||
let mur: str = "cgident: unresolvable identifier (rule 7)\n";
|
||||
os.write(2, mur.ptr, mur.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
|
||||
// cgslicehdr — load the 24B slice/str header at base+0 into the
|
||||
@@ -3707,7 +3719,16 @@ fn cgdot(c: *cgen, n: *syntax.node) void = {
|
||||
};
|
||||
tn = nx;
|
||||
};
|
||||
if (tn == nil) { return; };
|
||||
// A registered local with NO type node means
|
||||
// inference missed upstream — emitting nothing
|
||||
// leaves the consumer reading stale AX, and
|
||||
// falling through would emit a bogus
|
||||
// `MOVQ <fld>(SB)` (the #191 hazard). Loud.
|
||||
if (tn == nil) {
|
||||
let mdt: str = "cgdot: local receiver has no type node (rule 7)\n";
|
||||
os.write(2, mdt.ptr, mdt.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
let lkind: syntax.nkind = tn.kind;
|
||||
// Pointer-to-struct: deref then field load.
|
||||
if (lkind == syntax.nkind.N_TPTR) {
|
||||
|
||||
Reference in New Issue
Block a user