mirror of
https://github.com/golang/go
synced 2024-11-17 07:14:45 -07:00
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 <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
e189b5e06d
commit
3a5e3d8173
@ -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
|
||||
|
17
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go2
vendored
Normal file
17
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go2
vendored
Normal file
@ -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) {}
|
@ -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.
|
||||
|
@ -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
|
||||
|
17
src/go/types/testdata/fixedbugs/issue51578.go2
vendored
Normal file
17
src/go/types/testdata/fixedbugs/issue51578.go2
vendored
Normal file
@ -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) {}
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user