diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index b9295e3a..e80cb000 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -8897,6 +8897,23 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; + if (k == nkind.N_YIELD) { + // A.6.2.0f — pass-through stamp; cstage check.c:1708 does NOT + // stamp N_YIELD (statement-shaped). Wwstage's A.6.2 invariant + // requires every post-dispatch kind have type_ set. Yield's + // value type is the operand's type per Hare's unified stmt/expr + // AST (ref/hare/hare/ast/expr.ha:449-461 — yield_expr is an + // expression with a type). Bare `yield;` (no operand) stamps + // void. + if (e.lhs == nil) { + let v: *node = mktname(c, "void"); + e.type_ = tinfofornode(c, v): *void; + return v; + }; + let t: *node = exprtype(c, e.lhs, nil); + if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; + return t; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union. diff --git a/selfhost/cmd/wcc/check.ww b/selfhost/cmd/wcc/check.ww index 96a332c2..0b226e51 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -1933,6 +1933,23 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; + if (k == nkind.N_YIELD) { + // A.6.2.0f — pass-through stamp; cstage check.c:1708 does NOT + // stamp N_YIELD (statement-shaped). Wwstage's A.6.2 invariant + // requires every post-dispatch kind have type_ set. Yield's + // value type is the operand's type per Hare's unified stmt/expr + // AST (ref/hare/hare/ast/expr.ha:449-461 — yield_expr is an + // expression with a type). Bare `yield;` (no operand) stamps + // void. + if (e.lhs == nil) { + let v: *node = mktname(c, "void"); + e.type_ = tinfofornode(c, v): *void; + return v; + }; + let t: *node = exprtype(c, e.lhs, nil); + if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; + return t; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union. diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 7554014f..b12d889b 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -8897,6 +8897,23 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = { if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; return t; }; + if (k == nkind.N_YIELD) { + // A.6.2.0f — pass-through stamp; cstage check.c:1708 does NOT + // stamp N_YIELD (statement-shaped). Wwstage's A.6.2 invariant + // requires every post-dispatch kind have type_ set. Yield's + // value type is the operand's type per Hare's unified stmt/expr + // AST (ref/hare/hare/ast/expr.ha:449-461 — yield_expr is an + // expression with a type). Bare `yield;` (no operand) stamps + // void. + if (e.lhs == nil) { + let v: *node = mktname(c, "void"); + e.type_ = tinfofornode(c, v): *void; + return v; + }; + let t: *node = exprtype(c, e.lhs, nil); + if (t != nil) { e.type_ = tinfofornode(c, t): *void; }; + return t; + }; if (k == nkind.N_TRYPROP) { // success unwrap: the success-variant type of operand's // tagged union.