1 // Copyright 2020 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 package funcInference
6
7 import "strconv"
8
9 type any interface{}
10
11 func f0[A any, B interface{*C}, C interface{*D}, D interface{*A}](A, B, C, D) {}
12 func _() {
13 f := f0[string]
14 f("a", nil, nil, nil)
15 f0("a", nil, nil, nil)
16 }
17
18 func f1[A any, B interface{*A}](A, B) {}
19 func _() {
20 f := f1[int]
21 f(int(0), new(int))
22 f1(int(0), new(int))
23 }
24
25 func f2[A any, B interface{[]A}](A, B) {}
26 func _() {
27 f := f2[byte]
28 f(byte(0), []byte{})
29 f2(byte(0), []byte{})
30 }
31
32 // Embedding stand-alone type parameters is not permitted for now. Disabled.
33 // func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
34 // func _() {
35 // f := f3[int]
36 // var x int
37 // f(x, &x, &x)
38 // f3(x, &x, &x)
39 // }
40
41 func f4[A any, B interface{[]C}, C interface{*A}](A, B, C) {}
42 func _() {
43 f := f4[int]
44 var x int
45 f(x, []*int{}, &x)
46 f4(x, []*int{}, &x)
47 }
48
49 func f5[A interface{struct{b B; c C}}, B any, C interface{*B}](x B) A { panic(0) }
50 func _() {
51 x := f5(1.2)
52 var _ float64 = x.b
53 var _ float64 = *x.c
54 }
55
56 func f6[A any, B interface{~struct{f []A}}](B) A { panic(0) }
57 func _() {
58 x := f6(struct{f []string}{})
59 var _ string = x
60 }
61
62 func f7[A interface{*B}, B interface{~*A}]() {}
63
64 // More realistic examples
65
66 func Double[S interface{ ~[]E }, E interface{ ~int | ~int8 | ~int16 | ~int32 | ~int64 }](s S) S {
67 r := make(S, len(s))
68 for i, v := range s {
69 r[i] = v + v
70 }
71 return r
72 }
73
74 type MySlice []int
75
76 var _ = Double(MySlice{1})
77
78 // From the draft design.
79
80 type Setter[B any] interface {
81 Set(string)
82 *B
83 }
84
85 func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
86 result := make([]T, len(s))
87 for i, v := range s {
88 // The type of &result[i] is *T which is in the type list
89 // of Setter, so we can convert it to PT.
90 p := PT(&result[i])
91 // PT has a Set method.
92 p.Set(v)
93 }
94 return result
95 }
96
97 type Settable int
98
99 func (p *Settable) Set(s string) {
100 i, _ := strconv.Atoi(s) // real code should not ignore the error
101 *p = Settable(i)
102 }
103
104 var _ = FromStrings[Settable]([]string{"1", "2"})
105
View as plain text