1
0
mirror of https://github.com/golang/go synced 2024-07-01 07:56:09 +00:00

cmd/compile/internal/types2: better error for type assertion/switch on type parameter value

Change-Id: I98751d0b2d8aefcf537b6d5200d0b52ffacf1105
Reviewed-on: https://go-review.googlesource.com/c/go/+/363439
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-11-11 16:32:16 -08:00
parent 9150c16bce
commit f9dcda3fd8
5 changed files with 19 additions and 13 deletions

View File

@ -1459,9 +1459,14 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
if x.mode == invalid {
goto Error
}
// TODO(gri) we may want to permit type assertions on type parameter values at some point
if isTypeParam(x.typ) {
check.errorf(x, invalidOp+"cannot use type assertion on type parameter value %s", x)
goto Error
}
xtyp, _ := under(x.typ).(*Interface)
if xtyp == nil {
check.errorf(x, "%s is not an interface type", x)
check.errorf(x, invalidOp+"%s is not an interface", x)
goto Error
}
// x.(type) expressions are encoded via TypeSwitchGuards

View File

@ -733,13 +733,14 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
if x.mode == invalid {
return
}
// Caution: We're not using asInterface here because we don't want
// to switch on a suitably constrained type parameter (for
// now).
// TODO(gri) Need to revisit this.
// TODO(gri) we may want to permit type switches on type parameter values at some point
if isTypeParam(x.typ) {
check.errorf(&x, "cannot use type switch on type parameter value %s", &x)
return
}
xtyp, _ := under(x.typ).(*Interface)
if xtyp == nil {
check.errorf(&x, "%s is not an interface type", &x)
check.errorf(&x, "%s is not an interface", &x)
return
}

View File

@ -482,8 +482,8 @@ func (_ R2[X, Y]) m2(X) Y
// type assertions and type switches over generic types lead to errors for now
func _[T any](x T) {
_ = x /* ERROR not an interface */ .(int)
switch x /* ERROR not an interface */ .(type) {
_ = x /* ERROR cannot use type assertion */ .(int)
switch x /* ERROR cannot use type switch */ .(type) {
}
// work-around
@ -494,8 +494,8 @@ func _[T any](x T) {
}
func _[T interface{~int}](x T) {
_ = x /* ERROR not an interface */ .(int)
switch x /* ERROR not an interface */ .(type) {
_ = x /* ERROR cannot use type assertion */ .(int)
switch x /* ERROR cannot use type switch */ .(type) {
}
// work-around

View File

@ -57,7 +57,7 @@ func main() {
// cannot type-assert non-interfaces
f := 2.0
_ = f.(int) // ERROR "non-interface type|only valid for interface types|not an interface type"
_ = f.(int) // ERROR "non-interface type|only valid for interface types|not an interface"
}

View File

@ -42,7 +42,7 @@ func main() {
func noninterface() {
var i int
switch i.(type) { // ERROR "cannot type switch on non-interface value|not an interface type"
switch i.(type) { // ERROR "cannot type switch on non-interface value|not an interface"
case string:
case int:
}
@ -51,6 +51,6 @@ func noninterface() {
name string
}
var s S
switch s.(type) { // ERROR "cannot type switch on non-interface value|not an interface type"
switch s.(type) { // ERROR "cannot type switch on non-interface value|not an interface"
}
}