mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
[dev.typeparams] cmd/compile/internal/types2: disallow ~T where T is a defined type or an interface
Change-Id: I35f6f43db00d56847da48320308f2fcfff924738 Reviewed-on: https://go-review.googlesource.com/c/go/+/324570 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
8cdce85bdf
commit
10d6b36ca3
|
@ -176,12 +176,12 @@ type _ interface {
|
||||||
// Interface type lists can contain any type, incl. *Named types.
|
// Interface type lists can contain any type, incl. *Named types.
|
||||||
// Verify that we use the underlying type to compute the operational type.
|
// Verify that we use the underlying type to compute the operational type.
|
||||||
type MyInt int
|
type MyInt int
|
||||||
func add1[T interface{~MyInt}](x T) T {
|
func add1[T interface{MyInt}](x T) T {
|
||||||
return x + 1
|
return x + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
type MyString string
|
type MyString string
|
||||||
func double[T interface{~MyInt | ~MyString}](x T) T {
|
func double[T interface{MyInt|MyString}](x T) T {
|
||||||
return x + x
|
return x + x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,15 @@ type (
|
||||||
_ interface{int|interface /* ERROR cannot use interface */ {}}
|
_ interface{int|interface /* ERROR cannot use interface */ {}}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// Tilde is not permitted on defined types or interfaces.
|
||||||
|
foo int
|
||||||
|
bar interface{}
|
||||||
|
_ interface{foo}
|
||||||
|
_ interface{~ /* ERROR invalid use of ~ */ foo }
|
||||||
|
_ interface{~ /* ERROR invalid use of ~ */ bar }
|
||||||
|
)
|
||||||
|
|
||||||
// Multiple embedded union elements are intersected. The order in which they
|
// Multiple embedded union elements are intersected. The order in which they
|
||||||
// appear in the interface doesn't matter since intersection is a symmetric
|
// appear in the interface doesn't matter since intersection is a symmetric
|
||||||
// operation.
|
// operation.
|
||||||
|
|
|
@ -36,8 +36,8 @@ func bar8[A foo8[A]](a A) {}
|
||||||
func main8() {}
|
func main8() {}
|
||||||
|
|
||||||
// crash 9
|
// crash 9
|
||||||
type foo9[A any] interface { ~/* ERROR cannot use interface */ foo9[A] }
|
type foo9[A any] interface { foo9 /* ERROR illegal cycle */ [A] }
|
||||||
func _() { var _ = new(foo9 /* ERROR interface contains type constraints */ [int]) }
|
func _() { var _ = new(foo9 /* ERROR illegal cycle */ [int]) }
|
||||||
|
|
||||||
// crash 12
|
// crash 12
|
||||||
var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undeclared */ /* ERROR undeclared */
|
var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undeclared */ /* ERROR undeclared */
|
||||||
|
|
|
@ -106,17 +106,18 @@ func parseUnion(check *Checker, tlist []syntax.Expr) Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
u := under(t)
|
u := under(t)
|
||||||
if tilde[i] {
|
if tilde[i] && !Identical(u, t) {
|
||||||
// TODO(gri) enable this check once we have converted tests
|
check.errorf(x, "invalid use of ~ (underlying type of %s is %s)", t, u)
|
||||||
// if !Identical(u, t) {
|
continue // don't report another error for t
|
||||||
// check.errorf(x, "invalid use of ~ (underlying type of %s is %s)", t, u)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
if _, ok := u.(*Interface); ok {
|
if _, ok := u.(*Interface); ok {
|
||||||
|
// A single type with a ~ is a single-term union.
|
||||||
check.errorf(pos, "cannot use interface %s with ~ or inside a union (implementation restriction)", t)
|
check.errorf(pos, "cannot use interface %s with ~ or inside a union (implementation restriction)", t)
|
||||||
|
continue // don't report another error for t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complain about duplicate entries a|a, but also a|~a, and ~a|~a.
|
// Complain about duplicate entries a|a, but also a|~a, and ~a|~a.
|
||||||
|
// TODO(gri) We should also exclude myint|~int since myint is included in ~int.
|
||||||
if includes(types[:i], t) {
|
if includes(types[:i], t) {
|
||||||
// TODO(gri) this currently doesn't print the ~ if present
|
// TODO(gri) this currently doesn't print the ~ if present
|
||||||
check.softErrorf(pos, "duplicate term %s in union element", t)
|
check.softErrorf(pos, "duplicate term %s in union element", t)
|
||||||
|
|
Loading…
Reference in a new issue