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  

View as plain text