mirror of
https://github.com/golang/go
synced 2024-11-17 13:54:46 -07:00
go/types, types2: better error msg when using fallthrough in type switch
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>
This commit is contained in:
parent
efbff6e43b
commit
5df3f491ac
@ -95,6 +95,7 @@ const (
|
||||
|
||||
// additional context information
|
||||
finalSwitchCase
|
||||
inTypeSwitch
|
||||
)
|
||||
|
||||
func (check *Checker) simpleStmt(s syntax.Stmt) {
|
||||
@ -370,7 +371,9 @@ func (check *Checker) stmt(ctxt stmtContext, 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
|
||||
@ -523,9 +526,14 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
|
||||
}
|
||||
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)
|
||||
}
|
||||
@ -572,7 +580,7 @@ func (check *Checker) stmt(ctxt stmtContext, s syntax.Stmt) {
|
||||
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)
|
||||
}
|
||||
|
@ -542,7 +542,7 @@ func switches1() {
|
||||
var y interface{}
|
||||
switch y.(type) {
|
||||
case int:
|
||||
fallthrough /* ERROR "fallthrough statement out of place" */ ; ; ;
|
||||
fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ;
|
||||
default:
|
||||
}
|
||||
|
||||
|
20
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51533.go
vendored
Normal file
20
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51533.go
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// 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:
|
||||
}
|
||||
}
|
@ -96,6 +96,7 @@ const (
|
||||
|
||||
// additional context information
|
||||
finalSwitchCase
|
||||
inTypeSwitch
|
||||
)
|
||||
|
||||
func (check *Checker) simpleStmt(s ast.Stmt) {
|
||||
@ -375,7 +376,9 @@ func (check *Checker) stmt(ctxt stmtContext, 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
|
||||
@ -541,12 +544,16 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
||||
}
|
||||
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)
|
||||
@ -627,7 +634,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
||||
}
|
||||
|
||||
case *ast.TypeSwitchStmt:
|
||||
inner |= breakOk
|
||||
inner |= breakOk | inTypeSwitch
|
||||
check.openScope(s, "type switch")
|
||||
defer check.closeScope()
|
||||
|
||||
|
2
src/go/types/testdata/check/stmt0.src
vendored
2
src/go/types/testdata/check/stmt0.src
vendored
@ -542,7 +542,7 @@ func switches1() {
|
||||
var y interface{}
|
||||
switch y.(type) {
|
||||
case int:
|
||||
fallthrough /* ERROR "fallthrough statement out of place" */ ; ; ;
|
||||
fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ;
|
||||
default:
|
||||
}
|
||||
|
||||
|
20
src/go/types/testdata/fixedbugs/issue51533.go
vendored
Normal file
20
src/go/types/testdata/fixedbugs/issue51533.go
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// 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:
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user