mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile/internal/types2: embedding stand-alone type parameters is not permitted
For #47127. Change-Id: Ie979ff56ae7c2dd0e5ce0ff39588f98ae68b5ee9 Reviewed-on: https://go-review.googlesource.com/c/go/+/334151 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
3a047326e8
commit
4ff0e04c2e
9 changed files with 87 additions and 40 deletions
|
|
@ -232,7 +232,7 @@ func _[T interface{ ~func() }](f T) {
|
||||||
|
|
||||||
type sliceOf[E any] interface{ ~[]E }
|
type sliceOf[E any] interface{ ~[]E }
|
||||||
|
|
||||||
func append[T interface{}, S sliceOf[T], T2 interface{ T }](s S, t ...T2) S
|
func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S
|
||||||
|
|
||||||
var f func()
|
var f func()
|
||||||
var cancelSlice []context.CancelFunc
|
var cancelSlice []context.CancelFunc
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,20 @@ import "strconv"
|
||||||
|
|
||||||
type any interface{}
|
type any interface{}
|
||||||
|
|
||||||
func f0[A any, B interface{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
|
// Embedding stand-alone type parameters is not permitted for now. Disabled.
|
||||||
func _() {
|
// func f0[A any, B interface{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
|
||||||
f := f0[string]
|
// func _() {
|
||||||
f("a", "b", "c", "d")
|
// f := f0[string]
|
||||||
f0("a", "b", "c", "d")
|
// f("a", "b", "c", "d")
|
||||||
}
|
// f0("a", "b", "c", "d")
|
||||||
|
// }
|
||||||
func f1[A any, B interface{~A}](A, B)
|
//
|
||||||
func _() {
|
// func f1[A any, B interface{~A}](A, B)
|
||||||
f := f1[int]
|
// func _() {
|
||||||
f(int(0), int(0))
|
// f := f1[int]
|
||||||
f1(int(0), int(0))
|
// f(int(0), int(0))
|
||||||
}
|
// f1(int(0), int(0))
|
||||||
|
// }
|
||||||
|
|
||||||
func f2[A any, B interface{~[]A}](A, B)
|
func f2[A any, B interface{~[]A}](A, B)
|
||||||
func _() {
|
func _() {
|
||||||
|
|
@ -29,13 +30,14 @@ func _() {
|
||||||
f2(byte(0), []byte{})
|
f2(byte(0), []byte{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
|
// Embedding stand-alone type parameters is not permitted for now. Disabled.
|
||||||
func _() {
|
// func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
|
||||||
f := f3[int]
|
// func _() {
|
||||||
var x int
|
// f := f3[int]
|
||||||
f(x, &x, &x)
|
// var x int
|
||||||
f3(x, &x, &x)
|
// f(x, &x, &x)
|
||||||
}
|
// f3(x, &x, &x)
|
||||||
|
// }
|
||||||
|
|
||||||
func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C)
|
func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C)
|
||||||
func _() {
|
func _() {
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,10 @@ type x7[A any] struct{ foo7 }
|
||||||
func main7() { var _ foo7 = x7[int]{} }
|
func main7() { var _ foo7 = x7[int]{} }
|
||||||
|
|
||||||
// crash 8
|
// crash 8
|
||||||
type foo8[A any] interface { ~A }
|
// Embedding stand-alone type parameters is not permitted for now. Disabled.
|
||||||
func bar8[A foo8[A]](a A) {}
|
// type foo8[A any] interface { ~A }
|
||||||
func main8() {}
|
// func bar8[A foo8[A]](a A) {}
|
||||||
|
// func main8() {}
|
||||||
|
|
||||||
// crash 9
|
// crash 9
|
||||||
type foo9[A any] interface { foo9 /* ERROR illegal cycle */ [A] }
|
type foo9[A any] interface { foo9 /* ERROR illegal cycle */ [A] }
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
|
// Embedding stand-alone type parameters is not permitted for now. Disabled.
|
||||||
|
|
||||||
|
/*
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// Minimal test case.
|
// Minimal test case.
|
||||||
|
|
@ -25,3 +28,4 @@ func Print[T constr[T]](s []T) {
|
||||||
func f() {
|
func f() {
|
||||||
Print([]string{"Hello, ", "playground\n"})
|
Print([]string{"Hello, ", "playground\n"})
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,8 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// TODO(gri) Eventually, once we disallow type lists, we need to
|
package p
|
||||||
// adjust this code: for 1.17 we don't accept type parameters,
|
|
||||||
// and for 1.18 this code is valid.
|
|
||||||
// Leaving for now so we can see that existing errors
|
|
||||||
// are being reported.
|
|
||||||
|
|
||||||
package go1_17 // don't permit non-interface elements in interfaces
|
|
||||||
|
|
||||||
type T[P any] interface{
|
type T[P any] interface{
|
||||||
P // ERROR P is a type parameter, not an interface
|
P // ERROR cannot embed a type parameter
|
||||||
}
|
}
|
||||||
|
|
|
||||||
37
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go2
vendored
Normal file
37
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go2
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
// Embedding of stand-alone type parameters is not permitted.
|
||||||
|
|
||||||
|
package p
|
||||||
|
|
||||||
|
type (
|
||||||
|
_[P any] interface{ *P | []P | chan P | map[string]P }
|
||||||
|
_[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
)
|
||||||
|
|
||||||
|
func _[P any]() {
|
||||||
|
type (
|
||||||
|
_[P any] interface{ *P | []P | chan P | map[string]P }
|
||||||
|
_[P any] interface{ P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_[P any] interface{ ~P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_[P any] interface{ int | P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_[P any] interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
|
||||||
|
_ interface{ *P | []P | chan P | map[string]P }
|
||||||
|
_ interface{ P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_ interface{ ~P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_ interface{ int | P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
_ interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _[P any, Q interface{ *P | []P | chan P | map[string]P }]()
|
||||||
|
func _[P any, Q interface{ P /* ERROR "cannot embed a type parameter" */ }]()
|
||||||
|
func _[P any, Q interface{ ~P /* ERROR "cannot embed a type parameter" */ }]()
|
||||||
|
func _[P any, Q interface{ int | P /* ERROR "cannot embed a type parameter" */ }]()
|
||||||
|
func _[P any, Q interface{ int | ~P /* ERROR "cannot embed a type parameter" */ }]()
|
||||||
|
|
@ -216,11 +216,9 @@ func computeTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *TypeSet {
|
||||||
// interface before go1.18.
|
// interface before go1.18.
|
||||||
types = typ
|
types = typ
|
||||||
case *TypeParam:
|
case *TypeParam:
|
||||||
if check != nil && !check.allowVersion(check.pkg, 1, 18) {
|
// Embedding stand-alone type parameters is not permitted for now.
|
||||||
check.errorf(pos, "%s is a type parameter, not an interface", typ)
|
// This case is handled during union parsing.
|
||||||
continue
|
unreachable()
|
||||||
}
|
|
||||||
types = typ
|
|
||||||
default:
|
default:
|
||||||
if typ == Typ[Invalid] {
|
if typ == Typ[Invalid] {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -128,13 +128,18 @@ func parseUnion(check *Checker, tlist []syntax.Expr) Type {
|
||||||
return newUnion(types, tilde)
|
return newUnion(types, tilde)
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseTilde(check *Checker, x syntax.Expr) (Type, bool) {
|
func parseTilde(check *Checker, x syntax.Expr) (typ Type, tilde bool) {
|
||||||
tilde := false
|
|
||||||
if op, _ := x.(*syntax.Operation); op != nil && op.Op == syntax.Tilde {
|
if op, _ := x.(*syntax.Operation); op != nil && op.Op == syntax.Tilde {
|
||||||
x = op.X
|
x = op.X
|
||||||
tilde = true
|
tilde = true
|
||||||
}
|
}
|
||||||
return check.anyType(x), tilde
|
typ = check.anyType(x)
|
||||||
|
// embedding stand-alone type parameters is not permitted (issue #47127).
|
||||||
|
if _, ok := under(typ).(*TypeParam); ok {
|
||||||
|
check.error(x, "cannot embed a type parameter")
|
||||||
|
typ = Typ[Invalid]
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// intersect computes the intersection of the types x and y,
|
// intersect computes the intersection of the types x and y,
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ func _[V any, T interface { type map[string]V }](p T) V {
|
||||||
// Testing partial and full type inference, including the case where the types can
|
// Testing partial and full type inference, including the case where the types can
|
||||||
// be inferred without needing the types of the function arguments.
|
// be inferred without needing the types of the function arguments.
|
||||||
|
|
||||||
|
// Cannot embed stand-alone type parameters. Disabled for now.
|
||||||
|
/*
|
||||||
func f0[A any, B interface{type C}, C interface{type D}, D interface{type A}](A, B, C, D)
|
func f0[A any, B interface{type C}, C interface{type D}, D interface{type A}](A, B, C, D)
|
||||||
func _() {
|
func _() {
|
||||||
f := f0[string]
|
f := f0[string]
|
||||||
|
|
@ -82,6 +84,7 @@ func _() {
|
||||||
f(0, 0)
|
f(0, 0)
|
||||||
f1(0, 0)
|
f1(0, 0)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func f2[A any, B interface{type []A}](_ A, _ B)
|
func f2[A any, B interface{type []A}](_ A, _ B)
|
||||||
func _() {
|
func _() {
|
||||||
|
|
@ -92,6 +95,8 @@ func _() {
|
||||||
// f2(0, []byte{}) - this one doesn't work
|
// f2(0, []byte{}) - this one doesn't work
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cannot embed stand-alone type parameters. Disabled for now.
|
||||||
|
/*
|
||||||
func f3[A any, B interface{type C}, C interface{type *A}](a A, _ B, c C)
|
func f3[A any, B interface{type C}, C interface{type *A}](a A, _ B, c C)
|
||||||
func _() {
|
func _() {
|
||||||
f := f3[int]
|
f := f3[int]
|
||||||
|
|
@ -99,6 +104,7 @@ func _() {
|
||||||
f(x, &x, &x)
|
f(x, &x, &x)
|
||||||
f3(x, &x, &x)
|
f3(x, &x, &x)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
func f4[A any, B interface{type []C}, C interface{type *A}](_ A, _ B, c C)
|
func f4[A any, B interface{type []C}, C interface{type *A}](_ A, _ B, c C)
|
||||||
func _() {
|
func _() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue