github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/types/testdata/examples/inference.go (about) 1 // -lang=go1.20 2 3 // Copyright 2021 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // This file shows some examples of type inference. 8 9 package p 10 11 type Ordered interface { 12 ~int | ~float64 | ~string 13 } 14 15 func min[T Ordered](x, y T) T { panic(0) } 16 17 func _() { 18 // min can be called with explicit instantiation. 19 _ = min[int](1, 2) 20 21 // Alternatively, the type argument can be inferred from 22 // one of the arguments. Untyped arguments will be considered 23 // last. 24 var x int 25 _ = min(x, x) 26 _ = min(x, 1) 27 _ = min(x, 1.0) 28 _ = min(1, 2) 29 _ = min(1, 2.3) 30 31 var y float64 32 _ = min(1, y) 33 _ = min(1.2, y) 34 _ = min(1.2, 3.4) 35 _ = min(1.2, 3) 36 37 var s string 38 _ = min(s, "foo") 39 _ = min("foo", "bar") 40 } 41 42 func mixed[T1, T2, T3 any](T1, T2, T3) {} 43 44 func _() { 45 // mixed can be called with explicit instantiation. 46 mixed[int, string, bool](0, "", false) 47 48 // Alternatively, partial type arguments may be provided 49 // (from left to right), and the other may be inferred. 50 mixed[int, string](0, "", false) 51 mixed[int](0, "", false) 52 mixed(0, "", false) 53 54 // Provided type arguments always take precedence over 55 // inferred types. 56 mixed[int, string](1.1 /* ERROR "cannot use 1.1" */, "", false) 57 } 58 59 func related1[Slice interface{ ~[]Elem }, Elem any](s Slice, e Elem) {} 60 61 func _() { 62 // related1 can be called with explicit instantiation. 63 var si []int 64 related1[[]int, int](si, 0) 65 66 // Alternatively, the 2nd type argument can be inferred 67 // from the first one through constraint type inference. 68 var ss []string 69 _ = related1[[]string] 70 related1[[]string](ss, "foo") 71 72 // A type argument inferred from another explicitly provided 73 // type argument overrides whatever value argument type is given. 74 related1[[]string](ss, 0 /* ERROR "cannot use 0" */) 75 76 // A type argument may be inferred from a value argument 77 // and then help infer another type argument via constraint 78 // type inference. 79 related1(si, 0) 80 related1(si, "foo" /* ERROR `cannot use "foo"` */) 81 } 82 83 func related2[Elem any, Slice interface{ []Elem }](e Elem, s Slice) {} 84 85 func _() { 86 // related2 can be called with explicit instantiation. 87 var si []int 88 related2[int, []int](0, si) 89 90 // Alternatively, the 2nd type argument can be inferred 91 // from the first one through constraint type inference. 92 var ss []string 93 _ = related2[string] 94 related2[string]("foo", ss) 95 96 // A type argument may be inferred from a value argument 97 // and then help infer another type argument via constraint 98 // type inference. Untyped arguments are always considered 99 // last. 100 related2(1.2, []float64{}) 101 related2(1.0, []int{}) 102 related2 /* ERROR "Slice (type []int) does not satisfy interface{[]Elem}" */ (float64(1.0), []int{}) // TODO(gri) better error message 103 } 104 105 type List[P any] []P 106 107 func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil } 108 109 func _() { 110 // related3 can be instantiated explicitly 111 related3[int, []int]() 112 related3[byte, List[byte]]() 113 114 // The 2nd type argument cannot be inferred from the first 115 // one because there's two possible choices: []Elem and 116 // List[Elem]. 117 related3 /* ERROR "cannot infer Slice" */ [int]() 118 } 119 120 func wantsMethods[P interface { 121 m1(Q) 122 m2() R 123 }, Q, R any](P) { 124 } 125 126 type hasMethods1 struct{} 127 128 func (hasMethods1) m1(int) 129 func (hasMethods1) m2() string 130 131 type hasMethods2 struct{} 132 133 func (*hasMethods2) m1(int) 134 func (*hasMethods2) m2() string 135 136 type hasMethods3 interface { 137 m1(float64) 138 m2() complex128 139 } 140 141 type hasMethods4 interface { 142 m1() 143 } 144 145 func _() { 146 // wantsMethod can be called with arguments that have the relevant methods 147 // and wantsMethod's type arguments are inferred from those types' method 148 // signatures. 149 wantsMethods(hasMethods1{}) 150 wantsMethods(&hasMethods1{}) 151 wantsMethods /* ERROR "P (type hasMethods2) does not satisfy interface{m1(Q); m2() R} (method m1 has pointer receiver)" */ (hasMethods2{}) 152 wantsMethods(&hasMethods2{}) 153 wantsMethods(hasMethods3(nil)) 154 wantsMethods /* ERROR "P (type any) does not satisfy interface{m1(Q); m2() R} (missing method m1)" */ (any(nil)) 155 wantsMethods /* ERROR "P (type hasMethods4) does not satisfy interface{m1(Q); m2() R} (wrong type for method m1)" */ (hasMethods4(nil)) 156 } 157 158 // "Reverse" type inference is not yet permitted. 159 160 func f[P any](P) {} 161 162 // This must not crash. 163 var _ func(int) = f // ERROR "implicitly instantiated function in assignment requires go1.21 or later"