cmd+selfhost+test: relax alloc-slice element-type pin via LHS retype
`alloc([], n)` synthesizes ([]u8 | nomem) at expression level — that's fine, since the slice form only legitimately appears in let-init position where the LHS carries the real element type. In clet, after type-checking the rhs, peel any N_TRYPROP/N_TRYUNW wrapper, match the alloc-slice AST shape with the same-module shadow gate (from #23), and retype the call's tagged return to ([]T | nomem) where T is the declared LHS element. Then assignability sees []T vs []T and accepts. Cgen N_LET shortcut gains a viatryprop arm next to the existing viatryunw — on rt_alloc returning null, emits the tagged-return nomem propagation (MOVQ $nidx, AX; epilogue) instead of exit(1). nidx comes from cg_tag_for_variant on the enclosing fn's return type, matching the existing TRYPROP propret path. Wwstage mirrors all four hunks (check.ww + cgenstmt.ww). Promotes the previously-silent conf=false skip into a confident accept. Unblocks #6 (dupall) and lays the path for #4/#7. Byte-identity holds modulo the pre-existing #44 alloc/rt_alloc symbol divergence.
This commit is contained in:
@@ -199,6 +199,24 @@ main(void)
|
||||
" for (let (k, v) .. s) { total += k + v; };\n"
|
||||
" return total: i32;\n"
|
||||
"};" },
|
||||
/* #45: alloc-slice `!` form, []T element ≠ u8. */
|
||||
{ "alloc_slice_rune_unw",
|
||||
"package main;\n"
|
||||
"import os;\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let s: []rune = alloc([], 8)!;\n"
|
||||
" return s.cap;\n"
|
||||
"};" },
|
||||
/* #45: alloc-slice `?` form propagates nomem via the
|
||||
* enclosing fn's tagged return. */
|
||||
{ "alloc_slice_str_prop",
|
||||
"package main;\n"
|
||||
"import os;\n"
|
||||
"fn doit() (i32 | nomem) = {\n"
|
||||
" let s: []str = alloc([], 4)?;\n"
|
||||
" return s.cap: i32;\n"
|
||||
"};\n"
|
||||
"fn main() i32 = { return doit()!; };" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user