1 // Copyright 2021 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // This file shows some examples of generic constraint interfaces.
6
7 package p
8
9 type MyInt int
10
11 type (
12 // Arbitrary types may be embedded like interfaces.
13 _ interface{int}
14 _ interface{~int}
15
16 // Types may be combined into a union.
17 union interface{int|~string}
18
19 // Union terms must describe disjoint (non-overlapping) type sets.
20 _ interface{int|int /* ERROR overlapping terms int */ }
21 _ interface{int|~ /* ERROR overlapping terms ~int */ int }
22 _ interface{~int|~ /* ERROR overlapping terms ~int */ int }
23 _ interface{~int|MyInt /* ERROR overlapping terms p.MyInt and ~int */ }
24 _ interface{int|any}
25 _ interface{int|~string|union}
26 _ interface{int|~string|interface{int}}
27 _ interface{union|int} // interfaces (here: union) are ignored when checking for overlap
28 _ interface{union|union} // ditto
29
30 // For now we do not permit interfaces with methods in unions.
31 _ interface{~ /* ERROR invalid use of ~ */ any}
32 _ interface{int|interface /* ERROR cannot use .* in union */ { m() }}
33 )
34
35 type (
36 // Tilde is not permitted on defined types or interfaces.
37 foo int
38 bar any
39 _ interface{foo}
40 _ interface{~ /* ERROR invalid use of ~ */ foo }
41 _ interface{~ /* ERROR invalid use of ~ */ bar }
42 )
43
44 // Stand-alone type parameters are not permitted as elements or terms in unions.
45 type (
46 _[T interface{ *T } ] struct{} // ok
47 _[T interface{ int | *T } ] struct{} // ok
48 _[T interface{ T /* ERROR cannot embed a type parameter */ } ] struct{}
49 _[T interface{ ~T /* ERROR cannot embed a type parameter */ } ] struct{}
50 _[T interface{ int|T /* ERROR cannot embed a type parameter */ }] struct{}
51 )
52
53 // Multiple embedded union elements are intersected. The order in which they
54 // appear in the interface doesn't matter since intersection is a symmetric
55 // operation.
56
57 type myInt1 int
58 type myInt2 int
59
60 func _[T interface{ myInt1|myInt2; ~int }]() T { return T(0) }
61 func _[T interface{ ~int; myInt1|myInt2 }]() T { return T(0) }
62
63 // Here the intersections are empty - there's no type that's in the type set of T.
64 func _[T interface{ myInt1|myInt2; int }]() T { return T(0 /* ERROR cannot convert */ ) }
65 func _[T interface{ int; myInt1|myInt2 }]() T { return T(0 /* ERROR cannot convert */ ) }
66
67 // Union elements may be interfaces as long as they don't define
68 // any methods or embed comparable.
69
70 type (
71 Integer interface{ ~int|~int8|~int16|~int32|~int64 }
72 Unsigned interface{ ~uint|~uint8|~uint16|~uint32|~uint64 }
73 Floats interface{ ~float32|~float64 }
74 Complex interface{ ~complex64|~complex128 }
75 Number interface{ Integer|Unsigned|Floats|Complex }
76 Ordered interface{ Integer|Unsigned|Floats|~string }
77
78 _ interface{ Number | error /* ERROR cannot use error in union */ }
79 _ interface{ Ordered | comparable /* ERROR cannot use comparable in union */ }
80 )
81
View as plain text