]> Cypherpunks.ru repositories - gostls13.git/blobdiff - test/switch.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / switch.go
index 09bf4341a00d9dce7822d744d8b71df6d9ba7a36..1806fa7f9be422e646bb6b8b9bc292422dcbbabd 100644 (file)
@@ -284,12 +284,134 @@ func main() {
        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 implicit bool converted to interface
+       // was broken: see issue 3980
+       switch i := interface{}(true); {
+       case i:
+               assert(true, "true")
+       case false:
+               assert(false, "i should be true")
+       default:
+               assert(false, "i should be true")
+       }
+
+       // switch on interface with constant cases differing by type.
+       // was rejected by compiler: see issue 4781
+       type T int
+       type B bool
+       type F float64
+       type S string
+       switch i := interface{}(float64(1.0)); i {
+       case nil:
+               assert(false, "i should be float64(1.0)")
+       case (*int)(nil):
+               assert(false, "i should be float64(1.0)")
+       case 1:
+               assert(false, "i should be float64(1.0)")
+       case T(1):
+               assert(false, "i should be float64(1.0)")
+       case F(1.0):
+               assert(false, "i should be float64(1.0)")
+       case 1.0:
+               assert(true, "true")
+       case "hello":
+               assert(false, "i should be float64(1.0)")
+       case S("hello"):
+               assert(false, "i should be float64(1.0)")
+       case true, B(false):
+               assert(false, "i should be float64(1.0)")
+       case false, B(true):
+               assert(false, "i should be float64(1.0)")
+       }
+
+       // 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")
+       }
+
+       // empty switch
+       switch {
+       }
+
+       // empty switch with default case.
+       fired = false
+       switch {
+       default:
+               fired = true
+       }
+       assert(fired, "fail")
+
+       // Default and fallthrough.
+       count = 0
+       switch {
+       default:
+               count++
+               fallthrough
+       case false:
+               count++
+       }
+       assert(count == 2, "fail")
+
+       // fallthrough to default, which is not at end.
+       count = 0
+       switch i5 {
+       case 5:
+               count++
+               fallthrough
+       default:
+               count++
+       case 6:
+               count++
+       }
+       assert(count == 2, "fail")
+
        i := 0
        switch x := 5; {
-               case i < x:
-                       os.Exit(0)
-               case i == x:
-               case i > x:
-                       os.Exit(1)
+       case i < x:
+               os.Exit(0)
+       case i == x:
+       case i > x:
+               os.Exit(1)
+       }
+
+       // Unified IR converts the tag and all case values to empty
+       // interface, when any of the case values aren't assignable to the
+       // tag value's type. Make sure that `case nil:` compares against the
+       // tag type's nil value (i.e., `(*int)(nil)`), not nil interface
+       // (i.e., `any(nil)`).
+       switch (*int)(nil) {
+       case nil:
+               // ok
+       case any(nil):
+               assert(false, "case any(nil) matched")
+       default:
+               assert(false, "default matched")
        }
 }