diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 6c994e7c..82ce2955 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -10740,6 +10740,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // and no dot applies to a u8 binding. let et: *node = nil; let it: *node = exprtype(c, n.lhs, nil); + // #80 (F2a batch-4 c4): an alias-typed iterable + // arrives as N_TNAME — without the AST-level + // dealias the binder fell to the N_FORRANGE + // fallback decl, stayed untyped, and any binop + // over the rangevar asserttyped-bailed (cs + // accepts: its scope_define types the elem). + if (it != nil) { it = resolvealias(c, unwrapbang(it)); }; if (it != nil) { if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; diff --git a/selfhost/cmd/wcc/check.ww b/selfhost/cmd/wcc/check.ww index ed0ce600..a6db7ca6 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -468,6 +468,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // and no dot applies to a u8 binding. let et: *node = nil; let it: *node = exprtype(c, n.lhs, nil); + // #80 (F2a batch-4 c4): an alias-typed iterable + // arrives as N_TNAME — without the AST-level + // dealias the binder fell to the N_FORRANGE + // fallback decl, stayed untyped, and any binop + // over the rangevar asserttyped-bailed (cs + // accepts: its scope_define types the elem). + if (it != nil) { it = resolvealias(c, unwrapbang(it)); }; if (it != nil) { if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index d4ea2165..495ca11d 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -10740,6 +10740,13 @@ fn resolvewalk(c: *checker, n: *node) void = { // and no dot applies to a u8 binding. let et: *node = nil; let it: *node = exprtype(c, n.lhs, nil); + // #80 (F2a batch-4 c4): an alias-typed iterable + // arrives as N_TNAME — without the AST-level + // dealias the binder fell to the N_FORRANGE + // fallback decl, stayed untyped, and any binop + // over the rangevar asserttyped-bailed (cs + // accepts: its scope_define types the elem). + if (it != nil) { it = resolvealias(c, unwrapbang(it)); }; if (it != nil) { if (it.kind == nkind.N_TSLICE) { et = it.lhs; }; if (it.kind == nkind.N_TARRAY) { et = it.lhs; }; diff --git a/test/wcc/944_alias_accept_run.c b/test/wcc/944_alias_accept_run.c index 3e344a92..38d02186 100644 --- a/test/wcc/944_alias_accept_run.c +++ b/test/wcc/944_alias_accept_run.c @@ -1106,6 +1106,37 @@ static const struct row rows[] = { " return check(b);\n" "};\n", 0, K_RUN_CS_WWERR, "unsupported address-of shape" }, /* ww: task #96 */ + /* ---- F2a batch-4 c4 (#80): bare-binder N_FORRANGE over an + * alias-typed iterable — the binder type derivation read the + * scrutinee's type expr without dealiasing (N_TNAME missed the + * N_TSLICE/N_TARRAY tests), binder fell to the untyped fallback + * decl, `untyped_lit * rangevar` asserttyped-bailed on ww only + * (cs scope_define types the elem). Re-probed AFTER c1 per spec: + * still live (the chase set didn't cover this AST-keyed read). + * Tuple-destructure arm sibling FILED (task #97, double-masked). */ + { "rangevar_alias2", /* the #80 repro shape */ + "package main;\n" + "type slk = []int;\n" + "export fn main() i32 = {\n" + " let a: [4]int = [10: int, 20: int, 30: int, 40: int];\n" + " let t: slk = a[2:];\n" + " if (t.len != 2) { return 1; };\n" + " if (t.cap != 2) { return 2; };\n" + " let sum: int = 0;\n" + " for (let x .. t) { sum = sum + 0 * x + 1; };\n" + " if (sum != 2) { return 3; };\n" + " return 0;\n" + "};\n", 0, K_RUN, NULL }, + { "rangevar_plain_ctl", /* non-alias control — held throughout */ + "package main;\n" + "export fn main() i32 = {\n" + " let a: [4]int = [10: int, 20: int, 30: int, 40: int];\n" + " let t: []int = a[2:];\n" + " let sum: int = 0;\n" + " for (let x .. t) { sum = sum + 0 * x + 1; };\n" + " if (sum != 2) { return 3; };\n" + " return 0;\n" + "};\n", 0, K_RUN, NULL }, /* BOUND expected-state row (#199α + #90): untyped literal into a * NESTED-tagged alias-wrapped variant. cs CHECKER loud-rejects — * the #199α ww-stricter no-transitive-drill rule (type.c:316-324);