]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.unified] cmd/compile/internal/noder: simplify mixed tag/case RTTI wiring
authorMatthew Dempsky <mdempsky@google.com>
Mon, 18 Jul 2022 20:45:57 +0000 (13:45 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 19 Jul 2022 23:31:17 +0000 (23:31 +0000)
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 <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/noder/reader.go

index 4c90f9dc54cdfa7529702c241182bffae6f7aa7e..d7ec9f2ebb20f97f851bea84a793c480ce21818a 100644 (file)
@@ -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 len(rtypes) < i {
-                                               rtypes = append(rtypes, nil)
+                       // 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]))
                                        }
-                                       rtypes = append(rtypes, reflectdata.TypePtrAt(cas.Pos(), typ))
                                }
                        }
                }