1// compile -G=3
2
3// Copyright 2021 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// This file tests type lists & structural constraints.
8
9// Note: This test has been adjusted to use the new
10//       type set notation rather than type lists.
11
12package p
13
14// Assignability of an unnamed pointer type to a type parameter that
15// has a matching underlying type.
16func _[T interface{}, PT interface{ ~*T }](x T) PT {
17	return &x
18}
19
20// Indexing of generic types containing type parameters in their type list:
21func at[T interface{ ~[]E }, E any](x T, i int) E {
22	return x[i]
23}
24
25// A generic type inside a function acts like a named type. Its underlying
26// type is itself, its "operational type" is defined by the type list in
27// the tybe bound, if any.
28func _[T interface{ ~int }](x T) {
29	var _ int = int(x)
30	var _ T = 42
31	var _ T = T(myint(42))
32}
33// TODO: put this type declaration back inside the above function when issue 47631 is fixed.
34type myint int
35
36// Indexing a generic type which has a structural contraints to be an array.
37func _[T interface{ ~[10]int }](x T) {
38	_ = x[9] // ok
39}
40
41// Dereference of a generic type which has a structural contraint to be a pointer.
42func _[T interface{ ~*int }](p T) int {
43	return *p
44}
45
46// Channel send and receive on a generic type which has a structural constraint to
47// be a channel.
48func _[T interface{ ~chan int }](ch T) int {
49	// This would deadlock if executed (but ok for a compile test)
50	ch <- 0
51	return <-ch
52}
53
54// Calling of a generic type which has a structural constraint to be a function.
55func _[T interface{ ~func() }](f T) {
56	f()
57	go f()
58}
59
60// Same, but function has a parameter and return value.
61func _[T interface{ ~func(string) int }](f T) int {
62	return f("hello")
63}
64
65// Map access of a generic type which has a structural constraint to be a map.
66func _[V any, T interface{ ~map[string]V }](p T) V {
67	return p["test"]
68}
69
70// Testing partial and full type inference, including the case where the types can
71// be inferred without needing the types of the function arguments.
72
73// Cannot embed stand-alone type parameters. Disabled for now.
74/*
75func f0[A any, B interface{type C}, C interface{type D}, D interface{type A}](A, B, C, D)
76func f0x() {
77        f := f0[string]
78        f("a", "b", "c", "d")
79        f0("a", "b", "c", "d")
80}
81
82func f1[A any, B interface{type A}](A, B)
83func f1x() {
84        f := f1[int]
85        f(int(0), int(0))
86        f1(int(0), int(0))
87        f(0, 0)
88        f1(0, 0)
89}
90*/
91
92func f2[A any, B interface{ ~[]A }](_ A, _ B) {}
93func f2x() {
94	f := f2[byte]
95	f(byte(0), []byte{})
96	f2(byte(0), []byte{})
97	f(0, []byte{})
98	// f2(0, []byte{}) - this one doesn't work
99}
100
101// Cannot embed stand-alone type parameters. Disabled for now.
102/*
103func f3[A any, B interface{type C}, C interface{type *A}](a A, _ B, c C)
104func f3x() {
105	f := f3[int]
106	var x int
107	f(x, &x, &x)
108	f3(x, &x, &x)
109}
110*/
111
112func f4[A any, B interface{ ~[]C }, C interface{ ~*A }](_ A, _ B, c C) {}
113func f4x() {
114	f := f4[int]
115	var x int
116	f(x, []*int{}, &x)
117	f4(x, []*int{}, &x)
118}
119
120func f5[A interface {
121	~struct {
122		b B
123		c C
124	}
125}, B any, C interface{ ~*B }](x B) A { panic(0) }
126func f5x() {
127	x := f5(1.2)
128	var _ float64 = x.b
129	var _ float64 = *x.c
130}
131
132func f6[A any, B interface{ ~struct{ f []A } }](B) A { panic(0) }
133func f6x() {
134	x := f6(struct{ f []string }{})
135	var _ string = x
136}
137