check: reject an untyped array-literal borrow into a union slice variant (#18)

This commit is contained in:
2026-06-28 11:27:24 +09:00
parent c6cdd8c2d6
commit d0ce55cab8
2 changed files with 55 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
//ww:error "not assignable"
// #18 carrier: an UNTYPED-int array literal returned into a tagged-union SLICE
// success variant ([]i32 | e). The literal defaults to [3]int, which is NOT
// assignable to any variant ([]i32 wants i32 elements; e is i32), so BOTH stages
// must REJECT at the assignability layer — harec tagged_select_subtype needs a
// UNIQUE assignable member and the STORAGE_SLICE arm requires element identity
// (ref/harec/src/types.c:702 + :1097). cstage rejects via type_assignable
// returning 0 (cmd/wcc/type.c:344); wwstage's isassignable previously shape-
// matched [3]int against the `e` (i32) scalar variant (both tagshape 0) and went
// LENIENT (confident=false), so checkretassign short-circuited before the borrow
// gate and SILENTLY ACCEPTED — a wwstage-only miscompile (cs≠ww). The fix makes
// an array src with no element-matching variant a CONFIDENT reject in isassignable.
// Sibling of #13 (the TYPED-literal leg, rejected by the borrow gate after it
// passes assignability) and distinct from #17 (a legal array VARIABLE coercion).
package main;
type e = !i32;
fn mk() ([]i32 | e) = { return [10, 20, 30]; };
export fn main() i32 = {
let s: []i32 = mk()!;
return s[0];
};