]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/types2: better error for type assertion/switch on type parameter...
authorRobert Griesemer <gri@golang.org>
Fri, 12 Nov 2021 00:32:16 +0000 (16:32 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 12 Nov 2021 22:20:51 +0000 (22:20 +0000)
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>
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/stmt.go
src/cmd/compile/internal/types2/testdata/check/typeparams.go2
test/interface/explicit.go
test/typeswitch3.go

index 17096ee4184306f6c57ddec81b8384a1bf2734d0..25e2060100d0de65ad9ef033459a7d420afbe093 100644 (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
index f9c07e38cdc4046521586171550a0ef737f2e5e0..6869c87929505c8e0f3029c813140b3aec5cd580 100644 (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
        }
 
index b1d02efdb554898ed71b874cfa8d4caf72fc67b1..03c3f9a0b589ffffe0cc76a3ed2b60ad6af1b59e 100644 (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
index 1b7af6712b661df40e890e2292fa5a0519248212..f769f5878ce1de12c4ae5cb6d847b45ae705b857 100644 (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"
 
 }
 
index a57889bc1dee4f66dd7276e746812f8dd6817938..2e144d81c00cef738b5ff3acadd19d1aedfa6ba3 100644 (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"
        }
 }