wcc/check: tinfofornode + decl-kind if-ladders -> switch (Wave-2 structural)
tinfofornode: 11-rung type-node-kind if/else (N_TNAME..N_TTAGGED) -> switch (k); no default case preserves the old trailing-else-less non-match path (r stays nil -> post-switch cache-bind). N_TTAGGED's early return r; (the nullable (*T|void) fold) intact. decl-kind in checkfile: 4-rung (N_FNDECL/N_DEF/N_TYPEDECL/N_LET) -> switch (k). w6c + wwdump combined.ww regenerated.
This commit is contained in:
@@ -12016,7 +12016,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
if (cached != nil) { return cached; };
|
if (cached != nil) { return cached; };
|
||||||
let r: *tinfo = nil;
|
let r: *tinfo = nil;
|
||||||
let k: nkind = n.kind;
|
let k: nkind = n.kind;
|
||||||
if (k == nkind.N_TNAME) {
|
switch (k) {
|
||||||
|
case nkind.N_TNAME:
|
||||||
let nm: str = n.str;
|
let nm: str = n.str;
|
||||||
if (streq(nm, "void")) { r = c.tc.tyvoid; };
|
if (streq(nm, "void")) { r = c.tc.tyvoid; };
|
||||||
if (streq(nm, "bool")) { r = c.tc.tybool; };
|
if (streq(nm, "bool")) { r = c.tc.tybool; };
|
||||||
@@ -12090,7 +12091,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else { if (k == nkind.N_TBANG) {
|
case nkind.N_TBANG:
|
||||||
// #61 audit §1.8: `!T` propagates the inner shape; cstage's
|
// #61 audit §1.8: `!T` propagates the inner shape; cstage's
|
||||||
// resolve_type sets ty->iserror on the wrapper but no wwstage
|
// resolve_type sets ty->iserror on the wrapper but no wwstage
|
||||||
// cgen reader consumes it yet, so A.1 drops the flag and
|
// cgen reader consumes it yet, so A.1 drops the flag and
|
||||||
@@ -12098,13 +12099,13 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
// unwrapbang pre-walk; graduate alongside the first cgen
|
// unwrapbang pre-walk; graduate alongside the first cgen
|
||||||
// site that needs iserror discrimination.
|
// site that needs iserror discrimination.
|
||||||
r = tinfofornode(c, n.lhs);
|
r = tinfofornode(c, n.lhs);
|
||||||
} else { if (k == nkind.N_TPTR) {
|
case nkind.N_TPTR:
|
||||||
r = typeptr(tinfofornode(c, n.lhs));
|
r = typeptr(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TSLICE) {
|
case nkind.N_TSLICE:
|
||||||
r = typeslice(tinfofornode(c, n.lhs));
|
r = typeslice(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TCHAN) {
|
case nkind.N_TCHAN:
|
||||||
r = typechan(tinfofornode(c, n.lhs));
|
r = typechan(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TARRAY) {
|
case nkind.N_TARRAY:
|
||||||
// Cstage cmd/wcc/check.c:314-326: length must be an integer
|
// Cstage cmd/wcc/check.c:314-326: length must be an integer
|
||||||
// literal (`[_]T` keeps alen=0 as the inferred-length sentinel
|
// literal (`[_]T` keeps alen=0 as the inferred-length sentinel
|
||||||
// patched at letslotsize-time).
|
// patched at letslotsize-time).
|
||||||
@@ -12120,7 +12121,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
};
|
};
|
||||||
let sub: *tinfo = tinfofornode(c, n.lhs);
|
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||||
r = typearray(sub, elen);
|
r = typearray(sub, elen);
|
||||||
} else { if (k == nkind.N_TFN) {
|
case nkind.N_TFN:
|
||||||
// Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B
|
// Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B
|
||||||
// (call-target pointer shape). Pre-bind before recursing into
|
// (call-target pointer shape). Pre-bind before recursing into
|
||||||
// the return type so a recursive `type F = fn() F` self-ref
|
// the return type so a recursive `type F = fn() F` self-ref
|
||||||
@@ -12132,7 +12133,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.slotsize = 8u64;
|
r.slotsize = 8u64;
|
||||||
tinfocachebind(c.tc, n, r);
|
tinfocachebind(c.tc, n, r);
|
||||||
r.ret = tinfofornode(c, n.lhs);
|
r.ret = tinfofornode(c, n.lhs);
|
||||||
} else { if (k == nkind.N_TENUM) {
|
case nkind.N_TENUM:
|
||||||
// Cstage cmd/wcc/check.c:529-542: storage type's size/align
|
// Cstage cmd/wcc/check.c:529-542: storage type's size/align
|
||||||
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
||||||
// to 8B per its stack-slot contract; tinfo.size carries the
|
// to 8B per its stack-slot contract; tinfo.size carries the
|
||||||
@@ -12145,7 +12146,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = storage.size;
|
r.size = storage.size;
|
||||||
r.align = storage.align;
|
r.align = storage.align;
|
||||||
r.slotsize = storage.size;
|
r.slotsize = storage.size;
|
||||||
} else { if (k == nkind.N_TTUPLE) {
|
case nkind.N_TTUPLE:
|
||||||
// Cstage cmd/wcc/check.c:329-345: sum of element sizes with
|
// Cstage cmd/wcc/check.c:329-345: sum of element sizes with
|
||||||
// per-element alignment NOT padded — cstage uses raw sums for
|
// per-element alignment NOT padded — cstage uses raw sums for
|
||||||
// tuples and 8B-rounding lives at the call/return ABI layer.
|
// tuples and 8B-rounding lives at the call/return ABI layer.
|
||||||
@@ -12196,7 +12197,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = total;
|
r.size = total;
|
||||||
r.align = maxal;
|
r.align = maxal;
|
||||||
r.slotsize = slottotal;
|
r.slotsize = slottotal;
|
||||||
} else { if (k == nkind.N_TSTRUCT) {
|
case nkind.N_TSTRUCT:
|
||||||
// Cstage cmd/wcc/check.c:468-527: per-field alignment, max
|
// Cstage cmd/wcc/check.c:468-527: per-field alignment, max
|
||||||
// align for the whole record, total rounded up to alignment.
|
// align for the whole record, total rounded up to alignment.
|
||||||
// Anonymous-embed promotion is deferred (#13).
|
// Anonymous-embed promotion is deferred (#13).
|
||||||
@@ -12271,7 +12272,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
soff = (soff + 7u64) & ~7u64;
|
soff = (soff + 7u64) & ~7u64;
|
||||||
};
|
};
|
||||||
r.slotsize = soff;
|
r.slotsize = soff;
|
||||||
} else { if (k == nkind.N_TTAGGED) {
|
case nkind.N_TTAGGED:
|
||||||
// Cstage cmd/wcc/check.c:347-435: 8B tag + max(variant)
|
// Cstage cmd/wcc/check.c:347-435: 8B tag + max(variant)
|
||||||
// rounded up to 8. Pre-bind for cycle protection (recursive
|
// rounded up to 8. Pre-bind for cycle protection (recursive
|
||||||
// sum-type shapes through NAMED variants).
|
// sum-type shapes through NAMED variants).
|
||||||
@@ -12371,7 +12372,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = 8u64 + pad;
|
r.size = 8u64 + pad;
|
||||||
r.align = al;
|
r.align = al;
|
||||||
r.slotsize = 8u64 + pad;
|
r.slotsize = 8u64 + pad;
|
||||||
};};};};};};};};};};};
|
};
|
||||||
if (r != nil) {
|
if (r != nil) {
|
||||||
// #61 A.5: any arm that didn't set slotsize gets ti.size as
|
// #61 A.5: any arm that didn't set slotsize gets ti.size as
|
||||||
// the default (covers primitives via prim() + the ptr/slice/
|
// the default (covers primitives via prim() + the ptr/slice/
|
||||||
@@ -14846,10 +14847,11 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
// inner nodes.
|
// inner nodes.
|
||||||
if (d.attr != nil) { resolvewalk(c, d.attr); };
|
if (d.attr != nil) { resolvewalk(c, d.attr); };
|
||||||
let k: nkind = d.kind;
|
let k: nkind = d.kind;
|
||||||
if (k == nkind.N_FNDECL) {
|
switch (k) {
|
||||||
|
case nkind.N_FNDECL:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
|
||||||
resolvefnbody(c, d);
|
resolvefnbody(c, d);
|
||||||
} else { if (k == nkind.N_DEF) {
|
case nkind.N_DEF:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
||||||
// #251: `def D: [N]T = [int/rune lits]` array-init
|
// #251: `def D: [N]T = [int/rune lits]` array-init
|
||||||
@@ -14874,9 +14876,9 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else { if (k == nkind.N_TYPEDECL) {
|
case nkind.N_TYPEDECL:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
} else { if (k == nkind.N_LET) {
|
case nkind.N_LET:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
||||||
// #130: top-level let assignability — the subtree
|
// #130: top-level let assignability — the subtree
|
||||||
@@ -14886,7 +14888,7 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
// were missed). Needed for the array accept-if-fits
|
// were missed). Needed for the array accept-if-fits
|
||||||
// range-check to fire on module-level `let A:[N]u8=[..]`.
|
// range-check to fire on module-level `let A:[N]u8=[..]`.
|
||||||
checkletassign(c, d);
|
checkletassign(c, d);
|
||||||
};};};};
|
};
|
||||||
d = d.next;
|
d = d.next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1630,7 +1630,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
if (cached != nil) { return cached; };
|
if (cached != nil) { return cached; };
|
||||||
let r: *tinfo = nil;
|
let r: *tinfo = nil;
|
||||||
let k: nkind = n.kind;
|
let k: nkind = n.kind;
|
||||||
if (k == nkind.N_TNAME) {
|
switch (k) {
|
||||||
|
case nkind.N_TNAME:
|
||||||
let nm: str = n.str;
|
let nm: str = n.str;
|
||||||
if (streq(nm, "void")) { r = c.tc.tyvoid; };
|
if (streq(nm, "void")) { r = c.tc.tyvoid; };
|
||||||
if (streq(nm, "bool")) { r = c.tc.tybool; };
|
if (streq(nm, "bool")) { r = c.tc.tybool; };
|
||||||
@@ -1704,7 +1705,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else { if (k == nkind.N_TBANG) {
|
case nkind.N_TBANG:
|
||||||
// #61 audit §1.8: `!T` propagates the inner shape; cstage's
|
// #61 audit §1.8: `!T` propagates the inner shape; cstage's
|
||||||
// resolve_type sets ty->iserror on the wrapper but no wwstage
|
// resolve_type sets ty->iserror on the wrapper but no wwstage
|
||||||
// cgen reader consumes it yet, so A.1 drops the flag and
|
// cgen reader consumes it yet, so A.1 drops the flag and
|
||||||
@@ -1712,13 +1713,13 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
// unwrapbang pre-walk; graduate alongside the first cgen
|
// unwrapbang pre-walk; graduate alongside the first cgen
|
||||||
// site that needs iserror discrimination.
|
// site that needs iserror discrimination.
|
||||||
r = tinfofornode(c, n.lhs);
|
r = tinfofornode(c, n.lhs);
|
||||||
} else { if (k == nkind.N_TPTR) {
|
case nkind.N_TPTR:
|
||||||
r = typeptr(tinfofornode(c, n.lhs));
|
r = typeptr(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TSLICE) {
|
case nkind.N_TSLICE:
|
||||||
r = typeslice(tinfofornode(c, n.lhs));
|
r = typeslice(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TCHAN) {
|
case nkind.N_TCHAN:
|
||||||
r = typechan(tinfofornode(c, n.lhs));
|
r = typechan(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TARRAY) {
|
case nkind.N_TARRAY:
|
||||||
// Cstage cmd/wcc/check.c:314-326: length must be an integer
|
// Cstage cmd/wcc/check.c:314-326: length must be an integer
|
||||||
// literal (`[_]T` keeps alen=0 as the inferred-length sentinel
|
// literal (`[_]T` keeps alen=0 as the inferred-length sentinel
|
||||||
// patched at letslotsize-time).
|
// patched at letslotsize-time).
|
||||||
@@ -1734,7 +1735,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
};
|
};
|
||||||
let sub: *tinfo = tinfofornode(c, n.lhs);
|
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||||
r = typearray(sub, elen);
|
r = typearray(sub, elen);
|
||||||
} else { if (k == nkind.N_TFN) {
|
case nkind.N_TFN:
|
||||||
// Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B
|
// Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B
|
||||||
// (call-target pointer shape). Pre-bind before recursing into
|
// (call-target pointer shape). Pre-bind before recursing into
|
||||||
// the return type so a recursive `type F = fn() F` self-ref
|
// the return type so a recursive `type F = fn() F` self-ref
|
||||||
@@ -1746,7 +1747,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.slotsize = 8u64;
|
r.slotsize = 8u64;
|
||||||
tinfocachebind(c.tc, n, r);
|
tinfocachebind(c.tc, n, r);
|
||||||
r.ret = tinfofornode(c, n.lhs);
|
r.ret = tinfofornode(c, n.lhs);
|
||||||
} else { if (k == nkind.N_TENUM) {
|
case nkind.N_TENUM:
|
||||||
// Cstage cmd/wcc/check.c:529-542: storage type's size/align
|
// Cstage cmd/wcc/check.c:529-542: storage type's size/align
|
||||||
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
||||||
// to 8B per its stack-slot contract; tinfo.size carries the
|
// to 8B per its stack-slot contract; tinfo.size carries the
|
||||||
@@ -1759,7 +1760,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = storage.size;
|
r.size = storage.size;
|
||||||
r.align = storage.align;
|
r.align = storage.align;
|
||||||
r.slotsize = storage.size;
|
r.slotsize = storage.size;
|
||||||
} else { if (k == nkind.N_TTUPLE) {
|
case nkind.N_TTUPLE:
|
||||||
// Cstage cmd/wcc/check.c:329-345: sum of element sizes with
|
// Cstage cmd/wcc/check.c:329-345: sum of element sizes with
|
||||||
// per-element alignment NOT padded — cstage uses raw sums for
|
// per-element alignment NOT padded — cstage uses raw sums for
|
||||||
// tuples and 8B-rounding lives at the call/return ABI layer.
|
// tuples and 8B-rounding lives at the call/return ABI layer.
|
||||||
@@ -1810,7 +1811,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = total;
|
r.size = total;
|
||||||
r.align = maxal;
|
r.align = maxal;
|
||||||
r.slotsize = slottotal;
|
r.slotsize = slottotal;
|
||||||
} else { if (k == nkind.N_TSTRUCT) {
|
case nkind.N_TSTRUCT:
|
||||||
// Cstage cmd/wcc/check.c:468-527: per-field alignment, max
|
// Cstage cmd/wcc/check.c:468-527: per-field alignment, max
|
||||||
// align for the whole record, total rounded up to alignment.
|
// align for the whole record, total rounded up to alignment.
|
||||||
// Anonymous-embed promotion is deferred (#13).
|
// Anonymous-embed promotion is deferred (#13).
|
||||||
@@ -1885,7 +1886,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
soff = (soff + 7u64) & ~7u64;
|
soff = (soff + 7u64) & ~7u64;
|
||||||
};
|
};
|
||||||
r.slotsize = soff;
|
r.slotsize = soff;
|
||||||
} else { if (k == nkind.N_TTAGGED) {
|
case nkind.N_TTAGGED:
|
||||||
// Cstage cmd/wcc/check.c:347-435: 8B tag + max(variant)
|
// Cstage cmd/wcc/check.c:347-435: 8B tag + max(variant)
|
||||||
// rounded up to 8. Pre-bind for cycle protection (recursive
|
// rounded up to 8. Pre-bind for cycle protection (recursive
|
||||||
// sum-type shapes through NAMED variants).
|
// sum-type shapes through NAMED variants).
|
||||||
@@ -1985,7 +1986,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = 8u64 + pad;
|
r.size = 8u64 + pad;
|
||||||
r.align = al;
|
r.align = al;
|
||||||
r.slotsize = 8u64 + pad;
|
r.slotsize = 8u64 + pad;
|
||||||
};};};};};};};};};};};
|
};
|
||||||
if (r != nil) {
|
if (r != nil) {
|
||||||
// #61 A.5: any arm that didn't set slotsize gets ti.size as
|
// #61 A.5: any arm that didn't set slotsize gets ti.size as
|
||||||
// the default (covers primitives via prim() + the ptr/slice/
|
// the default (covers primitives via prim() + the ptr/slice/
|
||||||
@@ -4460,10 +4461,11 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
// inner nodes.
|
// inner nodes.
|
||||||
if (d.attr != nil) { resolvewalk(c, d.attr); };
|
if (d.attr != nil) { resolvewalk(c, d.attr); };
|
||||||
let k: nkind = d.kind;
|
let k: nkind = d.kind;
|
||||||
if (k == nkind.N_FNDECL) {
|
switch (k) {
|
||||||
|
case nkind.N_FNDECL:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
|
||||||
resolvefnbody(c, d);
|
resolvefnbody(c, d);
|
||||||
} else { if (k == nkind.N_DEF) {
|
case nkind.N_DEF:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
||||||
// #251: `def D: [N]T = [int/rune lits]` array-init
|
// #251: `def D: [N]T = [int/rune lits]` array-init
|
||||||
@@ -4488,9 +4490,9 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else { if (k == nkind.N_TYPEDECL) {
|
case nkind.N_TYPEDECL:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
} else { if (k == nkind.N_LET) {
|
case nkind.N_LET:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
||||||
// #130: top-level let assignability — the subtree
|
// #130: top-level let assignability — the subtree
|
||||||
@@ -4500,7 +4502,7 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
// were missed). Needed for the array accept-if-fits
|
// were missed). Needed for the array accept-if-fits
|
||||||
// range-check to fire on module-level `let A:[N]u8=[..]`.
|
// range-check to fire on module-level `let A:[N]u8=[..]`.
|
||||||
checkletassign(c, d);
|
checkletassign(c, d);
|
||||||
};};};};
|
};
|
||||||
d = d.next;
|
d = d.next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12016,7 +12016,8 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
if (cached != nil) { return cached; };
|
if (cached != nil) { return cached; };
|
||||||
let r: *tinfo = nil;
|
let r: *tinfo = nil;
|
||||||
let k: nkind = n.kind;
|
let k: nkind = n.kind;
|
||||||
if (k == nkind.N_TNAME) {
|
switch (k) {
|
||||||
|
case nkind.N_TNAME:
|
||||||
let nm: str = n.str;
|
let nm: str = n.str;
|
||||||
if (streq(nm, "void")) { r = c.tc.tyvoid; };
|
if (streq(nm, "void")) { r = c.tc.tyvoid; };
|
||||||
if (streq(nm, "bool")) { r = c.tc.tybool; };
|
if (streq(nm, "bool")) { r = c.tc.tybool; };
|
||||||
@@ -12090,7 +12091,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else { if (k == nkind.N_TBANG) {
|
case nkind.N_TBANG:
|
||||||
// #61 audit §1.8: `!T` propagates the inner shape; cstage's
|
// #61 audit §1.8: `!T` propagates the inner shape; cstage's
|
||||||
// resolve_type sets ty->iserror on the wrapper but no wwstage
|
// resolve_type sets ty->iserror on the wrapper but no wwstage
|
||||||
// cgen reader consumes it yet, so A.1 drops the flag and
|
// cgen reader consumes it yet, so A.1 drops the flag and
|
||||||
@@ -12098,13 +12099,13 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
// unwrapbang pre-walk; graduate alongside the first cgen
|
// unwrapbang pre-walk; graduate alongside the first cgen
|
||||||
// site that needs iserror discrimination.
|
// site that needs iserror discrimination.
|
||||||
r = tinfofornode(c, n.lhs);
|
r = tinfofornode(c, n.lhs);
|
||||||
} else { if (k == nkind.N_TPTR) {
|
case nkind.N_TPTR:
|
||||||
r = typeptr(tinfofornode(c, n.lhs));
|
r = typeptr(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TSLICE) {
|
case nkind.N_TSLICE:
|
||||||
r = typeslice(tinfofornode(c, n.lhs));
|
r = typeslice(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TCHAN) {
|
case nkind.N_TCHAN:
|
||||||
r = typechan(tinfofornode(c, n.lhs));
|
r = typechan(tinfofornode(c, n.lhs));
|
||||||
} else { if (k == nkind.N_TARRAY) {
|
case nkind.N_TARRAY:
|
||||||
// Cstage cmd/wcc/check.c:314-326: length must be an integer
|
// Cstage cmd/wcc/check.c:314-326: length must be an integer
|
||||||
// literal (`[_]T` keeps alen=0 as the inferred-length sentinel
|
// literal (`[_]T` keeps alen=0 as the inferred-length sentinel
|
||||||
// patched at letslotsize-time).
|
// patched at letslotsize-time).
|
||||||
@@ -12120,7 +12121,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
};
|
};
|
||||||
let sub: *tinfo = tinfofornode(c, n.lhs);
|
let sub: *tinfo = tinfofornode(c, n.lhs);
|
||||||
r = typearray(sub, elen);
|
r = typearray(sub, elen);
|
||||||
} else { if (k == nkind.N_TFN) {
|
case nkind.N_TFN:
|
||||||
// Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B
|
// Cstage cmd/wcc/check.c:437-466: function types are 8B / 8B
|
||||||
// (call-target pointer shape). Pre-bind before recursing into
|
// (call-target pointer shape). Pre-bind before recursing into
|
||||||
// the return type so a recursive `type F = fn() F` self-ref
|
// the return type so a recursive `type F = fn() F` self-ref
|
||||||
@@ -12132,7 +12133,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.slotsize = 8u64;
|
r.slotsize = 8u64;
|
||||||
tinfocachebind(c.tc, n, r);
|
tinfocachebind(c.tc, n, r);
|
||||||
r.ret = tinfofornode(c, n.lhs);
|
r.ret = tinfofornode(c, n.lhs);
|
||||||
} else { if (k == nkind.N_TENUM) {
|
case nkind.N_TENUM:
|
||||||
// Cstage cmd/wcc/check.c:529-542: storage type's size/align
|
// Cstage cmd/wcc/check.c:529-542: storage type's size/align
|
||||||
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
||||||
// to 8B per its stack-slot contract; tinfo.size carries the
|
// to 8B per its stack-slot contract; tinfo.size carries the
|
||||||
@@ -12145,7 +12146,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = storage.size;
|
r.size = storage.size;
|
||||||
r.align = storage.align;
|
r.align = storage.align;
|
||||||
r.slotsize = storage.size;
|
r.slotsize = storage.size;
|
||||||
} else { if (k == nkind.N_TTUPLE) {
|
case nkind.N_TTUPLE:
|
||||||
// Cstage cmd/wcc/check.c:329-345: sum of element sizes with
|
// Cstage cmd/wcc/check.c:329-345: sum of element sizes with
|
||||||
// per-element alignment NOT padded — cstage uses raw sums for
|
// per-element alignment NOT padded — cstage uses raw sums for
|
||||||
// tuples and 8B-rounding lives at the call/return ABI layer.
|
// tuples and 8B-rounding lives at the call/return ABI layer.
|
||||||
@@ -12196,7 +12197,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = total;
|
r.size = total;
|
||||||
r.align = maxal;
|
r.align = maxal;
|
||||||
r.slotsize = slottotal;
|
r.slotsize = slottotal;
|
||||||
} else { if (k == nkind.N_TSTRUCT) {
|
case nkind.N_TSTRUCT:
|
||||||
// Cstage cmd/wcc/check.c:468-527: per-field alignment, max
|
// Cstage cmd/wcc/check.c:468-527: per-field alignment, max
|
||||||
// align for the whole record, total rounded up to alignment.
|
// align for the whole record, total rounded up to alignment.
|
||||||
// Anonymous-embed promotion is deferred (#13).
|
// Anonymous-embed promotion is deferred (#13).
|
||||||
@@ -12271,7 +12272,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
soff = (soff + 7u64) & ~7u64;
|
soff = (soff + 7u64) & ~7u64;
|
||||||
};
|
};
|
||||||
r.slotsize = soff;
|
r.slotsize = soff;
|
||||||
} else { if (k == nkind.N_TTAGGED) {
|
case nkind.N_TTAGGED:
|
||||||
// Cstage cmd/wcc/check.c:347-435: 8B tag + max(variant)
|
// Cstage cmd/wcc/check.c:347-435: 8B tag + max(variant)
|
||||||
// rounded up to 8. Pre-bind for cycle protection (recursive
|
// rounded up to 8. Pre-bind for cycle protection (recursive
|
||||||
// sum-type shapes through NAMED variants).
|
// sum-type shapes through NAMED variants).
|
||||||
@@ -12371,7 +12372,7 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = {
|
|||||||
r.size = 8u64 + pad;
|
r.size = 8u64 + pad;
|
||||||
r.align = al;
|
r.align = al;
|
||||||
r.slotsize = 8u64 + pad;
|
r.slotsize = 8u64 + pad;
|
||||||
};};};};};};};};};};};
|
};
|
||||||
if (r != nil) {
|
if (r != nil) {
|
||||||
// #61 A.5: any arm that didn't set slotsize gets ti.size as
|
// #61 A.5: any arm that didn't set slotsize gets ti.size as
|
||||||
// the default (covers primitives via prim() + the ptr/slice/
|
// the default (covers primitives via prim() + the ptr/slice/
|
||||||
@@ -14846,10 +14847,11 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
// inner nodes.
|
// inner nodes.
|
||||||
if (d.attr != nil) { resolvewalk(c, d.attr); };
|
if (d.attr != nil) { resolvewalk(c, d.attr); };
|
||||||
let k: nkind = d.kind;
|
let k: nkind = d.kind;
|
||||||
if (k == nkind.N_FNDECL) {
|
switch (k) {
|
||||||
|
case nkind.N_FNDECL:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
|
||||||
resolvefnbody(c, d);
|
resolvefnbody(c, d);
|
||||||
} else { if (k == nkind.N_DEF) {
|
case nkind.N_DEF:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
||||||
// #251: `def D: [N]T = [int/rune lits]` array-init
|
// #251: `def D: [N]T = [int/rune lits]` array-init
|
||||||
@@ -14874,9 +14876,9 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else { if (k == nkind.N_TYPEDECL) {
|
case nkind.N_TYPEDECL:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
} else { if (k == nkind.N_LET) {
|
case nkind.N_LET:
|
||||||
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
|
||||||
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
|
||||||
// #130: top-level let assignability — the subtree
|
// #130: top-level let assignability — the subtree
|
||||||
@@ -14886,7 +14888,7 @@ export fn checkfile(c: *checker, file: *node) void = {
|
|||||||
// were missed). Needed for the array accept-if-fits
|
// were missed). Needed for the array accept-if-fits
|
||||||
// range-check to fire on module-level `let A:[N]u8=[..]`.
|
// range-check to fire on module-level `let A:[N]u8=[..]`.
|
||||||
checkletassign(c, d);
|
checkletassign(c, d);
|
||||||
};};};};
|
};
|
||||||
d = d.next;
|
d = d.next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user