From a0c7e2620a11daa26345ed4ae5c4f7edca2ba95a Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 9 Mar 2022 14:27:25 -0800 Subject: [PATCH] [release-branch.go1.18] go/types, types2: pointer base types cannot be type constraints 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 Run-TryBot: Robert Griesemer Reviewed-by: Robert Findley TryBot-Result: Gopher Robot (cherry picked from commit 3a5e3d8173df547d8360a609097fc80f01182db1) Reviewed-on: https://go-review.googlesource.com/c/go/+/391357 Trust: Dmitri Shuralyov Run-TryBot: Dmitri Shuralyov Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/types2/expr.go | 1 + .../types2/testdata/fixedbugs/issue51578.go2 | 17 +++++++++++++++++ src/cmd/compile/internal/types2/typexpr.go | 10 +++++++--- src/go/types/expr.go | 1 + src/go/types/testdata/fixedbugs/issue51578.go2 | 17 +++++++++++++++++ src/go/types/typexpr.go | 10 +++++++--- 6 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go2 create mode 100644 src/go/types/testdata/fixedbugs/issue51578.go2 diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go index 861a83472daeb..05cf1d0b33dce 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -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 index 0000000000000..5c204bae2097f --- /dev/null +++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go2 @@ -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 diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go index a9ce55bd1e578..7e30562e97211 100644 --- a/src/cmd/compile/internal/types2/typexpr.go +++ b/src/cmd/compile/internal/types2/typexpr.go @@ -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. diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 68b0789d6504c..e24bd60dc391a 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -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 index 0000000000000..5c204bae2097f --- /dev/null +++ b/src/go/types/testdata/fixedbugs/issue51578.go2 @@ -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 diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 14735c3709178..5bb2d8f811208 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -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.