installdecl routes all four kinds (fn/type/def/let) through installtop, which turns scopedefineinmodule's nil return into cstage's exact "duplicate <kind> <name>" reject, keyed (name,mod) so cross-package same-leaf decls coexist. Builtin redecls are dropped, not dup-errored: cstage never scopes builtins (lookup_builtin first, check.c:69), so a user redecl is dead there — wwstage mirrors via scopesamekeysym + no-source-decl test. -T synth __wwtests installs direct, mirroring check.c:3079. Closes the silent dup-fn hole (user fn run vs lib/test run built a broken test binary with no diagnostic). Per-kind reject rows + cross-package/builtin accept byte-id rows + -T collision parity row in 910/997. (#23-team, category-A addendum closed)
15 lines
585 B
Plaintext
15 lines
585 B
Plaintext
// #23 builtin carve-out — a user redecl of a pre-seeded builtin name is
|
|
// NOT a duplicate (cstage keeps no builtins in scope: lookup_builtin wins
|
|
// first at check.c:69, so the user version installs dead). wwstage seeds
|
|
// builtins into c.top, so installtop must DROP this redecl rather than
|
|
// erroring. Both stages accept; the builtin `nomem` (= !void) wins, so
|
|
// g()'s i32 arm returns 7. Pins the 771/774/926 shape.
|
|
type nomem = !void;
|
|
fn g() (i32 | nomem) = { return 7; };
|
|
export fn main() i32 = {
|
|
match (g()) {
|
|
case let v: i32 => return v;
|
|
case nomem => return 99;
|
|
};
|
|
};
|