// }
_InvalidTypeSwitch
+ // _InvalidExprSwitch occurs when a switch expression is not comparable.
+ //
+ // Example:
+ // func _() {
+ // var a struct{ _ func() }
+ // switch a /* ERROR cannot switch on a */ {
+ // }
+ // }
+ _InvalidExprSwitch
+
/* control flow > select */
// _InvalidSelectCase occurs when a select case is not a channel send or
--- /dev/null
+// Copyright 2020 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
+
+type P *struct{}
+
+func _() {
+ // want an error even if the switch is empty
+ var a struct{ _ func() }
+ switch a /* ERROR cannot switch on a */ {
+ }
+
+ switch a /* ERROR cannot switch on a */ {
+ case a: // no follow-on error here
+ }
+
+ // this is ok because f can be compared to nil
+ var f func()
+ switch f {
+ }
+
+ switch f {
+ case nil:
+ }
+
+ switch (func())(nil) {
+ case nil:
+ }
+
+ switch (func())(nil) {
+ case f /* ERROR cannot compare */ :
+ }
+
+ switch nil /* ERROR use of untyped nil in switch expression */ {
+ }
+
+ // this is ok
+ switch P(nil) {
+ case P(nil):
+ }
+}
// By checking assignment of x to an invisible temporary
// (as a compiler would), we get all the relevant checks.
check.assignment(&x, nil, "switch expression")
+ if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
+ check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
+ x.mode = invalid
+ }
} else {
// spec: "A missing switch expression is
// equivalent to the boolean value true."