blob: f04b76ca1a9812edf2237fc1aef2c647b960e9f2 [file] [log] [blame]
Dan Willemsenbc60c3c2021-12-15 01:09:00 -08001// 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
5package funcInference
6
7import "strconv"
8
9type any interface{}
10
11func f0[A any, B interface{~*C}, C interface{~*D}, D interface{~*A}](A, B, C, D) {}
12func _() {
13 f := f0[string]
14 f("a", nil, nil, nil)
15 f0("a", nil, nil, nil)
16}
17
18func f1[A any, B interface{~*A}](A, B) {}
19func _() {
20 f := f1[int]
21 f(int(0), new(int))
22 f1(int(0), new(int))
23}
24
25func f2[A any, B interface{~[]A}](A, B) {}
26func _() {
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
41func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C) {}
42func _() {
43 f := f4[int]
44 var x int
45 f(x, []*int{}, &x)
46 f4(x, []*int{}, &x)
47}
48
49func f5[A interface{~struct{b B; c C}}, B any, C interface{~*B}](x B) A { panic(0) }
50func _() {
51 x := f5(1.2)
52 var _ float64 = x.b
53 var _ float64 = *x.c
54}
55
56func f6[A any, B interface{~struct{f []A}}](B) A { panic(0) }
57func _() {
58 x := f6(struct{f []string}{})
59 var _ string = x
60}
61
62func f7[A interface{*B}, B interface{~*A}]() {}
63
64// More realistic examples
65
66func 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
74type MySlice []int
75
76var _ = Double(MySlice{1})
77
78// From the draft design.
79
80type Setter[B any] interface {
81 Set(string)
82 ~*B
83}
84
85func 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
97type Settable int
98
99func (p *Settable) Set(s string) {
100 i, _ := strconv.Atoi(s) // real code should not ignore the error
101 *p = Settable(i)
102}
103
104var _ = FromStrings[Settable]([]string{"1", "2"})