1
0
mirror of https://github.com/golang/go synced 2024-11-11 23:40:22 -07:00

[dev.typeparams] go/types: convert testdata/check tests to type set syntax

This is a port of CL 324569 to go/types, with some error positions
adjusted: go/types puts errors related to terms on the '~', not type
name.

Change-Id: I92e8443ce27a5ecae0e3e0dac4811eaf3eee07ff
Reviewed-on: https://go-review.googlesource.com/c/go/+/326682
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Rob Findley 2021-06-10 09:27:44 -04:00 committed by Robert Findley
parent b6fc4d01a8
commit 6e50f4f111
6 changed files with 90 additions and 89 deletions

View File

@ -7,19 +7,19 @@
package builtins package builtins
type Bmc interface { type Bmc interface {
type map[rune]string, chan int ~map[rune]string | ~chan int
} }
type Bms interface { type Bms interface {
type map[string]int, []int ~map[string]int | ~[]int
} }
type Bcs interface { type Bcs interface {
type chan bool, []float64 ~chan bool | ~[]float64
} }
type Bss interface { type Bss interface {
type []int, []string ~[]int | ~[]string
} }
func _[T any] () { func _[T any] () {

View File

@ -64,7 +64,7 @@ func _() {
// type with a type list constraint, all of the type argument's types in its // type with a type list constraint, all of the type argument's types in its
// bound, but at least one (!), must be in the type list of the bound of the // bound, but at least one (!), must be in the type list of the bound of the
// corresponding parameterized type's type parameter. // corresponding parameterized type's type parameter.
type T1[P interface{type uint}] struct{} type T1[P interface{~uint}] struct{}
func _[P any]() { func _[P any]() {
_ = T1[P /* ERROR P has no type constraints */ ]{} _ = T1[P /* ERROR P has no type constraints */ ]{}
@ -72,7 +72,7 @@ func _[P any]() {
// This is the original (simplified) program causing the same issue. // This is the original (simplified) program causing the same issue.
type Unsigned interface { type Unsigned interface {
type uint ~uint
} }
type T2[U Unsigned] struct { type T2[U Unsigned] struct {
@ -163,7 +163,7 @@ type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
// predicate disjunction in the implementation was wrong because if a type list // predicate disjunction in the implementation was wrong because if a type list
// contains both an integer and a floating-point type, the type parameter is // contains both an integer and a floating-point type, the type parameter is
// neither an integer or a floating-point number. // neither an integer or a floating-point number.
func convert[T1, T2 interface{type int, uint, float32}](v T1) T2 { func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
return T2(v) return T2(v)
} }
@ -175,12 +175,12 @@ func _() {
// both numeric, or both strings. The implementation had the same problem // both numeric, or both strings. The implementation had the same problem
// with this check as the conversion issue above (issue #39623). // with this check as the conversion issue above (issue #39623).
func issue39623[T interface{type int, string}](x, y T) T { func issue39623[T interface{~int | ~string}](x, y T) T {
return x + y return x + y
} }
// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI: // Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
func Sum[T interface{type int, string}](s []T) (sum T) { func Sum[T interface{~int | ~string}](s []T) (sum T) {
for _, v := range s { for _, v := range s {
sum += v sum += v
} }
@ -189,19 +189,19 @@ func Sum[T interface{type int, string}](s []T) (sum T) {
// Assignability of an unnamed pointer type to a type parameter that // Assignability of an unnamed pointer type to a type parameter that
// has a matching underlying type. // has a matching underlying type.
func _[T interface{}, PT interface{type *T}] (x T) PT { func _[T interface{}, PT interface{~*T}] (x T) PT {
return &x return &x
} }
// Indexing of generic types containing type parameters in their type list: // Indexing of generic types containing type parameters in their type list:
func at[T interface{ type []E }, E interface{}](x T, i int) E { func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
return x[i] return x[i]
} }
// A generic type inside a function acts like a named type. Its underlying // A generic type inside a function acts like a named type. Its underlying
// type is itself, its "operational type" is defined by the type list in // type is itself, its "operational type" is defined by the type list in
// the tybe bound, if any. // the tybe bound, if any.
func _[T interface{type int}](x T) { func _[T interface{~int}](x T) {
type myint int type myint int
var _ int = int(x) var _ int = int(x)
var _ T = 42 var _ T = 42
@ -210,24 +210,24 @@ func _[T interface{type int}](x T) {
// Indexing a generic type with an array type bound checks length. // Indexing a generic type with an array type bound checks length.
// (Example by mdempsky@.) // (Example by mdempsky@.)
func _[T interface { type [10]int }](x T) { func _[T interface { ~[10]int }](x T) {
_ = x[9] // ok _ = x[9] // ok
_ = x[20 /* ERROR out of bounds */ ] _ = x[20 /* ERROR out of bounds */ ]
} }
// Pointer indirection of a generic type. // Pointer indirection of a generic type.
func _[T interface{ type *int }](p T) int { func _[T interface{ ~*int }](p T) int {
return *p return *p
} }
// Channel sends and receives on generic types. // Channel sends and receives on generic types.
func _[T interface{ type chan int }](ch T) int { func _[T interface{ ~chan int }](ch T) int {
ch <- 0 ch <- 0
return <- ch return <- ch
} }
// Calling of a generic variable. // Calling of a generic variable.
func _[T interface{ type func() }](f T) { func _[T interface{ ~func() }](f T) {
f() f()
go f() go f()
} }
@ -239,7 +239,7 @@ func _[T interface{ type func() }](f T) {
// type parameter that was substituted with a defined type. // type parameter that was substituted with a defined type.
// Test case from an (originally) failing example. // Test case from an (originally) failing example.
type sliceOf[E any] interface{ type []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{ T }](s S, t ...T2) S

View File

@ -9,10 +9,10 @@ import "math"
// Numeric is type bound that matches any numeric type. // Numeric is type bound that matches any numeric type.
// It would likely be in a constraints package in the standard library. // It would likely be in a constraints package in the standard library.
type Numeric interface { type Numeric interface {
type int, int8, int16, int32, int64, ~int | ~int8 | ~int16 | ~int32 | ~int64 |
uint, uint8, uint16, uint32, uint64, uintptr, ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
float32, float64, ~float32 | ~float64 |
complex64, complex128 ~complex64 | ~complex128
} }
func DotProduct[T Numeric](s1, s2 []T) T { func DotProduct[T Numeric](s1, s2 []T) T {
@ -42,14 +42,14 @@ func AbsDifference[T NumericAbs[T]](a, b T) T {
// OrderedNumeric is a type bound that matches numeric types that support the < operator. // OrderedNumeric is a type bound that matches numeric types that support the < operator.
type OrderedNumeric interface { type OrderedNumeric interface {
type int, int8, int16, int32, int64, ~int | ~int8 | ~int16 | ~int32 | ~int64 |
uint, uint8, uint16, uint32, uint64, uintptr, ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
float32, float64 ~float32 | ~float64
} }
// Complex is a type bound that matches the two complex types, which do not have a < operator. // Complex is a type bound that matches the two complex types, which do not have a < operator.
type Complex interface { type Complex interface {
type complex64, complex128 ~complex64 | ~complex128
} }
// OrderedAbs is a helper type that defines an Abs method for // OrderedAbs is a helper type that defines an Abs method for

View File

@ -11,28 +11,28 @@ type any interface{}
// TODO(rFindley) the below partially applied function types should probably // TODO(rFindley) the below partially applied function types should probably
// not be permitted (spec question). // not be permitted (spec question).
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{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
func _() { func _() {
f := f0[string] f := f0[string]
f("a", "b", "c", "d") f("a", "b", "c", "d")
f0("a", "b", "c", "d") f0("a", "b", "c", "d")
} }
func f1[A any, B interface{type A}](A, B) func f1[A any, B interface{~A}](A, B)
func _() { func _() {
f := f1[int] f := f1[int]
f(int(0), int(0)) f(int(0), int(0))
f1(int(0), int(0)) f1(int(0), int(0))
} }
func f2[A any, B interface{type []A}](A, B) func f2[A any, B interface{~[]A}](A, B)
func _() { func _() {
f := f2[byte] f := f2[byte]
f(byte(0), []byte{}) f(byte(0), []byte{})
f2(byte(0), []byte{}) f2(byte(0), []byte{})
} }
func f3[A any, B interface{type C}, C interface{type *A}](A, B, C) func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
func _() { func _() {
f := f3[int] f := f3[int]
var x int var x int
@ -40,7 +40,7 @@ func _() {
f3(x, &x, &x) f3(x, &x, &x)
} }
func f4[A any, B interface{type []C}, C interface{type *A}](A, B, C) func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C)
func _() { func _() {
f := f4[int] f := f4[int]
var x int var x int
@ -48,14 +48,14 @@ func _() {
f4(x, []*int{}, &x) f4(x, []*int{}, &x)
} }
func f5[A interface{type struct{b B; c C}}, B any, C interface{type *B}](x B) A func f5[A interface{~struct{b B; c C}}, B any, C interface{~*B}](x B) A
func _() { func _() {
x := f5(1.2) x := f5(1.2)
var _ float64 = x.b var _ float64 = x.b
var _ float64 = *x.c var _ float64 = *x.c
} }
func f6[A any, B interface{type struct{f []A}}](B) A func f6[A any, B interface{~struct{f []A}}](B) A
func _() { func _() {
x := f6(struct{f []string}{}) x := f6(struct{f []string}{})
var _ string = x var _ string = x
@ -63,11 +63,11 @@ func _() {
// TODO(gri) Need to flag invalid recursive constraints. At the // TODO(gri) Need to flag invalid recursive constraints. At the
// moment these cause infinite recursions and stack overflow. // moment these cause infinite recursions and stack overflow.
// func f7[A interface{type B}, B interface{type A}]() // func f7[A interface{type B}, B interface{~A}]()
// More realistic examples // More realistic examples
func Double[S interface{ type []E }, E interface{ type int, int8, int16, int32, int64 }](s S) S { func Double[S interface{ ~[]E }, E interface{ ~int | ~int8 | ~int16 | ~int32 | ~int64 }](s S) S {
r := make(S, len(s)) r := make(S, len(s))
for i, v := range s { for i, v := range s {
r[i] = v + v r[i] = v + v
@ -83,7 +83,7 @@ var _ = Double(MySlice{1})
type Setter[B any] interface { type Setter[B any] interface {
Set(string) Set(string)
type *B ~*B
} }
func FromStrings[T interface{}, PT Setter[T]](s []string) []T { func FromStrings[T interface{}, PT Setter[T]](s []string) []T {

View File

@ -148,15 +148,15 @@ func _[T any](r R2[T, int], p *R2[string, T]) {
p.pm() p.pm()
} }
// An interface can (explicitly) declare at most one type list. // It is ok to have multiple embedded unions.
type _ interface { type _ interface {
m0() m0()
type int, string, bool ~int | ~string | ~bool
type /* ERROR multiple type lists */ float32, float64 ~float32 | ~float64
m1() m1()
m2() m2()
type /* ERROR multiple type lists */ complex64, complex128 ~complex64 | ~complex128
type /* ERROR multiple type lists */ rune ~rune
} }
// Interface type lists may contain each type at most once. // Interface type lists may contain each type at most once.
@ -164,23 +164,24 @@ type _ interface {
// for them to be all in a single list, and we report the error // for them to be all in a single list, and we report the error
// as well.) // as well.)
type _ interface { type _ interface {
type int, int /* ERROR duplicate term int */ ~int|~ /* ERROR duplicate term int */ int
type /* ERROR multiple type lists */ int /* ERROR duplicate term int */ ~int|int /* ERROR duplicate term int */
int|int /* ERROR duplicate term int */
} }
type _ interface { type _ interface {
type struct{f int}, struct{g int}, struct /* ERROR duplicate term */ {f int} ~struct{f int} | ~struct{g int} | ~ /* ERROR duplicate term */ struct{f int}
} }
// 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{type 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{type MyInt, MyString}](x T) T { func double[T interface{~MyInt | ~MyString}](x T) T {
return x + x return x + x
} }
@ -189,15 +190,15 @@ func double[T interface{type MyInt, MyString}](x T) T {
// type lists. // type lists.
type E0 interface { type E0 interface {
type int, bool, string ~int | ~bool | ~string
} }
type E1 interface { type E1 interface {
type int, float64, string ~int | ~float64 | ~string
} }
type E2 interface { type E2 interface {
type float64 ~float64
} }
type I0 interface { type I0 interface {
@ -246,7 +247,7 @@ var _ = f12[float64]
type I0_ interface { type I0_ interface {
E0 E0
type int ~int
} }
func f0_[T I0_]() func f0_[T I0_]()

View File

@ -52,22 +52,22 @@ func swapswap[A, B any](a A, b B) (A, B) {
type F[A, B any] func(A, B) (B, A) type F[A, B any] func(A, B) (B, A)
func min[T interface{ type int }](x, y T) T { func min[T interface{ ~int }](x, y T) T {
if x < y { if x < y {
return x return x
} }
return y return y
} }
func _[T interface{type int, float32}](x, y T) bool { return x < y } func _[T interface{~int | ~float32}](x, y T) bool { return x < y }
func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y } func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y }
func _[T interface{type int, float32, bool}](x, y T) bool { return x /* ERROR cannot compare */ < y } func _[T interface{~int | ~float32 | ~bool}](x, y T) bool { return x /* ERROR cannot compare */ < y }
func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y } func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y }
func _[T C2[T]](x, y T) bool { return x < y } func _[T C2[T]](x, y T) bool { return x < y }
type C1[T any] interface{} type C1[T any] interface{}
type C2[T any] interface{ type int, float32 } type C2[T any] interface{ ~int | ~float32 }
func new[T any]() *T { func new[T any]() *T {
var x T var x T
@ -95,48 +95,48 @@ var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
// indexing // indexing
func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
func _[T interface{ type int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } func _[T interface{ ~int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
func _[T interface{ type string }] (x T, i int) { _ = x[i] } func _[T interface{ ~string }] (x T, i int) { _ = x[i] }
func _[T interface{ type []int }] (x T, i int) { _ = x[i] } func _[T interface{ ~[]int }] (x T, i int) { _ = x[i] }
func _[T interface{ type [10]int, *[20]int, map[int]int }] (x T, i int) { _ = x[i] } func _[T interface{ ~[10]int | ~*[20]int | ~map[int]int }] (x T, i int) { _ = x[i] }
func _[T interface{ type string, []byte }] (x T, i int) { _ = x[i] } func _[T interface{ ~string | ~[]byte }] (x T, i int) { _ = x[i] }
func _[T interface{ type []int, [1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } func _[T interface{ ~[]int | ~[1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
func _[T interface{ type string, []rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } func _[T interface{ ~string | ~[]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
// indexing with various combinations of map types in type lists (see issue #42616) // indexing with various combinations of map types in type lists (see issue #42616)
func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = x[i] } func _[T interface{ ~[]E | ~map[int]E }, E any](x T, i int) { _ = x[i] }
func _[T interface{ type []E }, E any](x T, i int) { _ = &x[i] } func _[T interface{ ~[]E }, E any](x T, i int) { _ = &x[i] }
func _[T interface{ type map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted func _[T interface{ ~map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted
func _[T interface{ type []E, map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] } func _[T interface{ ~[]E | ~map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] }
func _[T interface{ type []E, map[int]E, map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types func _[T interface{ ~[]E | ~map[int]E | ~map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types
func _[T interface{ type []E, map[string]E }, E any](x T, i int) { _ = x[i /* ERROR cannot use i */ ] } func _[T interface{ ~[]E | ~map[string]E }, E any](x T, i int) { _ = x[i /* ERROR cannot use i */ ] }
// slicing // slicing
// TODO(gri) implement this // TODO(gri) implement this
func _[T interface{ type string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] } func _[T interface{ ~string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] }
// len/cap built-ins // len/cap built-ins
func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) } func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
func _[T interface{ type int }](x T) { _ = len(x /* ERROR invalid argument */ ) } func _[T interface{ ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
func _[T interface{ type string, []byte, int }](x T) { _ = len(x /* ERROR invalid argument */ ) } func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
func _[T interface{ type string }](x T) { _ = len(x) } func _[T interface{ ~string }](x T) { _ = len(x) }
func _[T interface{ type [10]int }](x T) { _ = len(x) } func _[T interface{ ~[10]int }](x T) { _ = len(x) }
func _[T interface{ type []byte }](x T) { _ = len(x) } func _[T interface{ ~[]byte }](x T) { _ = len(x) }
func _[T interface{ type map[int]int }](x T) { _ = len(x) } func _[T interface{ ~map[int]int }](x T) { _ = len(x) }
func _[T interface{ type chan int }](x T) { _ = len(x) } func _[T interface{ ~chan int }](x T) { _ = len(x) }
func _[T interface{ type string, []byte, chan int }](x T) { _ = len(x) } func _[T interface{ ~string | ~[]byte | ~chan int }](x T) { _ = len(x) }
func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) } func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) }
func _[T interface{ type int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } func _[T interface{ ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
func _[T interface{ type string, []byte, int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
func _[T interface{ type string }](x T) { _ = cap(x /* ERROR invalid argument */ ) } func _[T interface{ ~string }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
func _[T interface{ type [10]int }](x T) { _ = cap(x) } func _[T interface{ ~[10]int }](x T) { _ = cap(x) }
func _[T interface{ type []byte }](x T) { _ = cap(x) } func _[T interface{ ~[]byte }](x T) { _ = cap(x) }
func _[T interface{ type map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } func _[T interface{ ~map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
func _[T interface{ type chan int }](x T) { _ = cap(x) } func _[T interface{ ~chan int }](x T) { _ = cap(x) }
func _[T interface{ type []byte, chan int }](x T) { _ = cap(x) } func _[T interface{ ~[]byte | ~chan int }](x T) { _ = cap(x) }
// range iteration // range iteration
@ -144,7 +144,7 @@ func _[T interface{}](x T) {
for range x /* ERROR cannot range */ {} for range x /* ERROR cannot range */ {}
} }
func _[T interface{ type string, []string }](x T) { func _[T interface{ ~string | ~[]string }](x T) {
for range x {} for range x {}
for i := range x { _ = i } for i := range x { _ = i }
for i, _ := range x { _ = i } for i, _ := range x { _ = i }
@ -156,23 +156,23 @@ func _[T interface{ type string, []string }](x T) {
} }
func _[T interface{ type string, []rune, map[int]rune }](x T) { func _[T interface{ ~string | ~[]rune | ~map[int]rune }](x T) {
for _, e := range x { _ = e } for _, e := range x { _ = e }
for i, e := range x { _ = i; _ = e } for i, e := range x { _ = i; _ = e }
} }
func _[T interface{ type string, []rune, map[string]rune }](x T) { func _[T interface{ ~string | ~[]rune | ~map[string]rune }](x T) {
for _, e := range x { _ = e } for _, e := range x { _ = e }
for i, e := range x /* ERROR must have the same key type */ { _ = e } for i, e := range x /* ERROR must have the same key type */ { _ = e }
} }
func _[T interface{ type string, chan int }](x T) { func _[T interface{ ~string | ~chan int }](x T) {
for range x {} for range x {}
for i := range x { _ = i } for i := range x { _ = i }
for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value for i, _ := range x { _ = i } // TODO(gri) should get an error here: channels only return one value
} }
func _[T interface{ type string, chan<-int }](x T) { func _[T interface{ ~string | ~chan<-int }](x T) {
for i := range x /* ERROR send-only channel */ { _ = i } for i := range x /* ERROR send-only channel */ { _ = i }
} }
@ -399,7 +399,7 @@ func _[T any](x T) {
} }
} }
func _[T interface{type int}](x T) { func _[T interface{~int}](x T) {
_ = x /* ERROR not an interface */ .(int) _ = x /* ERROR not an interface */ .(int)
switch x /* ERROR not an interface */ .(type) { switch x /* ERROR not an interface */ .(type) {
} }