wcc/check: #26 recurse over-fill walk into nested tuple element (wwstage)
extracts the shared checktuplearrfits helper (also used by #25); wwstage-only checker reject-align, cstage already louds.
This commit is contained in:
@@ -14649,6 +14649,35 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// checktuplearrfits — #20/#25/#26: walk a declared tuple type's
|
||||
// element types (ttn.list, each N_TPARAM-wrapped → type on .lhs)
|
||||
// lockstep with an N_TUPLE rhs's values (tup.list, chained directly).
|
||||
// An array-literal element runs the alias-aware over-fill
|
||||
// checkarrlitfits; a nested-tuple element (declared N_TTUPLE vs rhs
|
||||
// N_TUPLE) recurses. Shared by checkletassign (let) and
|
||||
// checkretassign (return). Mirrors cstage's element-wise
|
||||
// type_assignable count-reject; no-ops on scalar elements.
|
||||
fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = {
|
||||
if (ttn == nil) { return; };
|
||||
if (tup == nil) { return; };
|
||||
let dt: *node = ttn.list;
|
||||
let vt: *node = tup.list;
|
||||
for (dt != nil && vt != nil) {
|
||||
if (vt.kind == nkind.N_ARRLIT) {
|
||||
checkarrlitfits(c, dt.lhs, vt);
|
||||
} else {
|
||||
if (vt.kind == nkind.N_TUPLE) {
|
||||
let drt: *node = resolvealias(c, unwrapbang(dt.lhs));
|
||||
if (drt != nil && drt.kind == nkind.N_TTUPLE) {
|
||||
checktuplearrfits(c, drt, vt);
|
||||
};
|
||||
};
|
||||
};
|
||||
dt = dt.next;
|
||||
vt = vt.next;
|
||||
};
|
||||
};
|
||||
|
||||
// desugararrayslice — #258. The single shared lowering for the implicit
|
||||
// [N]T -> []T borrow. isassignable already admits an array with a defined
|
||||
// length into a matching []T slot (see isassignable's #258 arm); here we
|
||||
@@ -15005,24 +15034,16 @@ fn checkletassign(c: *checker, n: *node) void = {
|
||||
// #20: array-typed TUPLE element with an overlong array literal —
|
||||
// `let t:([2]int,i32) = ([1,2,3],5)` was silently accepted (the tuple
|
||||
// position wasn't wired to checkarrlitfits, unlike the direct-array
|
||||
// let above). Walk declared-tuple element types vs rhs values; over-
|
||||
// fill-check each (checkarrlitfits chases aliases #106, recurses
|
||||
// nested arrays #251, and no-ops on non-array elements). Mirror
|
||||
// cstage's tuple element-wise reject. No early return — the rest of
|
||||
// checkletassign still runs for the tuple. N_TTUPLE elements wrap
|
||||
// their type on .lhs (N_TPARAM chain, stamptuplebinds:311); the
|
||||
// N_TUPLE rhs values chain directly on .list.
|
||||
// let above). #26: the walk now lives in checktuplearrfits, which also
|
||||
// recurses into a nested-tuple element (checkarrlitfits chases aliases
|
||||
// #106, recurses nested arrays #251; the helper no-ops on non-array,
|
||||
// non-tuple elements). Mirror cstage's tuple element-wise reject. No
|
||||
// early return — the rest of checkletassign still runs for the tuple.
|
||||
// N_TTUPLE elements wrap their type on .lhs (N_TPARAM chain,
|
||||
// stamptuplebinds:311); the N_TUPLE rhs values chain directly on .list.
|
||||
if (llhs != nil && llhs.kind == nkind.N_TTUPLE
|
||||
&& n.rhs.kind == nkind.N_TUPLE) {
|
||||
let dt: *node = llhs.list;
|
||||
let vt: *node = n.rhs.list;
|
||||
for (dt != nil && vt != nil) {
|
||||
if (vt.kind == nkind.N_ARRLIT) {
|
||||
checkarrlitfits(c, dt.lhs, vt);
|
||||
};
|
||||
dt = dt.next;
|
||||
vt = vt.next;
|
||||
};
|
||||
checktuplearrfits(c, llhs, n.rhs);
|
||||
};
|
||||
// #25/#31: an array literal initialising a SLICE local. Re-stamp the
|
||||
// literal as [count]T (the slice element) so the #258 borrow's exact-
|
||||
|
||||
@@ -4368,6 +4368,35 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// checktuplearrfits — #20/#25/#26: walk a declared tuple type's
|
||||
// element types (ttn.list, each N_TPARAM-wrapped → type on .lhs)
|
||||
// lockstep with an N_TUPLE rhs's values (tup.list, chained directly).
|
||||
// An array-literal element runs the alias-aware over-fill
|
||||
// checkarrlitfits; a nested-tuple element (declared N_TTUPLE vs rhs
|
||||
// N_TUPLE) recurses. Shared by checkletassign (let) and
|
||||
// checkretassign (return). Mirrors cstage's element-wise
|
||||
// type_assignable count-reject; no-ops on scalar elements.
|
||||
fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = {
|
||||
if (ttn == nil) { return; };
|
||||
if (tup == nil) { return; };
|
||||
let dt: *node = ttn.list;
|
||||
let vt: *node = tup.list;
|
||||
for (dt != nil && vt != nil) {
|
||||
if (vt.kind == nkind.N_ARRLIT) {
|
||||
checkarrlitfits(c, dt.lhs, vt);
|
||||
} else {
|
||||
if (vt.kind == nkind.N_TUPLE) {
|
||||
let drt: *node = resolvealias(c, unwrapbang(dt.lhs));
|
||||
if (drt != nil && drt.kind == nkind.N_TTUPLE) {
|
||||
checktuplearrfits(c, drt, vt);
|
||||
};
|
||||
};
|
||||
};
|
||||
dt = dt.next;
|
||||
vt = vt.next;
|
||||
};
|
||||
};
|
||||
|
||||
// desugararrayslice — #258. The single shared lowering for the implicit
|
||||
// [N]T -> []T borrow. isassignable already admits an array with a defined
|
||||
// length into a matching []T slot (see isassignable's #258 arm); here we
|
||||
@@ -4724,24 +4753,16 @@ fn checkletassign(c: *checker, n: *node) void = {
|
||||
// #20: array-typed TUPLE element with an overlong array literal —
|
||||
// `let t:([2]int,i32) = ([1,2,3],5)` was silently accepted (the tuple
|
||||
// position wasn't wired to checkarrlitfits, unlike the direct-array
|
||||
// let above). Walk declared-tuple element types vs rhs values; over-
|
||||
// fill-check each (checkarrlitfits chases aliases #106, recurses
|
||||
// nested arrays #251, and no-ops on non-array elements). Mirror
|
||||
// cstage's tuple element-wise reject. No early return — the rest of
|
||||
// checkletassign still runs for the tuple. N_TTUPLE elements wrap
|
||||
// their type on .lhs (N_TPARAM chain, stamptuplebinds:311); the
|
||||
// N_TUPLE rhs values chain directly on .list.
|
||||
// let above). #26: the walk now lives in checktuplearrfits, which also
|
||||
// recurses into a nested-tuple element (checkarrlitfits chases aliases
|
||||
// #106, recurses nested arrays #251; the helper no-ops on non-array,
|
||||
// non-tuple elements). Mirror cstage's tuple element-wise reject. No
|
||||
// early return — the rest of checkletassign still runs for the tuple.
|
||||
// N_TTUPLE elements wrap their type on .lhs (N_TPARAM chain,
|
||||
// stamptuplebinds:311); the N_TUPLE rhs values chain directly on .list.
|
||||
if (llhs != nil && llhs.kind == nkind.N_TTUPLE
|
||||
&& n.rhs.kind == nkind.N_TUPLE) {
|
||||
let dt: *node = llhs.list;
|
||||
let vt: *node = n.rhs.list;
|
||||
for (dt != nil && vt != nil) {
|
||||
if (vt.kind == nkind.N_ARRLIT) {
|
||||
checkarrlitfits(c, dt.lhs, vt);
|
||||
};
|
||||
dt = dt.next;
|
||||
vt = vt.next;
|
||||
};
|
||||
checktuplearrfits(c, llhs, n.rhs);
|
||||
};
|
||||
// #25/#31: an array literal initialising a SLICE local. Re-stamp the
|
||||
// literal as [count]T (the slice element) so the #258 borrow's exact-
|
||||
|
||||
@@ -14649,6 +14649,35 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// checktuplearrfits — #20/#25/#26: walk a declared tuple type's
|
||||
// element types (ttn.list, each N_TPARAM-wrapped → type on .lhs)
|
||||
// lockstep with an N_TUPLE rhs's values (tup.list, chained directly).
|
||||
// An array-literal element runs the alias-aware over-fill
|
||||
// checkarrlitfits; a nested-tuple element (declared N_TTUPLE vs rhs
|
||||
// N_TUPLE) recurses. Shared by checkletassign (let) and
|
||||
// checkretassign (return). Mirrors cstage's element-wise
|
||||
// type_assignable count-reject; no-ops on scalar elements.
|
||||
fn checktuplearrfits(c: *checker, ttn: *node, tup: *node) void = {
|
||||
if (ttn == nil) { return; };
|
||||
if (tup == nil) { return; };
|
||||
let dt: *node = ttn.list;
|
||||
let vt: *node = tup.list;
|
||||
for (dt != nil && vt != nil) {
|
||||
if (vt.kind == nkind.N_ARRLIT) {
|
||||
checkarrlitfits(c, dt.lhs, vt);
|
||||
} else {
|
||||
if (vt.kind == nkind.N_TUPLE) {
|
||||
let drt: *node = resolvealias(c, unwrapbang(dt.lhs));
|
||||
if (drt != nil && drt.kind == nkind.N_TTUPLE) {
|
||||
checktuplearrfits(c, drt, vt);
|
||||
};
|
||||
};
|
||||
};
|
||||
dt = dt.next;
|
||||
vt = vt.next;
|
||||
};
|
||||
};
|
||||
|
||||
// desugararrayslice — #258. The single shared lowering for the implicit
|
||||
// [N]T -> []T borrow. isassignable already admits an array with a defined
|
||||
// length into a matching []T slot (see isassignable's #258 arm); here we
|
||||
@@ -15005,24 +15034,16 @@ fn checkletassign(c: *checker, n: *node) void = {
|
||||
// #20: array-typed TUPLE element with an overlong array literal —
|
||||
// `let t:([2]int,i32) = ([1,2,3],5)` was silently accepted (the tuple
|
||||
// position wasn't wired to checkarrlitfits, unlike the direct-array
|
||||
// let above). Walk declared-tuple element types vs rhs values; over-
|
||||
// fill-check each (checkarrlitfits chases aliases #106, recurses
|
||||
// nested arrays #251, and no-ops on non-array elements). Mirror
|
||||
// cstage's tuple element-wise reject. No early return — the rest of
|
||||
// checkletassign still runs for the tuple. N_TTUPLE elements wrap
|
||||
// their type on .lhs (N_TPARAM chain, stamptuplebinds:311); the
|
||||
// N_TUPLE rhs values chain directly on .list.
|
||||
// let above). #26: the walk now lives in checktuplearrfits, which also
|
||||
// recurses into a nested-tuple element (checkarrlitfits chases aliases
|
||||
// #106, recurses nested arrays #251; the helper no-ops on non-array,
|
||||
// non-tuple elements). Mirror cstage's tuple element-wise reject. No
|
||||
// early return — the rest of checkletassign still runs for the tuple.
|
||||
// N_TTUPLE elements wrap their type on .lhs (N_TPARAM chain,
|
||||
// stamptuplebinds:311); the N_TUPLE rhs values chain directly on .list.
|
||||
if (llhs != nil && llhs.kind == nkind.N_TTUPLE
|
||||
&& n.rhs.kind == nkind.N_TUPLE) {
|
||||
let dt: *node = llhs.list;
|
||||
let vt: *node = n.rhs.list;
|
||||
for (dt != nil && vt != nil) {
|
||||
if (vt.kind == nkind.N_ARRLIT) {
|
||||
checkarrlitfits(c, dt.lhs, vt);
|
||||
};
|
||||
dt = dt.next;
|
||||
vt = vt.next;
|
||||
};
|
||||
checktuplearrfits(c, llhs, n.rhs);
|
||||
};
|
||||
// #25/#31: an array literal initialising a SLICE local. Re-stamp the
|
||||
// literal as [count]T (the slice element) so the #258 borrow's exact-
|
||||
|
||||
Reference in New Issue
Block a user