Fixes #51533.
Change-Id: Ia41a2e96d1ef94f740887e3167e6396e4f52035c
Reviewed-on: https://go-review.googlesource.com/c/go/+/392759
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
// additional context information
finalSwitchCase
+ inTypeSwitch
)
func (check *Checker) simpleStmt(s syntax.Stmt) {
// process collected function literals before scope changes
defer check.processDelayed(len(check.delayed))
- inner := ctxt &^ (fallthroughOk | finalSwitchCase)
+ // reset context for statements of inner blocks
+ inner := ctxt &^ (fallthroughOk | finalSwitchCase | inTypeSwitch)
+
switch s := s.(type) {
case *syntax.EmptyStmt:
// ignore
}
case syntax.Fallthrough:
if ctxt&fallthroughOk == 0 {
- msg := "fallthrough statement out of place"
- if ctxt&finalSwitchCase != 0 {
+ var msg string
+ switch {
+ case ctxt&finalSwitchCase != 0:
msg = "cannot fallthrough final case in switch"
+ case ctxt&inTypeSwitch != 0:
+ msg = "cannot fallthrough in type switch"
+ default:
+ msg = "fallthrough statement out of place"
}
check.error(s, msg)
}
check.simpleStmt(s.Init)
if g, _ := s.Tag.(*syntax.TypeSwitchGuard); g != nil {
- check.typeSwitchStmt(inner, s, g)
+ check.typeSwitchStmt(inner|inTypeSwitch, s, g)
} else {
check.switchStmt(inner, s)
}
var y interface{}
switch y.(type) {
case int:
- fallthrough /* ERROR "fallthrough statement out of place" */ ; ; ;
+ fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ;
default:
}
--- /dev/null
+// Copyright 2022 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 p
+
+func _(x any) {
+ switch x {
+ case 0:
+ fallthrough // ERROR fallthrough statement out of place
+ _ = x
+ default:
+ }
+
+ switch x.(type) {
+ case int:
+ fallthrough // ERROR cannot fallthrough in type switch
+ default:
+ }
+}
// additional context information
finalSwitchCase
+ inTypeSwitch
)
func (check *Checker) simpleStmt(s ast.Stmt) {
// process collected function literals before scope changes
defer check.processDelayed(len(check.delayed))
- inner := ctxt &^ (fallthroughOk | finalSwitchCase)
+ // reset context for statements of inner blocks
+ inner := ctxt &^ (fallthroughOk | finalSwitchCase | inTypeSwitch)
+
switch s := s.(type) {
case *ast.BadStmt, *ast.EmptyStmt:
// ignore
}
case token.FALLTHROUGH:
if ctxt&fallthroughOk == 0 {
- msg := "fallthrough statement out of place"
- code := _MisplacedFallthrough
- if ctxt&finalSwitchCase != 0 {
+ var msg string
+ switch {
+ case ctxt&finalSwitchCase != 0:
msg = "cannot fallthrough final case in switch"
+ case ctxt&inTypeSwitch != 0:
+ msg = "cannot fallthrough in type switch"
+ default:
+ msg = "fallthrough statement out of place"
}
- check.error(s, code, msg)
+ check.error(s, _MisplacedFallthrough, msg)
}
default:
check.invalidAST(s, "branch statement: %s", s.Tok)
}
case *ast.TypeSwitchStmt:
- inner |= breakOk
+ inner |= breakOk | inTypeSwitch
check.openScope(s, "type switch")
defer check.closeScope()
var y interface{}
switch y.(type) {
case int:
- fallthrough /* ERROR "fallthrough statement out of place" */ ; ; ;
+ fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ;
default:
}
--- /dev/null
+// Copyright 2022 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 p
+
+func _(x any) {
+ switch x {
+ case 0:
+ fallthrough // ERROR fallthrough statement out of place
+ _ = x
+ default:
+ }
+
+ switch x.(type) {
+ case int:
+ fallthrough // ERROR cannot fallthrough in type switch
+ default:
+ }
+}