mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +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:
parent
9150c16bce
commit
f9dcda3fd8
@ -1459,9 +1459,14 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
|
|||||||
if x.mode == invalid {
|
if x.mode == invalid {
|
||||||
goto Error
|
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)
|
xtyp, _ := under(x.typ).(*Interface)
|
||||||
if xtyp == nil {
|
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
|
goto Error
|
||||||
}
|
}
|
||||||
// x.(type) expressions are encoded via TypeSwitchGuards
|
// x.(type) expressions are encoded via TypeSwitchGuards
|
||||||
|
@ -733,13 +733,14 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
|
|||||||
if x.mode == invalid {
|
if x.mode == invalid {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Caution: We're not using asInterface here because we don't want
|
// TODO(gri) we may want to permit type switches on type parameter values at some point
|
||||||
// to switch on a suitably constrained type parameter (for
|
if isTypeParam(x.typ) {
|
||||||
// now).
|
check.errorf(&x, "cannot use type switch on type parameter value %s", &x)
|
||||||
// TODO(gri) Need to revisit this.
|
return
|
||||||
|
}
|
||||||
xtyp, _ := under(x.typ).(*Interface)
|
xtyp, _ := under(x.typ).(*Interface)
|
||||||
if xtyp == nil {
|
if xtyp == nil {
|
||||||
check.errorf(&x, "%s is not an interface type", &x)
|
check.errorf(&x, "%s is not an interface", &x)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,8 +482,8 @@ func (_ R2[X, Y]) m2(X) Y
|
|||||||
// type assertions and type switches over generic types lead to errors for now
|
// type assertions and type switches over generic types lead to errors for now
|
||||||
|
|
||||||
func _[T any](x T) {
|
func _[T any](x T) {
|
||||||
_ = x /* ERROR not an interface */ .(int)
|
_ = x /* ERROR cannot use type assertion */ .(int)
|
||||||
switch x /* ERROR not an interface */ .(type) {
|
switch x /* ERROR cannot use type switch */ .(type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// work-around
|
// work-around
|
||||||
@ -494,8 +494,8 @@ func _[T any](x T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func _[T interface{~int}](x T) {
|
func _[T interface{~int}](x T) {
|
||||||
_ = x /* ERROR not an interface */ .(int)
|
_ = x /* ERROR cannot use type assertion */ .(int)
|
||||||
switch x /* ERROR not an interface */ .(type) {
|
switch x /* ERROR cannot use type switch */ .(type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// work-around
|
// work-around
|
||||||
|
@ -57,7 +57,7 @@ func main() {
|
|||||||
|
|
||||||
// cannot type-assert non-interfaces
|
// cannot type-assert non-interfaces
|
||||||
f := 2.0
|
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"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ func main() {
|
|||||||
|
|
||||||
func noninterface() {
|
func noninterface() {
|
||||||
var i int
|
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 string:
|
||||||
case int:
|
case int:
|
||||||
}
|
}
|
||||||
@ -51,6 +51,6 @@ func noninterface() {
|
|||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
var s S
|
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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user