From 64cd6faa13e9155e7942f3f51127c1d61a38fcf7 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Mon, 18 Jul 2022 13:45:57 -0700 Subject: [PATCH] [dev.unified] cmd/compile/internal/noder: simplify mixed tag/case RTTI wiring The previous CL largely removed the need for worrying about mixed tag/case comparisons in switch statements by ensuring they're always converted to a common type, except for one annoying case: switch statements with an implicit `true` tag, and case values of interface type (which must be empty interface, because `bool`'s method set is empty). It would be simpler to have writer.go desugar the implicit `true` itself, because we already handle explicit `true` correctly. But the existing code already works fine, and I don't want to add further complexity to writer.go until dictionaries and stenciling is done. Change-Id: Ia8d44c425b1be7fc578cd570d15a7560fe9d2674 Reviewed-on: https://go-review.googlesource.com/c/go/+/418102 Run-TryBot: Matthew Dempsky Reviewed-by: Cuong Manh Le Reviewed-by: Keith Randall TryBot-Result: Gopher Robot Reviewed-by: Keith Randall --- src/cmd/compile/internal/noder/reader.go | 30 +++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 4c90f9dc54..d7ec9f2ebb 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -1569,23 +1569,21 @@ func (r *reader) switchStmt(label *types.Sym) ir.Node { } else { cases = r.exprList() - tagType := types.Types[types.TBOOL] - if tag != nil { - tagType = tag.Type() - } - for i, cas := range cases { - if cas.Op() == ir.ONIL { - continue // never needs rtype - } - if tagType.IsInterface() != cas.Type().IsInterface() { - typ := tagType - if typ.IsInterface() { - typ = cas.Type() + // For `switch { case any(true): }` (e.g., issue 3980 in + // test/switch.go), the backend still creates a mixed bool/any + // comparison, and we need to explicitly supply the RTTI for the + // comparison. + // + // TODO(mdempsky): Change writer.go to desugar "switch {" into + // "switch true {", which we already handle correctly. + if tag == nil { + for i, cas := range cases { + if cas.Type().IsEmptyInterface() { + for len(rtypes) < i { + rtypes = append(rtypes, nil) + } + rtypes = append(rtypes, reflectdata.TypePtrAt(cas.Pos(), types.Types[types.TBOOL])) } - for len(rtypes) < i { - rtypes = append(rtypes, nil) - } - rtypes = append(rtypes, reflectdata.TypePtrAt(cas.Pos(), typ)) } } }