| // Copyright 2018 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 |
| |
| // import "io" // for type assertion tests |
| |
| // The predeclared identifier "any" is only visible as a constraint |
| // in a type parameter list. |
| var _ any // ERROR undeclared |
| func _[_ any /* ok here */ , _ interface{any /* ERROR undeclared */ }](any /* ERROR undeclared */ ) { |
| var _ any /* ERROR undeclared */ |
| } |
| |
| func identity[T any](x T) T { return x } |
| |
| func _[_ any](x int) int |
| func _[T any](T /* ERROR redeclared */ T)() |
| func _[T, T /* ERROR redeclared */ any]() |
| |
| // Constraints (incl. any) may be parenthesized. |
| func _[_ (any)]() {} |
| func _[_ (interface{})]() {} |
| |
| func reverse[T any](list []T) []T { |
| rlist := make([]T, len(list)) |
| i := len(list) |
| for _, x := range list { |
| i-- |
| rlist[i] = x |
| } |
| return rlist |
| } |
| |
| var _ = reverse /* ERROR cannot use generic function reverse */ |
| var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3}) |
| var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3}) |
| var f = reverse[chan int] |
| var _ = f(0 /* ERROR cannot use 0 .* as \[\]chan int */ ) |
| |
| func swap[A, B any](a A, b B) (B, A) { return b, a } |
| |
| var _ = swap /* ERROR single value is expected */ [int, float32](1, 2) |
| var f32, i = swap[int, float32](swap[float32, int](1, 2)) |
| var _ float32 = f32 |
| var _ int = i |
| |
| func swapswap[A, B any](a A, b B) (A, B) { |
| return swap[B, A](b, a) |
| } |
| |
| type F[A, B any] func(A, B) (B, A) |
| |
| func min[T interface{ type int }](x, y T) T { |
| if x < y { |
| return x |
| } |
| return y |
| } |
| |
| func _[T interface{type int, float32}](x, y T) bool { return x < 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 C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y } |
| func _[T C2[T]](x, y T) bool { return x < y } |
| |
| type C1[T any] interface{} |
| type C2[T any] interface{ type int, float32 } |
| |
| func new[T any]() *T { |
| var x T |
| return &x |
| } |
| |
| var _ = new /* ERROR cannot use generic function new */ |
| var _ *int = new[int]() |
| |
| func _[T any](map[T /* ERROR incomparable map key type T \(missing comparable constraint\) */]int) // w/o constraint we don't know if T is comparable |
| |
| func f1[T1 any](struct{T1}) int |
| var _ = f1[int](struct{T1}{}) |
| type T1 = int |
| |
| func f2[t1 any](struct{t1; x float32}) int |
| var _ = f2[t1](struct{t1; x float32}{}) |
| type t1 = int |
| |
| |
| func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int |
| |
| var _ = f3[int, rune, bool](1, struct{x rune}{}, nil) |
| |
| // indexing |
| |
| 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{ type string }] (x T, i int) { _ = x[i] } |
| func _[T interface{ type []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{ type 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{ type string, []rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] } |
| |
| // 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{ type []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{ type []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{ type []E, map[string]E }, E any](x T, i int) { _ = x[i /* ERROR cannot use i */ ] } |
| |
| // slicing |
| // TODO(gri) implement this |
| |
| func _[T interface{ type string }] (x T, i, j, k int) { _ = x /* ERROR invalid operation */ [i:j:k] } |
| |
| // len/cap built-ins |
| |
| 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{ type string, []byte, int }](x T) { _ = len(x /* ERROR invalid argument */ ) } |
| func _[T interface{ type string }](x T) { _ = len(x) } |
| func _[T interface{ type [10]int }](x T) { _ = len(x) } |
| func _[T interface{ type []byte }](x T) { _ = len(x) } |
| func _[T interface{ type map[int]int }](x T) { _ = len(x) } |
| func _[T interface{ type chan int }](x T) { _ = len(x) } |
| func _[T interface{ type string, []byte, chan int }](x T) { _ = len(x) } |
| |
| 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{ type 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{ type [10]int }](x T) { _ = cap(x) } |
| func _[T interface{ type []byte }](x T) { _ = cap(x) } |
| func _[T interface{ type map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) } |
| func _[T interface{ type chan int }](x T) { _ = cap(x) } |
| func _[T interface{ type []byte, chan int }](x T) { _ = cap(x) } |
| |
| // range iteration |
| |
| func _[T interface{}](x T) { |
| for range x /* ERROR cannot range */ {} |
| } |
| |
| func _[T interface{ type string, []string }](x T) { |
| for range x {} |
| for i := range x { _ = i } |
| for i, _ := range x { _ = i } |
| for i, e := range x /* ERROR must have the same element type */ { _ = i } |
| for _, e := range x /* ERROR must have the same element type */ {} |
| var e rune |
| _ = e |
| for _, (e) = range x /* ERROR must have the same element type */ {} |
| } |
| |
| |
| func _[T interface{ type string, []rune, map[int]rune }](x T) { |
| for _, e := range x { _ = e } |
| for i, e := range x { _ = i; _ = e } |
| } |
| |
| func _[T interface{ type string, []rune, map[string]rune }](x T) { |
| for _, e := range x { _ = e } |
| for i, e := range x /* ERROR must have the same key type */ { _ = e } |
| } |
| |
| func _[T interface{ type string, chan int }](x T) { |
| for range x {} |
| for i := range x { _ = i } |
| 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) { |
| for i := range x /* ERROR send-only channel */ { _ = i } |
| } |
| |
| // type inference checks |
| |
| var _ = new /* ERROR cannot infer T */ () |
| |
| func f4[A, B, C any](A, B) C |
| |
| var _ = f4 /* ERROR cannot infer C */ (1, 2) |
| var _ = f4[int, float32, complex128](1, 2) |
| |
| func f5[A, B, C any](A, []*B, struct{f []C}) int |
| |
| var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{}) |
| var _ = f5 /* ERROR cannot infer */ (0, nil, struct{f []complex128}{}) |
| var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{}) |
| |
| func f6[A any](A, []A) int |
| |
| var _ = f6(0, nil) |
| |
| func f6nil[A any](A) int |
| |
| var _ = f6nil /* ERROR cannot infer */ (nil) |
| |
| // type inference with variadic functions |
| |
| func f7[T any](...T) T |
| |
| var _ int = f7 /* ERROR cannot infer T */ () |
| var _ int = f7(1) |
| var _ int = f7(1, 2) |
| var _ int = f7([]int{}...) |
| var _ int = f7 /* ERROR cannot use */ ([]float64{}...) |
| var _ float64 = f7([]float64{}...) |
| var _ = f7[float64](1, 2.3) |
| var _ = f7(float64(1), 2.3) |
| var _ = f7(1, 2.3 /* ERROR does not match */ ) |
| var _ = f7(1.2, 3 /* ERROR does not match */ ) |
| |
| func f8[A, B any](A, B, ...B) int |
| |
| var _ = f8(1) /* ERROR not enough arguments */ |
| var _ = f8(1, 2.3) |
| var _ = f8(1, 2.3, 3.4, 4.5) |
| var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ ) |
| var _ = f8[int, float64](1, 2.3, 3.4, 4) |
| |
| var _ = f8[int, float64](0, 0, nil...) // test case for #18268 |
| |
| // init functions cannot have type parameters |
| |
| func init() {} |
| func init[/* ERROR func init must have no type parameters */ _ any]() {} |
| func init[/* ERROR func init must have no type parameters */ P any]() {} |
| |
| type T struct {} |
| |
| func (T) m1() {} |
| func (T) m2[ /* ERROR methods cannot have type parameters */ _ any]() {} |
| func (T) m3[ /* ERROR methods cannot have type parameters */ P any]() {} |
| |
| // type inference across parameterized types |
| |
| type S1[P any] struct { f P } |
| |
| func f9[P any](x S1[P]) |
| |
| func _() { |
| f9[int](S1[int]{42}) |
| f9(S1[int]{42}) |
| } |
| |
| type S2[A, B, C any] struct{} |
| |
| func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool]) |
| |
| func _[P any]() { |
| f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{}) |
| f10(S2[int, int, string]{}, S2[int, float32, bool]{}) |
| f10(S2[P, int, P]{}, S2[P, float32, bool]{}) |
| } |
| |
| // corner case for type inference |
| // (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic) |
| |
| func f11[T any]() |
| |
| func _() { |
| f11[int]() |
| } |
| |
| // the previous example was extracted from |
| |
| func f12[T interface{m() T}]() |
| |
| type A[T any] T |
| |
| func (a A[T]) m() A[T] |
| |
| func _[T any]() { |
| f12[A[T]]() |
| } |
| |
| // method expressions |
| |
| func (_ S1[P]) m() |
| |
| func _() { |
| m := S1[int].m |
| m(struct { f int }{42}) |
| } |
| |
| func _[T any] (x T) { |
| m := S1[T].m |
| m(S1[T]{x}) |
| } |
| |
| // type parameters in methods (generalization) |
| |
| type R0 struct{} |
| |
| func (R0) _[ /* ERROR methods cannot have type parameters */ T any](x T) |
| func (R0 /* ERROR invalid receiver */ ) _[ /* ERROR methods cannot have type parameters */ R0 any]() // scope of type parameters starts at "func" |
| |
| type R1[A, B any] struct{} |
| |
| func (_ R1[A, B]) m0(A, B) |
| func (_ R1[A, B]) m1[ /* ERROR methods cannot have type parameters */ T any](A, B, T) T |
| func (_ R1 /* ERROR not a generic type */ [R1, _]) _() |
| func (_ R1[A, B]) _[ /* ERROR methods cannot have type parameters */ A /* ERROR redeclared */ any](B) |
| |
| func _() { |
| var r R1[int, string] |
| r.m1[rune](42, "foo", 'a') |
| r.m1[rune](42, "foo", 1.2 /* ERROR cannot use .* as rune .* \(truncated\) */) |
| r.m1(42, "foo", 1.2) // using type inference |
| var _ float64 = r.m1(42, "foo", 1.2) |
| } |
| |
| type I1[A any] interface { |
| m1(A) |
| } |
| |
| var _ I1[int] = r1[int]{} |
| |
| type r1[T any] struct{} |
| |
| func (_ r1[T]) m1(T) |
| |
| type I2[A, B any] interface { |
| m1(A) |
| m2(A) B |
| } |
| |
| var _ I2[int, float32] = R2[int, float32]{} |
| |
| type R2[P, Q any] struct{} |
| |
| func (_ R2[X, Y]) m1(X) |
| func (_ R2[X, Y]) m2(X) Y |
| |
| // type assertions and type switches over generic types |
| // NOTE: These are currently disabled because it's unclear what the correct |
| // approach is, and one can always work around by assigning the variable to |
| // an interface first. |
| |
| // // ReadByte1 corresponds to the ReadByte example in the draft design. |
| // func ReadByte1[T io.Reader](r T) (byte, error) { |
| // if br, ok := r.(io.ByteReader); ok { |
| // return br.ReadByte() |
| // } |
| // var b [1]byte |
| // _, err := r.Read(b[:]) |
| // return b[0], err |
| // } |
| // |
| // // ReadBytes2 is like ReadByte1 but uses a type switch instead. |
| // func ReadByte2[T io.Reader](r T) (byte, error) { |
| // switch br := r.(type) { |
| // case io.ByteReader: |
| // return br.ReadByte() |
| // } |
| // var b [1]byte |
| // _, err := r.Read(b[:]) |
| // return b[0], err |
| // } |
| // |
| // // type assertions and type switches over generic types are strict |
| // type I3 interface { |
| // m(int) |
| // } |
| // |
| // type I4 interface { |
| // m() int // different signature from I3.m |
| // } |
| // |
| // func _[T I3](x I3, p T) { |
| // // type assertions and type switches over interfaces are not strict |
| // _ = x.(I4) |
| // switch x.(type) { |
| // case I4: |
| // } |
| // |
| // // type assertions and type switches over generic types are strict |
| // _ = p /* ERROR cannot have dynamic type I4 */.(I4) |
| // switch p.(type) { |
| // case I4 /* ERROR cannot have dynamic type I4 */ : |
| // } |
| // } |
| |
| // type assertions and type switches over generic types lead to errors for now |
| |
| func _[T any](x T) { |
| _ = x /* ERROR not an interface */ .(int) |
| switch x /* ERROR not an interface */ .(type) { |
| } |
| |
| // work-around |
| var t interface{} = x |
| _ = t.(int) |
| switch t.(type) { |
| } |
| } |
| |
| func _[T interface{type int}](x T) { |
| _ = x /* ERROR not an interface */ .(int) |
| switch x /* ERROR not an interface */ .(type) { |
| } |
| |
| // work-around |
| var t interface{} = x |
| _ = t.(int) |
| switch t.(type) { |
| } |
| } |
| |
| // error messages related to type bounds mention those bounds |
| type C[P any] interface{} |
| |
| func _[P C[P]] (x P) { |
| x.m /* ERROR x.m undefined */ () |
| } |
| |
| type I interface {} |
| |
| func _[P I] (x P) { |
| x.m /* ERROR interface I has no method m */ () |
| } |
| |
| func _[P interface{}] (x P) { |
| x.m /* ERROR type bound for P has no method m */ () |
| } |
| |
| func _[P any] (x P) { |
| x.m /* ERROR type bound for P has no method m */ () |
| } |