check: stamp SK_TYPE value idents with the per-decl NAMED
A TYPE name used as a VALUE (an error-singleton `return too_long;`) stamped the flattened BODY type, so structurally identical !void singletons in one union were indistinguishable and flatvariantidxt loud-rejected the ambiguity — the real cause of the lib/path wwstage reject (the pinned #120/#29 global-slice-const blame was stale; that family had drained). The N_IDENT arm resolves through a synthesized TNAME (the #66 N_STRUCTLIT precedent); the module-qualified N_DOT twin reads the sym's cached NAMED. Graduates the path M_WWREJECT pin (#142).
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
package wwfixture;
|
package wwfixture;
|
||||||
|
|
||||||
def protocolversion: i32 = 1;
|
def protocolversion: i32 = 1;
|
||||||
def corpuscount: i32 = 1237;
|
def corpuscount: i32 = 1238;
|
||||||
def errorcount: i32 = 314;
|
def errorcount: i32 = 314;
|
||||||
def compilecount: i32 = 12;
|
def compilecount: i32 = 12;
|
||||||
def runcount: i32 = 145;
|
def runcount: i32 = 145;
|
||||||
def runexitcount: i32 = 766;
|
def runexitcount: i32 = 767;
|
||||||
def nativecount: i32 = 2474;
|
def nativecount: i32 = 2476;
|
||||||
def corpushash: str = "7763f2eb34524f67355114f5bdfbf3f64415152a8ec64060fe32a322bdbe1b24";
|
def corpushash: str = "a78db801f50ad02de11fed981bd6d9c2d67509e69a69615744f1b2ad3ef4814d";
|
||||||
|
|
||||||
type directive = enum i32 {
|
type directive = enum i32 {
|
||||||
ERROR = 0,
|
ERROR = 0,
|
||||||
|
|||||||
@@ -3310,6 +3310,26 @@ fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = {
|
|||||||
e.type_ = tinfofornode(c, ft): *void;
|
e.type_ = tinfofornode(c, ft): *void;
|
||||||
return ft;
|
return ft;
|
||||||
};
|
};
|
||||||
|
// #142: a TYPE name used as a VALUE (an error-singleton
|
||||||
|
// `return too_long;`) must stamp the per-decl NAMED, not the
|
||||||
|
// flattened body — three structurally identical !void
|
||||||
|
// singletons in one union are indistinguishable by body, so
|
||||||
|
// flatvariantidxt's NAMED pass either mis-tags or
|
||||||
|
// loud-rejects as ambiguous. Resolve through a synthesized
|
||||||
|
// TNAME to reuse tinfofornode's TY_NAMED build/cache (the
|
||||||
|
// SAME NAMED ptr the union variant resolved to) — the #66
|
||||||
|
// N_STRUCTLIT precedent verbatim; cstage mirror
|
||||||
|
// cmd/wcc/check.c:1414 `n->type = s->type`. The BODY node
|
||||||
|
// still returns so AST-level assign/return checks keep
|
||||||
|
// their prior input.
|
||||||
|
if (s.skind == syntax.skind.SK_TYPE) {
|
||||||
|
let tnm: *syntax.node = mktname(c, e.str);
|
||||||
|
let nti: *syntax.tinfo = tinfofornode(c, tnm);
|
||||||
|
if (nti != nil) {
|
||||||
|
e.type_ = nti: *void;
|
||||||
|
return s.decl.lhs;
|
||||||
|
};
|
||||||
|
};
|
||||||
let t: *syntax.node = s.decl.lhs;
|
let t: *syntax.node = s.decl.lhs;
|
||||||
// Propagate the declared type's tinfo onto the use site so
|
// Propagate the declared type's tinfo onto the use site so
|
||||||
// downstream cgen walkers can read n.type_ off an ident.
|
// downstream cgen walkers can read n.type_ off an ident.
|
||||||
@@ -3878,6 +3898,19 @@ fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = {
|
|||||||
e.type_ = tinfofornode(c, ft): *void;
|
e.type_ = tinfofornode(c, ft): *void;
|
||||||
return ft;
|
return ft;
|
||||||
};
|
};
|
||||||
|
// #142 twin of the N_IDENT SK_TYPE arm: a
|
||||||
|
// module-qualified TYPE name used as a VALUE
|
||||||
|
// (`mod.too_long`) stamps the per-decl NAMED.
|
||||||
|
// The sym caches its NAMED (tinfofornode
|
||||||
|
// N_TNAME arm) once any type-position ref
|
||||||
|
// resolved; a nil cache falls through to the
|
||||||
|
// prior body stamp.
|
||||||
|
if (fs.skind == syntax.skind.SK_TYPE) {
|
||||||
|
if (fs.type_ != nil) {
|
||||||
|
e.type_ = fs.type_: *void;
|
||||||
|
return fs.decl.lhs;
|
||||||
|
};
|
||||||
|
};
|
||||||
let tn: *syntax.node = fs.decl.lhs;
|
let tn: *syntax.node = fs.decl.lhs;
|
||||||
if (tn != nil) {
|
if (tn != nil) {
|
||||||
e.type_ = tinfofornode(c, tn): *void;
|
e.type_ = tinfofornode(c, tn): *void;
|
||||||
|
|||||||
@@ -117,14 +117,16 @@ static const struct ent ents[] = {
|
|||||||
/* fixtureless modules, import-probe shape */
|
/* fixtureless modules, import-probe shape */
|
||||||
{ .probe = "package main;\nimport sort;\nfn main() i32 = { return 0; };\n",
|
{ .probe = "package main;\nimport sort;\nfn main() i32 = { return 0; };\n",
|
||||||
.mode = M_ID, .sentinel = "package sort;", .moddir = "lib/sort" },
|
.mode = M_ID, .sentinel = "package sort;", .moddir = "lib/sort" },
|
||||||
/* c2-stack path::buffer realignment: w6c compiles, w6c_ww rejects
|
/* #142 graduated (the old #120/#29 global-slice-const blame was
|
||||||
* path's module-global slice consts (const dot/dotdot: []u8) = the
|
* stale — that family drained earlier): path declares three
|
||||||
* #120/#29 acceptance divergence (module-level composite globals);
|
* structurally identical !void error singletons, and a VALUE use
|
||||||
* + the #148 twin #151 (global []u8 by-value arg). Both → #125
|
* (`return too_long;`) stamped the flattened BODY type, so
|
||||||
* batch. cstage runtime is covered by 989_path_run. M_WWREJECT
|
* flatvariantidxt loud-rejected the ambiguity. The SK_TYPE value
|
||||||
* self-graduates: flips RED to M_ID the day wwstage accepts this. */
|
* arms now stamp the per-decl NAMED (the #66 N_STRUCTLIT
|
||||||
|
* precedent). Runtime pin: r142_singleton_value_named. */
|
||||||
{ .probe = "package main;\nimport path;\nfn main() i32 = { return 0; };\n",
|
{ .probe = "package main;\nimport path;\nfn main() i32 = { return 0; };\n",
|
||||||
.mode = M_WWREJECT, .cite = "#120/#29", .sentinel = "package path;", .moddir = "lib/path" },
|
.mode = M_ID, .cite = "#142 graduated by the SK_TYPE NAMED value stamp",
|
||||||
|
.sentinel = "package path;", .moddir = "lib/path" },
|
||||||
{ .probe = "package main;\nimport endian;\nfn main() i32 = { return 0; };\n",
|
{ .probe = "package main;\nimport endian;\nfn main() i32 = { return 0; };\n",
|
||||||
.mode = M_ID, .sentinel = "package endian;", .moddir = "lib/endian" },
|
.mode = M_ID, .sentinel = "package endian;", .moddir = "lib/endian" },
|
||||||
{ .probe = "package main;\nimport net;\nfn main() i32 = { return 0; };\n",
|
{ .probe = "package main;\nimport net;\nfn main() i32 = { return 0; };\n",
|
||||||
|
|||||||
23
test/wcc/data/r142_singleton_value_named/case.ww
Normal file
23
test/wcc/data/r142_singleton_value_named/case.ww
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//ww:run-exit 42
|
||||||
|
// #142: a VALUE use of an error-singleton type name whose union has
|
||||||
|
// structurally identical siblings. The pre-fix wwstage stamped the
|
||||||
|
// flattened BODY type (!void), so flatvariantidxt could not pick a
|
||||||
|
// variant and loud-rejected; the per-decl NAMED stamp discriminates.
|
||||||
|
// Exit 42 proves the SECOND variant is selected, not the first.
|
||||||
|
package main;
|
||||||
|
|
||||||
|
type a = !void;
|
||||||
|
type b = !void;
|
||||||
|
type err = !(a | b);
|
||||||
|
|
||||||
|
fn f() err = {
|
||||||
|
return b;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() i32 = {
|
||||||
|
match (f()) {
|
||||||
|
case a => { return 41; };
|
||||||
|
case b => { return 42; };
|
||||||
|
};
|
||||||
|
return 9;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user