check: lower an array-variable borrow into a union slice success variant (#17)
This commit is contained in:
@@ -5639,6 +5639,25 @@ fn desugararrayslice(c: *checker, dsttn: *syntax.node, srctn: *syntax.node, val:
|
||||
let su: *syntax.node = resolvealias(c, unwrapbang(srctn));
|
||||
if (du == nil) { return val; };
|
||||
if (su == nil) { return val; };
|
||||
// #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 rejectarrlitborrow N_TTAGGED
|
||||
// chase (an array LITERAL has no outliving backing and is rejected there
|
||||
// first; a variable has storage, so this borrow is legal).
|
||||
if (du.kind == syntax.nkind.N_TTAGGED && su.kind == syntax.nkind.N_TARRAY) {
|
||||
let v: *syntax.node = du.list;
|
||||
for (v != nil) {
|
||||
let vu: *syntax.node = resolvealias(c, unwrapbang(v));
|
||||
if (vu != nil && vu.kind == syntax.nkind.N_TSLICE && typeeqast(c, vu.lhs, su.lhs)) {
|
||||
du = vu;
|
||||
break;
|
||||
};
|
||||
v = v.next;
|
||||
};
|
||||
};
|
||||
if (du.kind != syntax.nkind.N_TSLICE) { return val; };
|
||||
if (su.kind != syntax.nkind.N_TARRAY) { return val; };
|
||||
if (!typeeqast(c, du.lhs, su.lhs)) { return val; };
|
||||
|
||||
Reference in New Issue
Block a user