selfhost/cmd/wcc: stamp e.type_ for CAST/TRY/TYPEASSERT/TYPETEST (A.6.1.1)

Phase 1 A.6.1 commit 1. Extends A.6.0's literal+ident type_
population to the CAST + TRY family + TYPEASSERT/TYPETEST arms in
exprtype. Mirrors cstage cmd/wcc/check.c:737 (N_CAST) and
1332-1435 (TYPETEST/TYPEASSERT/TRYPROP/TRYUNW) where n->type is
stamped on each value-returning path.

N_TRYPROP / N_TRYUNW only stamp the value-returning paths
(success-variant match inside the for-loop, no-error tail at
ou.list); the three nil-returning early-outs are intentionally
left unstamped.

Verified 132/132 incl. 995_self_rebuild byte-identity.
This commit is contained in:
2026-05-21 14:27:09 +09:00
parent 321e7ca615
commit c0fe38c101
3 changed files with 57 additions and 15 deletions

View File

@@ -8255,7 +8255,9 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
return t;
};
if (k == nkind.N_CAST) {
// `expr: T` — explicit cast; the type expr is e.rhs.
// `expr: T` — explicit cast; the type expr is e.rhs. Mirrors
// cstage cmd/wcc/check.c:737 `n->type = resolve_type(c, n->rhs)`.
e.type_ = tinfofornode(c, e.rhs): *void;
return e.rhs;
};
if (k == nkind.N_CALL) {
@@ -8396,11 +8398,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
if (taggedhaserr(c, ou)) {
let v: *node = ou.list;
for (v != nil) {
if (!iserrvariant(c, ou, v)) { return v; };
if (!iserrvariant(c, ou, v)) {
e.type_ = tinfofornode(c, v): *void;
return v;
};
v = v.next;
};
return nil;
};
e.type_ = tinfofornode(c, ou.list): *void;
return ou.list;
};
if (k == nkind.N_TRYUNW) {
@@ -8414,20 +8420,28 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
if (taggedhaserr(c, ou)) {
let v: *node = ou.list;
for (v != nil) {
if (!iserrvariant(c, ou, v)) { return v; };
if (!iserrvariant(c, ou, v)) {
e.type_ = tinfofornode(c, v): *void;
return v;
};
v = v.next;
};
return nil;
};
e.type_ = tinfofornode(c, ou.list): *void;
return ou.list;
};
if (k == nkind.N_TYPEASSERT) {
// `e as T` → T
// `e as T` → T. Mirrors cstage cmd/wcc/check.c TYPEASSERT
// `n->type = resolve_type(c, n->rhs)`.
e.type_ = tinfofornode(c, e.rhs): *void;
return e.rhs;
};
if (k == nkind.N_TYPETEST) {
// `e is T` → bool
return mktname(c, "bool");
let tn: *node = mktname(c, "bool");
e.type_ = tinfofornode(c, tn): *void;
return tn;
};
return nil;
};

View File

@@ -1323,7 +1323,9 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
return t;
};
if (k == nkind.N_CAST) {
// `expr: T` — explicit cast; the type expr is e.rhs.
// `expr: T` — explicit cast; the type expr is e.rhs. Mirrors
// cstage cmd/wcc/check.c:737 `n->type = resolve_type(c, n->rhs)`.
e.type_ = tinfofornode(c, e.rhs): *void;
return e.rhs;
};
if (k == nkind.N_CALL) {
@@ -1464,11 +1466,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
if (taggedhaserr(c, ou)) {
let v: *node = ou.list;
for (v != nil) {
if (!iserrvariant(c, ou, v)) { return v; };
if (!iserrvariant(c, ou, v)) {
e.type_ = tinfofornode(c, v): *void;
return v;
};
v = v.next;
};
return nil;
};
e.type_ = tinfofornode(c, ou.list): *void;
return ou.list;
};
if (k == nkind.N_TRYUNW) {
@@ -1482,20 +1488,28 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
if (taggedhaserr(c, ou)) {
let v: *node = ou.list;
for (v != nil) {
if (!iserrvariant(c, ou, v)) { return v; };
if (!iserrvariant(c, ou, v)) {
e.type_ = tinfofornode(c, v): *void;
return v;
};
v = v.next;
};
return nil;
};
e.type_ = tinfofornode(c, ou.list): *void;
return ou.list;
};
if (k == nkind.N_TYPEASSERT) {
// `e as T` → T
// `e as T` → T. Mirrors cstage cmd/wcc/check.c TYPEASSERT
// `n->type = resolve_type(c, n->rhs)`.
e.type_ = tinfofornode(c, e.rhs): *void;
return e.rhs;
};
if (k == nkind.N_TYPETEST) {
// `e is T` → bool
return mktname(c, "bool");
let tn: *node = mktname(c, "bool");
e.type_ = tinfofornode(c, tn): *void;
return tn;
};
return nil;
};

View File

@@ -8255,7 +8255,9 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
return t;
};
if (k == nkind.N_CAST) {
// `expr: T` — explicit cast; the type expr is e.rhs.
// `expr: T` — explicit cast; the type expr is e.rhs. Mirrors
// cstage cmd/wcc/check.c:737 `n->type = resolve_type(c, n->rhs)`.
e.type_ = tinfofornode(c, e.rhs): *void;
return e.rhs;
};
if (k == nkind.N_CALL) {
@@ -8396,11 +8398,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
if (taggedhaserr(c, ou)) {
let v: *node = ou.list;
for (v != nil) {
if (!iserrvariant(c, ou, v)) { return v; };
if (!iserrvariant(c, ou, v)) {
e.type_ = tinfofornode(c, v): *void;
return v;
};
v = v.next;
};
return nil;
};
e.type_ = tinfofornode(c, ou.list): *void;
return ou.list;
};
if (k == nkind.N_TRYUNW) {
@@ -8414,20 +8420,28 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
if (taggedhaserr(c, ou)) {
let v: *node = ou.list;
for (v != nil) {
if (!iserrvariant(c, ou, v)) { return v; };
if (!iserrvariant(c, ou, v)) {
e.type_ = tinfofornode(c, v): *void;
return v;
};
v = v.next;
};
return nil;
};
e.type_ = tinfofornode(c, ou.list): *void;
return ou.list;
};
if (k == nkind.N_TYPEASSERT) {
// `e as T` → T
// `e as T` → T. Mirrors cstage cmd/wcc/check.c TYPEASSERT
// `n->type = resolve_type(c, n->rhs)`.
e.type_ = tinfofornode(c, e.rhs): *void;
return e.rhs;
};
if (k == nkind.N_TYPETEST) {
// `e is T` → bool
return mktname(c, "bool");
let tn: *node = mktname(c, "bool");
e.type_ = tinfofornode(c, tn): *void;
return tn;
};
return nil;
};