diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 49b35211..2ee02f75 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -12436,9 +12436,15 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { return resolvetagged(c, etn); }; if (k == nkind.N_DOT) { - let ft: *node = dotfieldtnode(c, scrut); - if (ft == nil) { return nil; }; - return resolvetagged(c, ft); + // #67: read the field's stamped tinfo off the N_DOT node + // (post-#66 N_DOT carries the field type) instead of the + // dotfieldtnode AST walk. cgmatch's gate reads scrutt.type_ + // via istaggedtype, so the resolved N_TTAGGED node the walk + // produced is no longer the carrier; the istaggedtype guard + // preserves the nil-for-non-tagged contract the sibling + // N_CALL/N_INDEX branches get from resolvetagged. + if (!istaggedtype(c, scrut)) { return nil; }; + return scrut; }; return nil; }; @@ -15115,7 +15121,11 @@ fn cgmatch(c: *cgen, n: *node) void = { } else { let want: i32 = 0; if (scrutt != nil) { - if (scrutt.kind == nkind.N_TTAGGED) { + // #67: gate on the stamped tinfo, not the node kind + // — matchscrutt now returns the scrutinee node itself + // for an N_DOT field (its .type_ is the tagged tinfo) + // rather than the resolved N_TTAGGED node. + if (istaggedtype(c, scrutt)) { let r: i32 = -1; if (pat.kind == nkind.N_TNAME) { r = flatvariantidx(c, scrutt, pat); diff --git a/selfhost/cmd/wcc/cgenexpr.ww b/selfhost/cmd/wcc/cgenexpr.ww index dd2f1565..e5f8c1c0 100644 --- a/selfhost/cmd/wcc/cgenexpr.ww +++ b/selfhost/cmd/wcc/cgenexpr.ww @@ -1116,7 +1116,11 @@ fn cgmatch(c: *cgen, n: *node) void = { } else { let want: i32 = 0; if (scrutt != nil) { - if (scrutt.kind == nkind.N_TTAGGED) { + // #67: gate on the stamped tinfo, not the node kind + // — matchscrutt now returns the scrutinee node itself + // for an N_DOT field (its .type_ is the tagged tinfo) + // rather than the resolved N_TTAGGED node. + if (istaggedtype(c, scrutt)) { let r: i32 = -1; if (pat.kind == nkind.N_TNAME) { r = flatvariantidx(c, scrutt, pat); diff --git a/selfhost/cmd/wcc/cgenutil.ww b/selfhost/cmd/wcc/cgenutil.ww index e867f69c..52733622 100644 --- a/selfhost/cmd/wcc/cgenutil.ww +++ b/selfhost/cmd/wcc/cgenutil.ww @@ -1891,9 +1891,15 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { return resolvetagged(c, etn); }; if (k == nkind.N_DOT) { - let ft: *node = dotfieldtnode(c, scrut); - if (ft == nil) { return nil; }; - return resolvetagged(c, ft); + // #67: read the field's stamped tinfo off the N_DOT node + // (post-#66 N_DOT carries the field type) instead of the + // dotfieldtnode AST walk. cgmatch's gate reads scrutt.type_ + // via istaggedtype, so the resolved N_TTAGGED node the walk + // produced is no longer the carrier; the istaggedtype guard + // preserves the nil-for-non-tagged contract the sibling + // N_CALL/N_INDEX branches get from resolvetagged. + if (!istaggedtype(c, scrut)) { return nil; }; + return scrut; }; return nil; }; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 836c1813..54e9566d 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -12436,9 +12436,15 @@ fn matchscrutt(c: *cgen, scrut: *node) *node = { return resolvetagged(c, etn); }; if (k == nkind.N_DOT) { - let ft: *node = dotfieldtnode(c, scrut); - if (ft == nil) { return nil; }; - return resolvetagged(c, ft); + // #67: read the field's stamped tinfo off the N_DOT node + // (post-#66 N_DOT carries the field type) instead of the + // dotfieldtnode AST walk. cgmatch's gate reads scrutt.type_ + // via istaggedtype, so the resolved N_TTAGGED node the walk + // produced is no longer the carrier; the istaggedtype guard + // preserves the nil-for-non-tagged contract the sibling + // N_CALL/N_INDEX branches get from resolvetagged. + if (!istaggedtype(c, scrut)) { return nil; }; + return scrut; }; return nil; }; @@ -15115,7 +15121,11 @@ fn cgmatch(c: *cgen, n: *node) void = { } else { let want: i32 = 0; if (scrutt != nil) { - if (scrutt.kind == nkind.N_TTAGGED) { + // #67: gate on the stamped tinfo, not the node kind + // — matchscrutt now returns the scrutinee node itself + // for an N_DOT field (its .type_ is the tagged tinfo) + // rather than the resolved N_TTAGGED node. + if (istaggedtype(c, scrutt)) { let r: i32 = -1; if (pat.kind == nkind.N_TNAME) { r = flatvariantidx(c, scrutt, pat);