Source file src/internal/types/testdata/examples/constraints.go
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 /* ERRORx `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 "term cannot be a type parameter" */ } ] struct{} 49 _[T interface{ ~T /* ERROR "type in term ~T cannot be a type parameter" */ } ] struct{} 50 _[T interface{ int|T /* ERROR "term cannot be 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