-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed as not planned
Closed as not planned
Copy link
Labels
Description
When a case statement modifies a variable that is scoped outside a switch statement, the next fallthrough
+ case
statement evaluates the variable as unchanged for the line where the next case
is set, but is evaluates as changed within the next case code block
. See example code in "What did you do?
What version of Go are you using (go version
)?
$ go version go version go1.20.4 darwin/arm64
Does this issue reproduce with the latest release?
Yes, at the time of writing 1.20.4
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GOOS="darwin" GOARCH="arm64"
What did you do?
func main() {
F()
}
func F() error {
var err error
switch {
case true:
fmt.Println("first case statement should execute")
err = FuncNoError()
fallthrough
case err == nil:
fmt.Println("second case statement should execute")
// FUNCTION RETURNS AN ERROR
err = FuncHasError()
fallthrough
case err == nil:
fmt.Println("third case statement SHOULD NOT execute")
err = FuncNoError()
fallthrough
case err != nil:
fmt.Printf("type of err: %T\n", err)
return fmt.Errorf("found an error: %w", err)
}
return nil
}
// FuncNoError a function that returns no error
func FuncNoError() error {
return nil
}
// FuncHasError a function that returns an error
func FuncHasError() error {
return errors.New("FuncHasError")
}
What did you expect to see?
- The third case statement
case err == nil
should evaluate as false skipping the code block. - The fourth case statement
case err != nil
even though err is nil (according tofmt.Printf("%T", err)
) the fourth code block is still executed. So err is remains "nil" when evaluated at the same line as thecase
statement, but evaluates to not nil when in thecase code block
.
The output from the code above should be
first case statement should execute
second case statement should execute
What did you see instead?
first case statement should execute
second case statement should execute
third case statement SHOULD NOT execute
type of err: <nil>