aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/testdata/examples/inference.go2
blob: e169aec74660bad3c4c3719ac8d07d2fe37e0872 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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 {
	~int|~float64|~string
}

func min[T Ordered](x, y T) T { panic(0) }

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{~[]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{~[]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
}