checkletassign previously early-returned on `n.lhs == nil`, so an inferred binding (`let r = expr;`) left decl.lhs unset; exprtype's N_IDENT branch at check.ww:1550 reads `s.decl.lhs` and so the use sites lost the inferred type. Mirrors cstage cmd/wcc/check.c:1477 clet `if (t == NULL && initt) t = type_default(initt);` and ref/harec/src/check.c:1422 check_expr_binding. cstage carries the let type on Sym.type; wwstage carries it on decl.lhs — same observable result, byte-id (rule 10) intact. Defaulting (untyped_int → i32) stays at use sites in exprtype, not the binding site. Mutation layer matches #41's installparams parser-decl-mutation precedent at check.ww:2747. Table-driven test deferred to #44 per the speed-first cadence; existing 990–997 byte-id corpus implicitly exercises inferred lets. Context for the capture sweep: #36.
This commit is contained in:
@@ -9465,11 +9465,22 @@ fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = {
|
||||
|
||||
fn checkletassign(c: *checker, n: *node) void = {
|
||||
if (n == nil) { return; };
|
||||
if (n.lhs == nil) { return; }; // no declared type, nothing to check
|
||||
if (n.rhs == nil) { return; }; // no init
|
||||
// hint = nil for A.6.0; A.6.1 will pass n.lhs once STRUCTLIT/ARRLIT
|
||||
// arms consume it. Plumbing-only at this point.
|
||||
let src: *node = exprtype(c, n.rhs, nil);
|
||||
// Inferred binding (`let r = expr;`, no type annotation). Mirror
|
||||
// cstage cmd/wcc/check.c:1477 clet `if (t == NULL && initt) t =
|
||||
// type_default(initt);` and ref/harec/src/check.c:1422
|
||||
// check_expr_binding. wwstage carries the let's type on decl.lhs
|
||||
// (exprtype N_IDENT at L1546 reads s.decl.lhs); cstage carries it
|
||||
// on Sym.type — same observable result, rule-10 byte-id holds.
|
||||
// Defaulting (untyped_int → i32, etc.) is exprtype's job at use
|
||||
// sites, not the binding site.
|
||||
if (n.lhs == nil) {
|
||||
if (src != nil) { n.lhs = src; };
|
||||
return;
|
||||
};
|
||||
if (src == nil) { return; }; // can't infer
|
||||
// #45: alloc([], n) defers element type to the let-init context
|
||||
// (Hare-style). exprtype's alloc-slice branch synthesizes
|
||||
|
||||
@@ -2501,11 +2501,22 @@ fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = {
|
||||
|
||||
fn checkletassign(c: *checker, n: *node) void = {
|
||||
if (n == nil) { return; };
|
||||
if (n.lhs == nil) { return; }; // no declared type, nothing to check
|
||||
if (n.rhs == nil) { return; }; // no init
|
||||
// hint = nil for A.6.0; A.6.1 will pass n.lhs once STRUCTLIT/ARRLIT
|
||||
// arms consume it. Plumbing-only at this point.
|
||||
let src: *node = exprtype(c, n.rhs, nil);
|
||||
// Inferred binding (`let r = expr;`, no type annotation). Mirror
|
||||
// cstage cmd/wcc/check.c:1477 clet `if (t == NULL && initt) t =
|
||||
// type_default(initt);` and ref/harec/src/check.c:1422
|
||||
// check_expr_binding. wwstage carries the let's type on decl.lhs
|
||||
// (exprtype N_IDENT at L1546 reads s.decl.lhs); cstage carries it
|
||||
// on Sym.type — same observable result, rule-10 byte-id holds.
|
||||
// Defaulting (untyped_int → i32, etc.) is exprtype's job at use
|
||||
// sites, not the binding site.
|
||||
if (n.lhs == nil) {
|
||||
if (src != nil) { n.lhs = src; };
|
||||
return;
|
||||
};
|
||||
if (src == nil) { return; }; // can't infer
|
||||
// #45: alloc([], n) defers element type to the let-init context
|
||||
// (Hare-style). exprtype's alloc-slice branch synthesizes
|
||||
|
||||
@@ -9465,11 +9465,22 @@ fn errnotassign(c: *checker, dst: *node, src: *node, where: str) void = {
|
||||
|
||||
fn checkletassign(c: *checker, n: *node) void = {
|
||||
if (n == nil) { return; };
|
||||
if (n.lhs == nil) { return; }; // no declared type, nothing to check
|
||||
if (n.rhs == nil) { return; }; // no init
|
||||
// hint = nil for A.6.0; A.6.1 will pass n.lhs once STRUCTLIT/ARRLIT
|
||||
// arms consume it. Plumbing-only at this point.
|
||||
let src: *node = exprtype(c, n.rhs, nil);
|
||||
// Inferred binding (`let r = expr;`, no type annotation). Mirror
|
||||
// cstage cmd/wcc/check.c:1477 clet `if (t == NULL && initt) t =
|
||||
// type_default(initt);` and ref/harec/src/check.c:1422
|
||||
// check_expr_binding. wwstage carries the let's type on decl.lhs
|
||||
// (exprtype N_IDENT at L1546 reads s.decl.lhs); cstage carries it
|
||||
// on Sym.type — same observable result, rule-10 byte-id holds.
|
||||
// Defaulting (untyped_int → i32, etc.) is exprtype's job at use
|
||||
// sites, not the binding site.
|
||||
if (n.lhs == nil) {
|
||||
if (src != nil) { n.lhs = src; };
|
||||
return;
|
||||
};
|
||||
if (src == nil) { return; }; // can't infer
|
||||
// #45: alloc([], n) defers element type to the let-init context
|
||||
// (Hare-style). exprtype's alloc-slice branch synthesizes
|
||||
|
||||
Reference in New Issue
Block a user