wcc: #99 alias-of-tuple — chase TY_NAMED in tuple coercion (cstage) + param spill (wwstage)
type pair = (int, int); let x: pair = (3, 4) -- an alias of a tuple initialized from an untyped literal, and passing such a value to a fn -- was a both-stage bug, mirror-twins of the same TY_NAMED-not-chased root: cstage CHECKER over-rejected the init (not assignable to declared pair): type.c's tuple-assignable arm gated on the un-chased dst kind, so a TY_NAMED alias skipped the per-element untyped->int coercion the direct tuple path applies. Fix: chase TY_NAMED both sides (mirrors the #258 slice-borrow arm). Direct and typed-alias tuples already worked; only alias+untyped was rejected. wwstage CGEN dropped the second word of an alias-tuple fn-arg: the tuple-param spill at cgendecl.ww gated on the syntactic N_TTUPLE, so an alias param (N_TNAME) fell to the scalar path and spilled one slot -> t.1 read frame garbage. Fix: chase the alias via aliaslookup to the resolved N_TTUPLE and spill all its slots. cstage cgen was already correct -- the bug was checker-only there. Converges cs==ww byte-id. One commit: same construct, the two halves must ship together (either alone leaves cs!=ww). test/wcc/826 (init/fn-arg/return, 2-field byte-id); test/wcc/944 4 rows graduated err->run-correct. byte-id 990-997 8/8.
This commit is contained in:
@@ -398,14 +398,23 @@ type_assignable(Type *dst, Type *src)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Tuple-to-tuple: element-wise assignable. */
|
||||
if (dst->kind == TY_TUPLE && src->kind == TY_TUPLE) {
|
||||
Tparam *pa = dst->params, *pb = src->params;
|
||||
while (pa && pb) {
|
||||
if (!type_assignable(pa->type, pb->type)) return 0;
|
||||
pa = pa->next; pb = pb->next;
|
||||
/* Tuple-to-tuple: element-wise assignable. Chase a TY_NAMED alias on
|
||||
* either side first (#99): `type pair=(int,int); let x: pair = (3,4)`
|
||||
* was rejected because dst->kind is TY_NAMED, skipping this arm — the
|
||||
* direct-tuple path coerces the untyped elements fine. Aliases are
|
||||
* transparent; mirrors the #258 slice-borrow arm just below which
|
||||
* already type_chase_named's both sides. */
|
||||
{
|
||||
Type *du = type_chase_named(dst);
|
||||
Type *su = type_chase_named(src);
|
||||
if (du && su && du->kind == TY_TUPLE && su->kind == TY_TUPLE) {
|
||||
Tparam *pa = du->params, *pb = su->params;
|
||||
while (pa && pb) {
|
||||
if (!type_assignable(pa->type, pb->type)) return 0;
|
||||
pa = pa->next; pb = pb->next;
|
||||
}
|
||||
return pa == NULL && pb == NULL;
|
||||
}
|
||||
return pa == NULL && pb == NULL;
|
||||
}
|
||||
|
||||
/* #258: implicit [N]T → []T array-to-slice borrow. Hare admits an
|
||||
|
||||
Reference in New Issue
Block a user