#64 flowed per-decl TY_NAMED wrappers, falsifying two #63-era assumptions surfaced in the flip review. elemissignedc read ti.sub for element signedness without peeling TY_NAMED; a NAMED-of-indexable would read NAMED.sub (nil) instead of the underlying's. Add the transitive peel ahead of the .sub read, mirroring cstage idx_eff's type_unwrap (cmd/w6c/cgen.c:790) before eff->sub (:3518-3520). Byte-id-neutral: every aliased indexable in-tree has a u8 element (typeissigned=false either way). Independent .sub/.under inventory confirms elemissignedc was the sole structural reader missing a peel (castsrcprim + TK_AMP already NAMED-guarded; typeis* handle element NAMED via .under recursion; typeeq is nominal by design and must not peel). Refresh the 5 #63 peel-site comments (slotsize, fieldsize, nullableptrtag, tupleelemslot, fieldslotsize): the peel now actively fires (#64 builds NAMED) rather than being a no-op; byte-id holds because NAMED collapses to the alias-invariant underlying. make test 133/133 (byte-id 990-997 green).
This commit is contained in:
@@ -8139,9 +8139,10 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = {
|
||||
// fallback arm).
|
||||
fn tupleelemslot(pt: *tinfo) u64 = {
|
||||
if (pt == nil) { return 8u64; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
let t: *tinfo = pt;
|
||||
for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; };
|
||||
if (t == nil) { return 8u64; };
|
||||
@@ -8170,9 +8171,10 @@ fn tupleelemslot(pt: *tinfo) u64 = {
|
||||
// pad-to-8); arrays use their slot-padded element-stride * elen.
|
||||
fn fieldslotsize(ft: *tinfo) u64 = {
|
||||
if (ft == nil) { return 8u64; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
let t: *tinfo = ft;
|
||||
for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; };
|
||||
if (t == nil) { return 8u64; };
|
||||
@@ -11271,6 +11273,15 @@ fn elemissignedc(c: *cgen, t: *node) bool = {
|
||||
if (t == nil) { return false; };
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return false; };
|
||||
// #65 Phase-N step-2 cleanup: peel TY_NAMED before the .sub read.
|
||||
// #64 now flows per-decl NAMED wrappers, so a NAMED-of-(`*T`/`[]T`/
|
||||
// `[N]T`) reaching here would read NAMED.sub (nil) instead of the
|
||||
// element. Mirrors cstage idx_eff's type_unwrap (cmd/w6c/cgen.c:790)
|
||||
// before the eff->sub read (:3518-3520). Byte-id-neutral: every
|
||||
// aliased indexable in-tree has a u8 element (typeissigned=false
|
||||
// either way). Transitive peel matches the #63 idiom.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return false; };
|
||||
return typeissigned(ti.sub);
|
||||
};
|
||||
|
||||
@@ -12195,9 +12206,10 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
||||
if (typn == nil) { return 8; };
|
||||
let ti: *tinfo = typn.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let kk: tykind = ti.kind;
|
||||
@@ -12232,9 +12244,10 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
||||
if (tnode == nil) { return 8; };
|
||||
let ti: *tinfo = tnode.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let k: tykind = ti.kind;
|
||||
@@ -12581,9 +12594,10 @@ export fn nullableptrtag(t: *node) i32 = {
|
||||
if (t == nil) { return 0; };
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return 0; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 0; };
|
||||
if (ti.kind != tykind.TY_TAGGED) { return 0; };
|
||||
|
||||
@@ -747,6 +747,15 @@ fn elemissignedc(c: *cgen, t: *node) bool = {
|
||||
if (t == nil) { return false; };
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return false; };
|
||||
// #65 Phase-N step-2 cleanup: peel TY_NAMED before the .sub read.
|
||||
// #64 now flows per-decl NAMED wrappers, so a NAMED-of-(`*T`/`[]T`/
|
||||
// `[N]T`) reaching here would read NAMED.sub (nil) instead of the
|
||||
// element. Mirrors cstage idx_eff's type_unwrap (cmd/w6c/cgen.c:790)
|
||||
// before the eff->sub read (:3518-3520). Byte-id-neutral: every
|
||||
// aliased indexable in-tree has a u8 element (typeissigned=false
|
||||
// either way). Transitive peel matches the #63 idiom.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return false; };
|
||||
return typeissigned(ti.sub);
|
||||
};
|
||||
|
||||
@@ -1671,9 +1680,10 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
||||
if (typn == nil) { return 8; };
|
||||
let ti: *tinfo = typn.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let kk: tykind = ti.kind;
|
||||
@@ -1708,9 +1718,10 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
||||
if (tnode == nil) { return 8; };
|
||||
let ti: *tinfo = tnode.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let k: tykind = ti.kind;
|
||||
@@ -2057,9 +2068,10 @@ export fn nullableptrtag(t: *node) i32 = {
|
||||
if (t == nil) { return 0; };
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return 0; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 0; };
|
||||
if (ti.kind != tykind.TY_TAGGED) { return 0; };
|
||||
|
||||
@@ -1042,9 +1042,10 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = {
|
||||
// fallback arm).
|
||||
fn tupleelemslot(pt: *tinfo) u64 = {
|
||||
if (pt == nil) { return 8u64; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
let t: *tinfo = pt;
|
||||
for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; };
|
||||
if (t == nil) { return 8u64; };
|
||||
@@ -1073,9 +1074,10 @@ fn tupleelemslot(pt: *tinfo) u64 = {
|
||||
// pad-to-8); arrays use their slot-padded element-stride * elen.
|
||||
fn fieldslotsize(ft: *tinfo) u64 = {
|
||||
if (ft == nil) { return 8u64; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
let t: *tinfo = ft;
|
||||
for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; };
|
||||
if (t == nil) { return 8u64; };
|
||||
|
||||
@@ -8139,9 +8139,10 @@ fn enumvalfold(body: *node, until: *node, e: *node, out: *u64) bool = {
|
||||
// fallback arm).
|
||||
fn tupleelemslot(pt: *tinfo) u64 = {
|
||||
if (pt == nil) { return 8u64; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
let t: *tinfo = pt;
|
||||
for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; };
|
||||
if (t == nil) { return 8u64; };
|
||||
@@ -8170,9 +8171,10 @@ fn tupleelemslot(pt: *tinfo) u64 = {
|
||||
// pad-to-8); arrays use their slot-padded element-stride * elen.
|
||||
fn fieldslotsize(ft: *tinfo) u64 = {
|
||||
if (ft == nil) { return 8u64; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
let t: *tinfo = ft;
|
||||
for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; };
|
||||
if (t == nil) { return 8u64; };
|
||||
@@ -11271,6 +11273,15 @@ fn elemissignedc(c: *cgen, t: *node) bool = {
|
||||
if (t == nil) { return false; };
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return false; };
|
||||
// #65 Phase-N step-2 cleanup: peel TY_NAMED before the .sub read.
|
||||
// #64 now flows per-decl NAMED wrappers, so a NAMED-of-(`*T`/`[]T`/
|
||||
// `[N]T`) reaching here would read NAMED.sub (nil) instead of the
|
||||
// element. Mirrors cstage idx_eff's type_unwrap (cmd/w6c/cgen.c:790)
|
||||
// before the eff->sub read (:3518-3520). Byte-id-neutral: every
|
||||
// aliased indexable in-tree has a u8 element (typeissigned=false
|
||||
// either way). Transitive peel matches the #63 idiom.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return false; };
|
||||
return typeissigned(ti.sub);
|
||||
};
|
||||
|
||||
@@ -12195,9 +12206,10 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
||||
if (typn == nil) { return 8; };
|
||||
let ti: *tinfo = typn.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let kk: tykind = ti.kind;
|
||||
@@ -12232,9 +12244,10 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
||||
if (tnode == nil) { return 8; };
|
||||
let ti: *tinfo = tnode.type_: *tinfo;
|
||||
if (ti == nil) { return 8; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 8; };
|
||||
let k: tykind = ti.kind;
|
||||
@@ -12581,9 +12594,10 @@ export fn nullableptrtag(t: *node) i32 = {
|
||||
if (t == nil) { return 0; };
|
||||
let ti: *tinfo = t.type_: *tinfo;
|
||||
if (ti == nil) { return 0; };
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query;
|
||||
// wrappers are built in step 2 (#64). No-op today (tinfofornode
|
||||
// still collapses aliases → no TY_NAMED), so byte-id is unchanged.
|
||||
// #63 Phase-N step 1: peel TY_NAMED before this structural query.
|
||||
// #64 builds per-decl NAMED wrappers (tinfofornode), so the peel
|
||||
// now fires on aliased operands; byte-id holds because it collapses
|
||||
// NAMED to the alias-invariant underlying this read consumes.
|
||||
for (ti != nil && ti.kind == tykind.TY_NAMED) { ti = ti.under; };
|
||||
if (ti == nil) { return 0; };
|
||||
if (ti.kind != tykind.TY_TAGGED) { return 0; };
|
||||
|
||||
Reference in New Issue
Block a user