aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/types2/testdata/check/tinference.go2
blob: 0afb77c1e41cfdbc5f6273fa8cf35cf4581a9823 (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
102
103
104
105
106
107
// Copyright 2020 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.

package tinferenceB

import "strconv"

type any interface{}

// Embedding stand-alone type parameters is not permitted for now. Disabled.
// func f0[A any, B interface{~C}, C interface{~D}, D interface{~A}](A, B, C, D)
// func _() {
// 	f := f0[string]
// 	f("a", "b", "c", "d")
// 	f0("a", "b", "c", "d")
// }
// 
// func f1[A any, B interface{~A}](A, B)
// func _() {
// 	f := f1[int]
// 	f(int(0), int(0))
// 	f1(int(0), int(0))
// }

func f2[A any, B interface{~[]A}](A, B) {}
func _() {
	f := f2[byte]
	f(byte(0), []byte{})
	f2(byte(0), []byte{})
}

// Embedding stand-alone type parameters is not permitted for now. Disabled.
// func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
// func _() {
// 	f := f3[int]
// 	var x int
// 	f(x, &x, &x)
// 	f3(x, &x, &x)
// }

func f4[A any, B interface{~[]C}, C interface{~*A}](A, B, C) {}
func _() {
	f := f4[int]
	var x int
	f(x, []*int{}, &x)
	f4(x, []*int{}, &x)
}

func f5[A interface{~struct{b B; c C}}, B any, C interface{~*B}](x B) A { panic(0) }
func _() {
	x := f5(1.2)
	var _ float64 = x.b
	var _ float64 = *x.c
}

func f6[A any, B interface{~struct{f []A}}](B) A { panic(0) }
func _() {
	x := f6(struct{f []string}{})
	var _ string = x
}

// TODO(gri) Need to flag invalid recursive constraints. At the
// moment these cause infinite recursions and stack overflow.
// func f7[A interface{type B}, B interface{~A}]()

// More realistic examples

func Double[S interface{ ~[]E }, E interface{ ~int | ~int8 | ~int16 | ~int32 | ~int64 }](s S) S {
	r := make(S, len(s))
	for i, v := range s {
		r[i] = v + v
	}
	return r
}

type MySlice []int

var _ = Double(MySlice{1})

// From the draft design.

type Setter[B any] interface {
	Set(string)
	~*B
}

func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
	result := make([]T, len(s))
	for i, v := range s {
		// The type of &result[i] is *T which is in the type list
		// of Setter2, so we can convert it to PT.
		p := PT(&result[i])
		// PT has a Set method.
		p.Set(v)
	}
	return result
}

type Settable int

func (p *Settable) Set(s string) {
	i, _ := strconv.Atoi(s) // real code should not ignore the error
	*p = Settable(i)
}

var _ = FromStrings[Settable]([]string{"1", "2"})