go/types: better error for type assertion/switch on type parameter value

This is a port of CL 363439 from types2 to go/types.

Change-Id: Ic71871874345e1d0a4a42703e3673aadd11f2bfc
Reviewed-on: https://go-review.googlesource.com/c/go/+/364378
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Robert Findley 2021-11-16 11:24:22 -05:00
parent 1d004fa201
commit 4083a6f377
3 changed files with 14 additions and 4 deletions

View file

@ -1432,6 +1432,11 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
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.invalidOp(x, _InvalidAssert, "cannot use type assertion on type parameter value %s", x)
goto Error
}
xtyp, _ := under(x.typ).(*Interface)
if xtyp == nil {
check.invalidOp(x, _InvalidAssert, "%s is not an interface", x)

View file

@ -685,6 +685,11 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
if x.mode == invalid {
return
}
// TODO(gri) we may want to permit type switches on type parameter values at some point
if isTypeParam(x.typ) {
check.errorf(&x, _InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
return
}
xtyp, _ := under(x.typ).(*Interface)
if xtyp == nil {
check.errorf(&x, _InvalidTypeSwitch, "%s is not an interface", &x)

View file

@ -481,8 +481,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
@ -493,8 +493,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