]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.18] go/types, types2: pointer base types cannot be type constraints
authorRobert Griesemer <gri@golang.org>
Wed, 9 Mar 2022 22:27:25 +0000 (14:27 -0800)
committerDmitri Shuralyov <dmitshur@golang.org>
Fri, 11 Mar 2022 00:01:01 +0000 (00:01 +0000)
Pointer types may appear in expressions *P and we don't know if
we have an indirection (P is a pointer value) or a pointer type
(P is a type) until we type-check P. Don't forget to check that
a type P must be an ordinary (not a constraint) type in this
special case.

Fixes #51578.

Change-Id: If782cc6dd2a602a498574c78c99e40c3b72274a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/391275
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 3a5e3d8173df547d8360a609097fc80f01182db1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/391357
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/types2/expr.go
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go2 [new file with mode: 0644]
src/cmd/compile/internal/types2/typexpr.go
src/go/types/expr.go
src/go/types/testdata/fixedbugs/issue51578.go2 [new file with mode: 0644]
src/go/types/typexpr.go

index 861a83472daeb87213cf76d23d2f62096f2b2131..05cf1d0b33dce1f34ce06f51ea6b185cdd805ef6 100644 (file)
@@ -1642,6 +1642,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
                                case invalid:
                                        goto Error
                                case typexpr:
+                                       check.validVarType(e.X, x.typ)
                                        x.typ = &Pointer{base: x.typ}
                                default:
                                        var base Type
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go2
new file mode 100644 (file)
index 0000000..5c204ba
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2022 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
+
+var _ = (*interface /* ERROR interface contains type constraints */ {int})(nil)
+
+// abbreviated test case from issue
+
+type TypeSet interface{ int | string }
+
+func _() {
+       f((*TypeSet /* ERROR interface contains type constraints */)(nil))
+}
+
+func f(any) {}
\ No newline at end of file
index a9ce55bd1e5782dba6de0014d73b31304f9970b0..7e30562e9721181791d206b0fed398f01670da43 100644 (file)
@@ -147,10 +147,16 @@ func (check *Checker) typ(e syntax.Expr) Type {
 // constraint interface.
 func (check *Checker) varType(e syntax.Expr) Type {
        typ := check.definedType(e, nil)
+       check.validVarType(e, typ)
+       return typ
+}
 
+// validVarType reports an error if typ is a constraint interface.
+// The expression e is used for error reporting, if any.
+func (check *Checker) validVarType(e syntax.Expr, typ Type) {
        // If we have a type parameter there's nothing to do.
        if isTypeParam(typ) {
-               return typ
+               return
        }
 
        // We don't want to call under() or complete interfaces while we are in
@@ -169,8 +175,6 @@ func (check *Checker) varType(e syntax.Expr) Type {
                        }
                }
        })
-
-       return typ
 }
 
 // definedType is like typ but also accepts a type name def.
index 68b0789d6504cfc0a0368a75a952e30762461c46..e24bd60dc391a300885920770552ddcfb784db0a 100644 (file)
@@ -1588,6 +1588,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
                case invalid:
                        goto Error
                case typexpr:
+                       check.validVarType(e.X, x.typ)
                        x.typ = &Pointer{base: x.typ}
                default:
                        var base Type
diff --git a/src/go/types/testdata/fixedbugs/issue51578.go2 b/src/go/types/testdata/fixedbugs/issue51578.go2
new file mode 100644 (file)
index 0000000..5c204ba
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2022 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
+
+var _ = (*interface /* ERROR interface contains type constraints */ {int})(nil)
+
+// abbreviated test case from issue
+
+type TypeSet interface{ int | string }
+
+func _() {
+       f((*TypeSet /* ERROR interface contains type constraints */)(nil))
+}
+
+func f(any) {}
\ No newline at end of file
index 14735c3709178bdf47fb393de76ad40d425d2071..5bb2d8f8112086fe08c933593ff57a232da51581 100644 (file)
@@ -144,10 +144,16 @@ func (check *Checker) typ(e ast.Expr) Type {
 // constraint interface.
 func (check *Checker) varType(e ast.Expr) Type {
        typ := check.definedType(e, nil)
+       check.validVarType(e, typ)
+       return typ
+}
 
+// validVarType reports an error if typ is a constraint interface.
+// The expression e is used for error reporting, if any.
+func (check *Checker) validVarType(e ast.Expr, typ Type) {
        // If we have a type parameter there's nothing to do.
        if isTypeParam(typ) {
-               return typ
+               return
        }
 
        // We don't want to call under() or complete interfaces while we are in
@@ -165,8 +171,6 @@ func (check *Checker) varType(e ast.Expr) Type {
                        }
                }
        })
-
-       return typ
 }
 
 // definedType is like typ but also accepts a type name def.