mirror of
https://github.com/golang/go
synced 2024-11-25 08:37:57 -07:00
f4f1ba2b1e
The compiler is incorrectly rejecting switches on arrays of comparable types. It also doesn't catch incomparable structs when typechecking the switch, leading to unreadable errors during typechecking of the generated code. Fixes #3894. R=rsc CC=gobot, golang-dev, r, remy https://golang.org/cl/6442074
328 lines
4.6 KiB
Go
328 lines
4.6 KiB
Go
// run
|
|
|
|
// Copyright 2009 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.
|
|
|
|
// Test switch statements.
|
|
|
|
package main
|
|
|
|
import "os"
|
|
|
|
func assert(cond bool, msg string) {
|
|
if !cond {
|
|
print("assertion fail: ", msg, "\n")
|
|
panic(1)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
i5 := 5
|
|
i7 := 7
|
|
hello := "hello"
|
|
|
|
switch true {
|
|
case i5 < 5:
|
|
assert(false, "<")
|
|
case i5 == 5:
|
|
assert(true, "!")
|
|
case i5 > 5:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch {
|
|
case i5 < 5:
|
|
assert(false, "<")
|
|
case i5 == 5:
|
|
assert(true, "!")
|
|
case i5 > 5:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch x := 5; true {
|
|
case i5 < x:
|
|
assert(false, "<")
|
|
case i5 == x:
|
|
assert(true, "!")
|
|
case i5 > x:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch x := 5; true {
|
|
case i5 < x:
|
|
assert(false, "<")
|
|
case i5 == x:
|
|
assert(true, "!")
|
|
case i5 > x:
|
|
assert(false, ">")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0:
|
|
assert(false, "0")
|
|
case 1:
|
|
assert(false, "1")
|
|
case 2:
|
|
assert(false, "2")
|
|
case 3:
|
|
assert(false, "3")
|
|
case 4:
|
|
assert(false, "4")
|
|
case 5:
|
|
assert(true, "5")
|
|
case 6:
|
|
assert(false, "6")
|
|
case 7:
|
|
assert(false, "7")
|
|
case 8:
|
|
assert(false, "8")
|
|
case 9:
|
|
assert(false, "9")
|
|
default:
|
|
assert(false, "default")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0, 1, 2, 3, 4:
|
|
assert(false, "4")
|
|
case 5:
|
|
assert(true, "5")
|
|
case 6, 7, 8, 9:
|
|
assert(false, "9")
|
|
default:
|
|
assert(false, "default")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
assert(false, "4")
|
|
case 5:
|
|
assert(true, "5")
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
default:
|
|
assert(i5 == 5, "good")
|
|
}
|
|
|
|
switch i5 {
|
|
case 0:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 1:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 2:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 3:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 4:
|
|
dummy := 0
|
|
_ = dummy
|
|
assert(false, "4")
|
|
case 5:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 6:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 7:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 8:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 9:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
default:
|
|
dummy := 0
|
|
_ = dummy
|
|
assert(i5 == 5, "good")
|
|
}
|
|
|
|
fired := false
|
|
switch i5 {
|
|
case 0:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough // tests scoping of cases
|
|
case 1:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 2:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 3:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 4:
|
|
dummy := 0
|
|
_ = dummy
|
|
assert(false, "4")
|
|
case 5:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 6:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 7:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 8:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
case 9:
|
|
dummy := 0
|
|
_ = dummy
|
|
fallthrough
|
|
default:
|
|
dummy := 0
|
|
_ = dummy
|
|
fired = !fired
|
|
assert(i5 == 5, "good")
|
|
}
|
|
assert(fired, "fired")
|
|
|
|
count := 0
|
|
switch i5 {
|
|
case 0:
|
|
count = count + 1
|
|
fallthrough
|
|
case 1:
|
|
count = count + 1
|
|
fallthrough
|
|
case 2:
|
|
count = count + 1
|
|
fallthrough
|
|
case 3:
|
|
count = count + 1
|
|
fallthrough
|
|
case 4:
|
|
count = count + 1
|
|
assert(false, "4")
|
|
case 5:
|
|
count = count + 1
|
|
fallthrough
|
|
case 6:
|
|
count = count + 1
|
|
fallthrough
|
|
case 7:
|
|
count = count + 1
|
|
fallthrough
|
|
case 8:
|
|
count = count + 1
|
|
fallthrough
|
|
case 9:
|
|
count = count + 1
|
|
fallthrough
|
|
default:
|
|
assert(i5 == count, "good")
|
|
}
|
|
assert(fired, "fired")
|
|
|
|
switch hello {
|
|
case "wowie":
|
|
assert(false, "wowie")
|
|
case "hello":
|
|
assert(true, "hello")
|
|
case "jumpn":
|
|
assert(false, "jumpn")
|
|
default:
|
|
assert(false, "default")
|
|
}
|
|
|
|
fired = false
|
|
switch i := i5 + 2; i {
|
|
case i7:
|
|
fired = true
|
|
default:
|
|
assert(false, "fail")
|
|
}
|
|
assert(fired, "var")
|
|
|
|
// switch on nil-only comparison types
|
|
switch f := func() {}; f {
|
|
case nil:
|
|
assert(false, "f should not be nil")
|
|
default:
|
|
}
|
|
|
|
switch m := make(map[int]int); m {
|
|
case nil:
|
|
assert(false, "m should not be nil")
|
|
default:
|
|
}
|
|
|
|
switch a := make([]int, 1); a {
|
|
case nil:
|
|
assert(false, "m should not be nil")
|
|
default:
|
|
}
|
|
|
|
// switch on interface.
|
|
switch i := interface{}("hello"); i {
|
|
case 42:
|
|
assert(false, `i should be "hello"`)
|
|
case "hello":
|
|
assert(true, "hello")
|
|
default:
|
|
assert(false, `i should be "hello"`)
|
|
}
|
|
|
|
// switch on array.
|
|
switch ar := [3]int{1, 2, 3}; ar {
|
|
case [3]int{1,2,3}:
|
|
assert(true, "[1 2 3]")
|
|
case [3]int{4,5,6}:
|
|
assert(false, "ar should be [1 2 3]")
|
|
default:
|
|
assert(false, "ar should be [1 2 3]")
|
|
}
|
|
|
|
// switch on channel
|
|
switch c1, c2 := make(chan int), make(chan int); c1 {
|
|
case nil:
|
|
assert(false, "c1 did not match itself")
|
|
case c2:
|
|
assert(false, "c1 did not match itself")
|
|
case c1:
|
|
assert(true, "chan")
|
|
default:
|
|
assert(false, "c1 did not match itself")
|
|
}
|
|
|
|
i := 0
|
|
switch x := 5; {
|
|
case i < x:
|
|
os.Exit(0)
|
|
case i == x:
|
|
case i > x:
|
|
os.Exit(1)
|
|
}
|
|
}
|