1
0
mirror of https://github.com/golang/go synced 2024-11-23 20:40:07 -07:00

[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 <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>
This commit is contained in:
Matthew Dempsky 2022-07-18 13:45:57 -07:00
parent a4c5198a3c
commit 64cd6faa13

View 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 `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))
}
}
}