mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
5abda2618b
commit
b0f01e17f8
3 changed files with 57 additions and 0 deletions
|
|
@ -1207,6 +1207,16 @@ const (
|
||||||
// }
|
// }
|
||||||
_InvalidTypeSwitch
|
_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 */
|
/* control flow > select */
|
||||||
|
|
||||||
// _InvalidSelectCase occurs when a select case is not a channel send or
|
// _InvalidSelectCase occurs when a select case is not a channel send or
|
||||||
|
|
|
||||||
43
src/go/types/fixedbugs/issue43110.src
Normal file
43
src/go/types/fixedbugs/issue43110.src
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
// 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):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -528,6 +528,10 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
||||||
// By checking assignment of x to an invisible temporary
|
// By checking assignment of x to an invisible temporary
|
||||||
// (as a compiler would), we get all the relevant checks.
|
// (as a compiler would), we get all the relevant checks.
|
||||||
check.assignment(&x, nil, "switch expression")
|
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 {
|
} else {
|
||||||
// spec: "A missing switch expression is
|
// spec: "A missing switch expression is
|
||||||
// equivalent to the boolean value true."
|
// equivalent to the boolean value true."
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue