Skip to content

Commit b0f01e1

Browse files
committed
go/types: report error for invalid (but empty) expr switch
This is a port of CL 278132 from the dev.typeparams branch. A notable addition is a new error code, since no existing codes made sense and we have an analogous code for type switches. Fixes #43110 Change-Id: I22b3f9d8777063223f82785504e8b7d299bc5216 Reviewed-on: https://go-review.googlesource.com/c/go/+/278813 Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Robert Findley <[email protected]>
1 parent 5abda26 commit b0f01e1

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

src/go/types/errorcodes.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,16 @@ const (
12071207
// }
12081208
_InvalidTypeSwitch
12091209

1210+
// _InvalidExprSwitch occurs when a switch expression is not comparable.
1211+
//
1212+
// Example:
1213+
// func _() {
1214+
// var a struct{ _ func() }
1215+
// switch a /* ERROR cannot switch on a */ {
1216+
// }
1217+
// }
1218+
_InvalidExprSwitch
1219+
12101220
/* control flow > select */
12111221

12121222
// _InvalidSelectCase occurs when a select case is not a channel send or

src/go/types/fixedbugs/issue43110.src

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2020 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
type P *struct{}
8+
9+
func _() {
10+
// want an error even if the switch is empty
11+
var a struct{ _ func() }
12+
switch a /* ERROR cannot switch on a */ {
13+
}
14+
15+
switch a /* ERROR cannot switch on a */ {
16+
case a: // no follow-on error here
17+
}
18+
19+
// this is ok because f can be compared to nil
20+
var f func()
21+
switch f {
22+
}
23+
24+
switch f {
25+
case nil:
26+
}
27+
28+
switch (func())(nil) {
29+
case nil:
30+
}
31+
32+
switch (func())(nil) {
33+
case f /* ERROR cannot compare */ :
34+
}
35+
36+
switch nil /* ERROR use of untyped nil in switch expression */ {
37+
}
38+
39+
// this is ok
40+
switch P(nil) {
41+
case P(nil):
42+
}
43+
}

src/go/types/stmt.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,10 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
528528
// By checking assignment of x to an invisible temporary
529529
// (as a compiler would), we get all the relevant checks.
530530
check.assignment(&x, nil, "switch expression")
531+
if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
532+
check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
533+
x.mode = invalid
534+
}
531535
} else {
532536
// spec: "A missing switch expression is
533537
// equivalent to the boolean value true."

0 commit comments

Comments
 (0)