From: Gergely Brautigam Date: Fri, 18 Jan 2019 20:43:56 +0000 (+0100) Subject: cmd/compile: suppress typecheck errors in a type switch case with broken type X-Git-Tag: go1.13beta1~1345 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8ee9bca2729ead81da6bf5a18b87767ff396d1b7;p=gostls13.git cmd/compile: suppress typecheck errors in a type switch case with broken type If a type switch case expression has failed typechecking, the case body is likely to also fail with confusing or spurious errors. Suppress typechecking the case body when this happens. Fixes #28926 Change-Id: Idfdb9d5627994f2fd90154af1659e9a92bf692c4 Reviewed-on: https://go-review.googlesource.com/c/158617 Run-TryBot: Daniel Martí TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/gc/swt.go b/src/cmd/compile/internal/gc/swt.go index 70fc66bf57..6a41885954 100644 --- a/src/cmd/compile/internal/gc/swt.go +++ b/src/cmd/compile/internal/gc/swt.go @@ -184,18 +184,11 @@ func typecheckswitch(n *Node) { } } - if n.Type == nil || n.Type.IsUntyped() { - // if the value we're switching on has no type or is untyped, - // we've already printed an error and don't need to continue - // typechecking the body - return - } - if top == Etype { ll := ncase.List if ncase.Rlist.Len() != 0 { nvar := ncase.Rlist.First() - if ll.Len() == 1 && ll.First().Type != nil && !ll.First().Type.IsKind(TNIL) { + if ll.Len() == 1 && (ll.First().Type == nil || !ll.First().Type.IsKind(TNIL)) { // single entry type switch nvar.Type = ll.First().Type } else { @@ -203,6 +196,13 @@ func typecheckswitch(n *Node) { nvar.Type = n.Type } + if nvar.Type == nil || nvar.Type.IsUntyped() { + // if the value we're switching on has no type or is untyped, + // we've already printed an error and don't need to continue + // typechecking the body + continue + } + nvar = typecheck(nvar, ctxExpr|ctxAssign) ncase.Rlist.SetFirst(nvar) } diff --git a/test/fixedbugs/issue28926.go b/test/fixedbugs/issue28926.go new file mode 100644 index 0000000000..5a46bd307c --- /dev/null +++ b/test/fixedbugs/issue28926.go @@ -0,0 +1,24 @@ +// errorcheck + +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +type Stringer interface { + String() string +} + +func main() { + var e interface{} + switch e := e.(type) { + case G: // ERROR "undefined: G" + e.M() // ok: this error should be ignored because the case failed its typecheck + case E: // ERROR "undefined: E" + e.D() // ok: this error should be ignored because the case failed its typecheck + case Stringer: + // ok: this error should not be ignored to prove that passing legs aren't left out + _ = e.(T) // ERROR "undefined: T" + } +}