--- /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 {
+ type int, float64, string
+}
+
+func min[T Ordered](x, y T) T
+
+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{type []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{type []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 satisfy */ float64(1.0), []int{}) // TODO(gri) fix error position
+}