check: lower an array-variable borrow into a union slice success variant (#17)
This commit is contained in:
@@ -1221,6 +1221,25 @@ desugar_arrayslice(Checker *c, Type *dst, Node *expr)
|
||||
return;
|
||||
Type *du = type_chase_named(dst);
|
||||
Type *su = type_chase_named(expr->type);
|
||||
/* #17: the borrow target may be the SLICE success variant of a tagged
|
||||
* union (`return/assign/let/f(arr)` into `([]T|e)`). Chase du to that
|
||||
* variant so an array VARIABLE lowers to a full slice exactly as a
|
||||
* bare []T dst does — the existing slice cgen then builds the full
|
||||
* {ptr,len,cap} header and the union widen's slice arm wraps it,
|
||||
* closing the silent len/cap drop. Mirrors #13's reject_arrlit_borrow
|
||||
* TY_TAGGED chase (an array LITERAL has no outliving backing and is
|
||||
* rejected there first; a variable has storage, so this borrow is
|
||||
* legal). An array-typed variant is the separate #5/#60 reject. */
|
||||
if (du && du->kind == TY_TAGGED && su && su->kind == TY_ARRAY) {
|
||||
for (Tparam *p = du->params; p; p = p->next) {
|
||||
Type *pu = type_chase_named(p->type);
|
||||
if (pu && pu->kind == TY_SLICE
|
||||
&& type_eq(pu->sub, su->sub)) {
|
||||
du = pu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (du == NULL || su == NULL ||
|
||||
du->kind != TY_SLICE || su->kind != TY_ARRAY)
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user