func TestCheck(t *testing.T) { DefPredeclaredTestFuncs(); testDirFiles(t, "testdata/check", 55, false) } // TODO(gri) narrow column tolerance
func TestSpec(t *testing.T) { testDirFiles(t, "../../../../go/types/testdata/spec", 0, false) }
-func TestExamples(t *testing.T) { testDirFiles(t, "testdata/examples", 45, false) }
+func TestExamples(t *testing.T) { testDirFiles(t, "../../../../go/types/testdata/examples", 45, false) }
func TestFixedbugs(t *testing.T) { testDirFiles(t, "testdata/fixedbugs", 0, false) }
func testDirFiles(t *testing.T, dir string, colDelta uint, manual bool) {
+++ /dev/null
-// 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.
-
-// This file shows some examples of generic constraint interfaces.
-
-package p
-
-type MyInt int
-
-type (
- // Arbitrary types may be embedded like interfaces.
- _ interface{int}
- _ interface{~int}
-
- // Types may be combined into a union.
- union interface{int|~string}
-
- // Union terms must describe disjoint (non-overlapping) type sets.
- _ interface{int|int /* ERROR overlapping terms int */ }
- _ interface{int|~ /* ERROR overlapping terms ~int */ int }
- _ interface{~int|~ /* ERROR overlapping terms ~int */ int }
- _ interface{~int|MyInt /* ERROR overlapping terms p.MyInt and ~int */ }
- _ interface{int|any}
- _ interface{int|~string|union}
- _ interface{int|~string|interface{int}}
- _ interface{union|int} // interfaces (here: union) are ignored when checking for overlap
- _ interface{union|union} // ditto
-
- // For now we do not permit interfaces with methods in unions.
- _ interface{~ /* ERROR invalid use of ~ */ any}
- _ interface{int|interface /* ERROR cannot use .* in union */ { m() }}
-)
-
-type (
- // Tilde is not permitted on defined types or interfaces.
- foo int
- bar any
- _ interface{foo}
- _ interface{~ /* ERROR invalid use of ~ */ foo }
- _ interface{~ /* ERROR invalid use of ~ */ bar }
-)
-
-// Stand-alone type parameters are not permitted as elements or terms in unions.
-type (
- _[T interface{ *T } ] struct{} // ok
- _[T interface{ int | *T } ] struct{} // ok
- _[T interface{ T /* ERROR term cannot be a type parameter */ } ] struct{}
- _[T interface{ ~T /* ERROR type in term ~T cannot be a type parameter */ } ] struct{}
- _[T interface{ int|T /* ERROR term cannot be a type parameter */ }] struct{}
-)
-
-// Multiple embedded union elements are intersected. The order in which they
-// appear in the interface doesn't matter since intersection is a symmetric
-// operation.
-
-type myInt1 int
-type myInt2 int
-
-func _[T interface{ myInt1|myInt2; ~int }]() T { return T(0) }
-func _[T interface{ ~int; myInt1|myInt2 }]() T { return T(0) }
-
-// Here the intersections are empty - there's no type that's in the type set of T.
-func _[T interface{ myInt1|myInt2; int }]() T { return T(0 /* ERROR cannot convert */ ) }
-func _[T interface{ int; myInt1|myInt2 }]() T { return T(0 /* ERROR cannot convert */ ) }
-
-// Union elements may be interfaces as long as they don't define
-// any methods or embed comparable.
-
-type (
- Integer interface{ ~int|~int8|~int16|~int32|~int64 }
- Unsigned interface{ ~uint|~uint8|~uint16|~uint32|~uint64 }
- Floats interface{ ~float32|~float64 }
- Complex interface{ ~complex64|~complex128 }
- Number interface{ Integer|Unsigned|Floats|Complex }
- Ordered interface{ Integer|Unsigned|Floats|~string }
-
- _ interface{ Number | error /* ERROR cannot use error in union */ }
- _ interface{ Ordered | comparable /* ERROR cannot use comparable in union */ }
-)
+++ /dev/null
-// Copyright 2019 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.
-
-// This file shows some examples of type-parameterized functions.
-
-package p
-
-// Reverse is a generic function that takes a []T argument and
-// reverses that slice in place.
-func Reverse[T any](list []T) {
- i := 0
- j := len(list)-1
- for i < j {
- list[i], list[j] = list[j], list[i]
- i++
- j--
- }
-}
-
-func _() {
- // Reverse can be called with an explicit type argument.
- Reverse[int](nil)
- Reverse[string]([]string{"foo", "bar"})
- Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
-
- // Since the type parameter is used for an incoming argument,
- // it can be inferred from the provided argument's type.
- Reverse([]string{"foo", "bar"})
- Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
-
- // But the incoming argument must have a type, even if it's a
- // default type. An untyped nil won't work.
- // Reverse(nil) // this won't type-check
-
- // A typed nil will work, though.
- Reverse([]int(nil))
-}
-
-// Certain functions, such as the built-in `new` could be written using
-// type parameters.
-func new[T any]() *T {
- var x T
- return &x
-}
-
-// When calling our own `new`, we need to pass the type parameter
-// explicitly since there is no (value) argument from which the
-// result type could be inferred. We don't try to infer the
-// result type from the assignment to keep things simple and
-// easy to understand.
-var _ = new[int]()
-var _ *float64 = new[float64]() // the result type is indeed *float64
-
-// A function may have multiple type parameters, of course.
-func foo[A, B, C any](a A, b []B, c *C) B {
- // do something here
- return b[0]
-}
-
-// As before, we can pass type parameters explicitly.
-var s = foo[int, string, float64](1, []string{"first"}, new[float64]())
-
-// Or we can use type inference.
-var _ float64 = foo(42, []float64{1.0}, &s)
-
-// Type inference works in a straight-forward manner even
-// for variadic functions.
-func variadic[A, B any](A, B, ...B) int { panic(0) }
-
-// var _ = variadic(1) // ERROR not enough arguments
-var _ = variadic(1, 2.3)
-var _ = variadic(1, 2.3, 3.4, 4.5)
-var _ = variadic[int, float64](1, 2.3, 3.4, 4)
-
-// Type inference also works in recursive function calls where
-// the inferred type is the type parameter of the caller.
-func f1[T any](x T) {
- f1(x)
-}
-
-func f2a[T any](x, y T) {
- f2a(x, y)
-}
-
-func f2b[T any](x, y T) {
- f2b(y, x)
-}
-
-func g2a[P, Q any](x P, y Q) {
- g2a(x, y)
-}
-
-func g2b[P, Q any](x P, y Q) {
- g2b(y, x)
-}
-
-// Here's an example of a recursive function call with variadic
-// arguments and type inference inferring the type parameter of
-// the caller (i.e., itself).
-func max[T interface{ ~int }](x ...T) T {
- var x0 T
- if len(x) > 0 {
- x0 = x[0]
- }
- if len(x) > 1 {
- x1 := max(x[1:]...)
- if x1 > x0 {
- return x1
- }
- }
- return x0
-}
-
-// When inferring channel types, the channel direction is ignored
-// for the purpose of type inference. Once the type has been in-
-// fered, the usual parameter passing rules are applied.
-// Thus even if a type can be inferred successfully, the function
-// call may not be valid.
-
-func fboth[T any](chan T) {}
-func frecv[T any](<-chan T) {}
-func fsend[T any](chan<- T) {}
-
-func _() {
- var both chan int
- var recv <-chan int
- var send chan<-int
-
- fboth(both)
- fboth(recv /* ERROR cannot use */ )
- fboth(send /* ERROR cannot use */ )
-
- frecv(both)
- frecv(recv)
- frecv(send /* ERROR cannot use */ )
-
- fsend(both)
- fsend(recv /* ERROR cannot use */)
- fsend(send)
-}
-
-func ffboth[T any](func(chan T)) {}
-func ffrecv[T any](func(<-chan T)) {}
-func ffsend[T any](func(chan<- T)) {}
-
-func _() {
- var both func(chan int)
- var recv func(<-chan int)
- var send func(chan<- int)
-
- ffboth(both)
- ffboth(recv /* ERROR cannot use */ )
- ffboth(send /* ERROR cannot use */ )
-
- ffrecv(both /* ERROR cannot use */ )
- ffrecv(recv)
- ffrecv(send /* ERROR cannot use */ )
-
- ffsend(both /* ERROR cannot use */ )
- ffsend(recv /* ERROR cannot use */ )
- ffsend(send)
-}
-
-// When inferring elements of unnamed composite parameter types,
-// if the arguments are defined types, use their underlying types.
-// Even though the matching types are not exactly structurally the
-// same (one is a type literal, the other a named type), because
-// assignment is permitted, parameter passing is permitted as well,
-// so type inference should be able to handle these cases well.
-
-func g1[T any]([]T) {}
-func g2[T any]([]T, T) {}
-func g3[T any](*T, ...T) {}
-
-func _() {
- type intSlize []int
- g1([]int{})
- g1(intSlize{})
- g2(nil, 0)
-
- type myString string
- var s1 string
- g3(nil, "1", myString("2"), "3")
- g3(& /* ERROR does not match */ s1, "1", myString("2"), "3")
- _ = s1
-
- type myStruct struct{x int}
- var s2 myStruct
- g3(nil, struct{x int}{}, myStruct{})
- g3(&s2, struct{x int}{}, myStruct{})
- g3(nil, myStruct{}, struct{x int}{})
- g3(&s2, myStruct{}, struct{x int}{})
-}
-
-// Here's a realistic example.
-
-func append[T any](s []T, t ...T) []T { panic(0) }
-
-func _() {
- var f func()
- type Funcs []func()
- var funcs Funcs
- _ = append(funcs, f)
-}
-
-// Generic type declarations cannot have empty type parameter lists
-// (that would indicate a slice type). Thus, generic functions cannot
-// have empty type parameter lists, either. This is a syntax error.
-
-func h[] /* ERROR empty type parameter list */ () {}
-
-func _() {
- h /* ERROR cannot index */ [] /* ERROR operand */ ()
-}
-
-// Parameterized functions must have a function body.
-
-func _ /* ERROR missing function body */ [P any]()
+++ /dev/null
-// 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.
-
-// This file shows some examples of type inference.
-
-package p
-
-type Ordered interface {
- ~int | ~float64 | ~string
-}
-
-func min[T Ordered](x, y T) T { panic(0) }
-
-func _() {
- // min can be called with explicit instantiation.
- _ = min[int](1, 2)
-
- // Alternatively, the type argument can be inferred from
- // one of the arguments. Untyped arguments will be considered
- // last.
- var x int
- _ = min(x, x)
- _ = min(x, 1)
- _ = min(x, 1.0)
- _ = min(1, 2)
- _ = min(1, 2.3 /* ERROR default type float64 .* does not match */)
-
- var y float64
- _ = min(1, y)
- _ = min(1.2, y)
- _ = min(1.2, 3.4)
- _ = min(1.2, 3 /* ERROR default type int .* does not match */)
-
- var s string
- _ = min(s, "foo")
- _ = min("foo", "bar")
-}
-
-func mixed[T1, T2, T3 any](T1, T2, T3) {}
-
-func _() {
- // mixed can be called with explicit instantiation.
- mixed[int, string, bool](0, "", false)
-
- // Alternatively, partial type arguments may be provided
- // (from left to right), and the other may be inferred.
- mixed[int, string](0, "", false)
- mixed[int](0, "", false)
- mixed(0, "", false)
-
- // Provided type arguments always take precedence over
- // inferred types.
- mixed[int, string](1.1 /* ERROR cannot use 1.1 */, "", false)
-}
-
-func related1[Slice interface{ ~[]Elem }, Elem any](s Slice, e Elem) {}
-
-func _() {
- // related1 can be called with explicit instantiation.
- var si []int
- related1[[]int, int](si, 0)
-
- // Alternatively, the 2nd type argument can be inferred
- // from the first one through constraint type inference.
- var ss []string
- _ = related1[[]string]
- related1[[]string](ss, "foo")
-
- // A type argument inferred from another explicitly provided
- // type argument overrides whatever value argument type is given.
- related1[[]string](ss, 0 /* ERROR cannot use 0 */)
-
- // A type argument may be inferred from a value argument
- // and then help infer another type argument via constraint
- // type inference.
- related1(si, 0)
- related1(si, "foo" /* ERROR cannot use "foo" */)
-}
-
-func related2[Elem any, Slice interface{ []Elem }](e Elem, s Slice) {}
-
-func _() {
- // related2 can be called with explicit instantiation.
- var si []int
- related2[int, []int](0, si)
-
- // Alternatively, the 2nd type argument can be inferred
- // from the first one through constraint type inference.
- var ss []string
- _ = related2[string]
- related2[string]("foo", ss)
-
- // A type argument may be inferred from a value argument
- // and then help infer another type argument via constraint
- // type inference. Untyped arguments are always considered
- // last.
- related2(1.2, []float64{})
- related2(1.0, []int{})
- related2 /* ERROR does not implement */ (float64(1.0), []int{}) // TODO(gri) fix error position
-}
-
-type List[P any] []P
-
-func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil }
-
-func _() {
- // related3 can be instantiated explicitly
- related3[int, []int]()
- related3[byte, List[byte]]()
-
- // The 2nd type argument cannot be inferred from the first
- // one because there's two possible choices: []Elem and
- // List[Elem].
- related3 /* ERROR cannot infer Slice */ [int]()
-}
+++ /dev/null
-// Copyright 2019 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.
-
-// This file shows some examples of methods on type-parameterized types.
-
-package p
-
-// Parameterized types may have methods.
-type T1[A any] struct{ a A }
-
-// When declaring a method for a parameterized type, the "instantiated"
-// receiver type acts as an implicit declaration of the type parameters
-// for the receiver type. In the example below, method m1 on type T1 has
-// the receiver type T1[A] which declares the type parameter A for use
-// with this method. That is, within the method m1, A stands for the
-// actual type argument provided to an instantiated T1.
-func (t T1[A]) m1() A { return t.a }
-
-// For instance, if T1 is instantiated with the type int, the type
-// parameter A in m1 assumes that type (int) as well and we can write
-// code like this:
-var x T1[int]
-var _ int = x.m1()
-
-// Because the type parameter provided to a parameterized receiver type
-// is declared through that receiver declaration, it must be an identifier.
-// It cannot possibly be some other type because the receiver type is not
-// instantiated with concrete types, it is standing for the parameterized
-// receiver type.
-func (t T1[[ /* ERROR must be an identifier */ ]int]) m2() {}
-
-// Note that using what looks like a predeclared identifier, say int,
-// as type parameter in this situation is deceptive and considered bad
-// style. In m3 below, int is the name of the local receiver type parameter
-// and it shadows the predeclared identifier int which then cannot be used
-// anymore as expected.
-// This is no different from locally re-declaring a predeclared identifier
-// and usually should be avoided. There are some notable exceptions; e.g.,
-// sometimes it makes sense to use the identifier "copy" which happens to
-// also be the name of a predeclared built-in function.
-func (t T1[int]) m3() { var _ int = 42 /* ERROR cannot use 42 .* as int */ }
-
-// The names of the type parameters used in a parameterized receiver
-// type don't have to match the type parameter names in the declaration
-// of the type used for the receiver. In our example, even though T1 is
-// declared with type parameter named A, methods using that receiver type
-// are free to use their own name for that type parameter. That is, the
-// name of type parameters is always local to the declaration where they
-// are introduced. In our example we can write a method m2 and use the
-// name X instead of A for the type parameter w/o any difference.
-func (t T1[X]) m4() X { return t.a }
-
-// If the receiver type is parameterized, type parameters must always be
-// provided: this simply follows from the general rule that a parameterized
-// type must be instantiated before it can be used. A method receiver
-// declaration using a parameterized receiver type is no exception. It is
-// simply that such receiver type expressions perform two tasks simultaneously:
-// they declare the (local) type parameters and then use them to instantiate
-// the receiver type. Forgetting to provide a type parameter leads to an error.
-func (t T1 /* ERROR generic type .* without instantiation */ ) m5() {}
-
-// However, sometimes we don't need the type parameter, and thus it is
-// inconvenient to have to choose a name. Since the receiver type expression
-// serves as a declaration for its type parameters, we are free to choose the
-// blank identifier:
-func (t T1[_]) m6() {}
-
-// Naturally, these rules apply to any number of type parameters on the receiver
-// type. Here are some more complex examples.
-type T2[A, B, C any] struct {
- a A
- b B
- c C
-}
-
-// Naming of the type parameters is local and has no semantic impact:
-func (t T2[A, B, C]) m1() (A, B, C) { return t.a, t.b, t.c }
-func (t T2[C, B, A]) m2() (C, B, A) { return t.a, t.b, t.c }
-func (t T2[X, Y, Z]) m3() (X, Y, Z) { return t.a, t.b, t.c }
-
-// Type parameters may be left blank if they are not needed:
-func (t T2[A, _, C]) m4() (A, C) { return t.a, t.c }
-func (t T2[_, _, X]) m5() X { return t.c }
-func (t T2[_, _, _]) m6() {}
-
-// As usual, blank names may be used for any object which we don't care about
-// using later. For instance, we may write an unnamed method with a receiver
-// that cannot be accessed:
-func (_ T2[_, _, _]) _() int { return 42 }
-
-// Because a receiver parameter list is simply a parameter list, we can
-// leave the receiver argument away for receiver types.
-type T0 struct{}
-func (T0) _() {}
-func (T1[A]) _() {}
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// // A generic receiver type may constrain its type parameter such
-// // that it must be a pointer type. Such receiver types are not
-// // permitted.
-// type T3a[P interface{ ~int | ~string | ~float64 }] P
-//
-// func (T3a[_]) m() {} // this is ok
-//
-// type T3b[P interface{ ~unsafe.Pointer }] P
-//
-// func (T3b /* ERROR invalid receiver */ [_]) m() {}
-//
-// type T3c[P interface{ *int | *string }] P
-//
-// func (T3c /* ERROR invalid receiver */ [_]) m() {}
+++ /dev/null
-// 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.
-
-package p
-
-// indirection
-
-func _[P any](p P) {
- _ = *p // ERROR cannot indirect p
-}
-
-func _[P interface{ int }](p P) {
- _ = *p // ERROR cannot indirect p
-}
-
-func _[P interface{ *int }](p P) {
- _ = *p
-}
-
-func _[P interface{ *int | *string }](p P) {
- _ = *p // ERROR must have identical base types
-}
-
-type intPtr *int
-
-func _[P interface{ *int | intPtr } ](p P) {
- var _ int = *p
-}
+++ /dev/null
-// Copyright 2019 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.
-
-// This file shows some examples of generic types.
-
-package p
-
-// List is just what it says - a slice of E elements.
-type List[E any] []E
-
-// A generic (parameterized) type must always be instantiated
-// before it can be used to designate the type of a variable
-// (including a struct field, or function parameter); though
-// for the latter cases, the provided type may be another type
-// parameter. So:
-var _ List[byte] = []byte{}
-
-// A generic binary tree might be declared as follows.
-type Tree[E any] struct {
- left, right *Tree[E]
- payload E
-}
-
-// A simple instantiation of Tree:
-var root1 Tree[int]
-
-// The actual type parameter provided may be a generic type itself:
-var root2 Tree[List[int]]
-
-// A couple of more complex examples.
-// We don't need extra parentheses around the element type of the slices on
-// the right (unlike when we use ()'s rather than []'s for type parameters).
-var _ List[List[int]] = []List[int]{}
-var _ List[List[List[Tree[int]]]] = []List[List[Tree[int]]]{}
-
-// Type parameters act like type aliases when used in generic types
-// in the sense that we can "emulate" a specific type instantiation
-// with type aliases.
-type T1[P any] struct {
- f P
-}
-
-type T2[P any] struct {
- f struct {
- g P
- }
-}
-
-var x1 T1[struct{ g int }]
-var x2 T2[int]
-
-func _() {
- // This assignment is invalid because the types of x1, x2 are T1(...)
- // and T2(...) respectively, which are two different defined types.
- x1 = x2 // ERROR assignment
-
- // This assignment is valid because the types of x1.f and x2.f are
- // both struct { g int }; the type parameters act like type aliases
- // and their actual names don't come into play here.
- x1.f = x2.f
-}
-
-// We can verify this behavior using type aliases instead:
-type T1a struct {
- f A1
-}
-type A1 = struct { g int }
-
-type T2a struct {
- f struct {
- g A2
- }
-}
-type A2 = int
-
-var x1a T1a
-var x2a T2a
-
-func _() {
- x1a = x2a // ERROR assignment
- x1a.f = x2a.f
-}
-
-// Another interesting corner case are generic types that don't use
-// their type arguments. For instance:
-type T[P any] struct{}
-
-var xint T[int]
-var xbool T[bool]
-
-// Are these two variables of the same type? After all, their underlying
-// types are identical. We consider them to be different because each type
-// instantiation creates a new named type, in this case T<int> and T<bool>
-// even if their underlying types are identical. This is sensible because
-// we might still have methods that have different signatures or behave
-// differently depending on the type arguments, and thus we can't possibly
-// consider such types identical. Consequently:
-func _() {
- xint = xbool // ERROR assignment
-}
-
-// Generic types cannot be used without instantiation.
-var _ T // ERROR cannot use generic type T
-var _ = T /* ERROR cannot use generic type T */ (0)
-
-// In type context, generic (parameterized) types cannot be parenthesized before
-// being instantiated. See also NOTES entry from 12/4/2019.
-var _ (T /* ERROR cannot use generic type T */ )[ /* ERROR unexpected \[|expected ';' */ int]
-
-// All types may be parameterized, including interfaces.
-type I1[T any] interface{
- m1(T)
-}
-
-// There is no such thing as a variadic generic type.
-type _[T ... /* ERROR invalid use of ... */ any] struct{}
-
-// Generic interfaces may be embedded as one would expect.
-type I2 interface {
- I1(int) // method!
- I1[string] // embedded I1
-}
-
-func _() {
- var x I2
- x.I1(0)
- x.m1("foo")
-}
-
-type I0 interface {
- m0()
-}
-
-type I3 interface {
- I0
- I1[bool]
- m(string)
-}
-
-func _() {
- var x I3
- x.m0()
- x.m1(true)
- x.m("foo")
-}
-
-type _ struct {
- ( /* ERROR cannot parenthesize */ int8)
- ( /* ERROR cannot parenthesize */ *int16)
- *( /* ERROR cannot parenthesize */ int32)
- List[int]
-
- int8 /* ERROR int8 redeclared */
- * /* ERROR int16 redeclared */ int16
- List /* ERROR List redeclared */ [int]
-}
-
-// Issue #45639: We don't allow this anymore. Keep this code
-// in case we decide to revisit this decision.
-//
-// It's possible to declare local types whose underlying types
-// are type parameters. As with ordinary type definitions, the
-// types underlying properties are "inherited" but the methods
-// are not.
-// func _[T interface{ m(); ~int }]() {
-// type L T
-// var x L
-//
-// // m is not defined on L (it is not "inherited" from
-// // its underlying type).
-// x.m /* ERROR x.m undefined */ ()
-//
-// // But the properties of T, such that as that it supports
-// // the operations of the types given by its type bound,
-// // are also the properties of L.
-// x++
-// _ = x - x
-//
-// // On the other hand, if we define a local alias for T,
-// // that alias stands for T as expected.
-// type A = T
-// var y A
-// y.m()
-// _ = y < 0
-// }
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// // It is not permitted to declare a local type whose underlying
-// // type is a type parameter not declared by that type declaration.
-// func _[T any]() {
-// type _ T // ERROR cannot use function type parameter T as RHS in type declaration
-// type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
-// }
-
-// As a special case, an explicit type argument may be omitted
-// from a type parameter bound if the type bound expects exactly
-// one type argument. In that case, the type argument is the
-// respective type parameter to which the type bound applies.
-// Note: We may not permit this syntactic sugar at first.
-// Note: This is now disabled. All examples below are adjusted.
-type Adder[T any] interface {
- Add(T) T
-}
-
-// We don't need to explicitly instantiate the Adder bound
-// if we have exactly one type parameter.
-func Sum[T Adder[T]](list []T) T {
- var sum T
- for _, x := range list {
- sum = sum.Add(x)
- }
- return sum
-}
-
-// Valid and invalid variations.
-type B0 any
-type B1[_ any] any
-type B2[_, _ any] any
-
-func _[T1 B0]() {}
-func _[T1 B1[T1]]() {}
-func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
-
-func _[T1, T2 B0]() {}
-func _[T1 B1[T1], T2 B1[T2]]() {}
-func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
-
-func _[T1 B0, T2 B1[T2]]() {} // here B1 applies to T2
-
-// When the type argument is left away, the type bound is
-// instantiated for each type parameter with that type
-// parameter.
-// Note: We may not permit this syntactic sugar at first.
-func _[A Adder[A], B Adder[B], C Adder[A]]() {
- var a A // A's type bound is Adder[A]
- a = a.Add(a)
- var b B // B's type bound is Adder[B]
- b = b.Add(b)
- var c C // C's type bound is Adder[A]
- a = c.Add(a)
-}
-
-// The type of variables (incl. parameters and return values) cannot
-// be an interface with type constraints or be/embed comparable.
-type I interface {
- ~int
-}
-
-var (
- _ interface /* ERROR contains type constraints */ {~int}
- _ I /* ERROR contains type constraints */
-)
-
-func _(I /* ERROR contains type constraints */ )
-func _(x, y, z I /* ERROR contains type constraints */ )
-func _() I /* ERROR contains type constraints */
-
-func _() {
- var _ I /* ERROR contains type constraints */
-}
-
-type C interface {
- comparable
-}
-
-var _ comparable /* ERROR comparable */
-var _ C /* ERROR comparable */
-
-func _(_ comparable /* ERROR comparable */ , _ C /* ERROR comparable */ )
-
-func _() {
- var _ comparable /* ERROR comparable */
- var _ C /* ERROR comparable */
-}
-
-// Type parameters are never const types, i.e., it's
-// not possible to declare a constant of type parameter type.
-// (If a type set contains just a single const type, we could
-// allow it, but such type sets don't make much sense in the
-// first place.)
-func _[T interface{~int|~float64}]() {
- // not valid
- const _ = T /* ERROR not constant */ (0)
- const _ T /* ERROR invalid constant type T */ = 1
-
- // valid
- var _ = T(0)
- var _ T = 1
- _ = T(0)
-}
-
-// It is possible to create composite literals of type parameter
-// type as long as it's possible to create a composite literal
-// of the core type of the type parameter's constraint.
-func _[P interface{ ~[]int }]() P {
- return P{}
- return P{1, 2, 3}
-}
-
-func _[P interface{ ~[]E }, E interface{ map[string]P } ]() P {
- x := P{}
- return P{{}}
- return P{E{}}
- return P{E{"foo": x}}
- return P{{"foo": x}, {}}
-}
-
-// This is a degenerate case with a singleton type set, but we can create
-// composite literals even if the core type is a defined type.
-type MyInts []int
-
-func _[P MyInts]() P {
- return P{}
-}
+++ /dev/null
-// 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.
-
-// This file shows some examples of constraint literals with elided interfaces.
-// These examples are permitted if proposal issue #48424 is accepted.
-
-package p
-
-// Constraint type sets of the form T, ~T, or A|B may omit the interface.
-type (
- _[T int] struct{}
- _[T ~int] struct{}
- _[T int | string] struct{}
- _[T ~int | ~string] struct{}
-)
-
-func min[T int | string](x, y T) T {
- if x < y {
- return x
- }
- return y
-}
-
-func lookup[M ~map[K]V, K comparable, V any](m M, k K) V {
- return m[k]
-}
-
-func deref[P ~*E, E any](p P) E {
- return *p
-}
-
-func _() int {
- p := new(int)
- return deref(p)
-}
-
-func addrOfCopy[V any, P *V](v V) P {
- return &v
-}
-
-func _() *int {
- return addrOfCopy(0)
-}
-
-// A type parameter may not be embedded in an interface;
-// so it can also not be used as a constraint.
-func _[A any, B A /* ERROR cannot use a type parameter as constraint */]() {}
-func _[A any, B, C A /* ERROR cannot use a type parameter as constraint */]() {}
-
-// Error messages refer to the type constraint as it appears in the source.
-// (No implicit interface should be exposed.)
-func _[T string](x T) T {
- return x /* ERROR constrained by string */ * x
-}
-
-func _[T int | string](x T) T {
- return x /* ERROR constrained by int|string */ * x
-}