aboutsummaryrefslogtreecommitdiff
path: root/test/typeparam/typelist.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-03-29 08:28:01 -0700
committerDan Scales <danscales@google.com>2021-03-30 03:05:45 +0000
commiteeadfa2d3810c252f86a88ddd282b48be5abc6df (patch)
treecbc38592e0a2dbad05d343271124278d028bcf95 /test/typeparam/typelist.go
parenta95454b6f31a982f064d262987199fba19f085e9 (diff)
downloadgo-eeadfa2d3810c252f86a88ddd282b48be5abc6df.tar.gz
go-eeadfa2d3810c252f86a88ddd282b48be5abc6df.zip
cmd/compile: fix various small bugs related to type lists
Fix various small bugs related to delaying transformations due to type params. Most of these relate to the need to delay a transformation when an argument of an expression or statement has a type parameter that has a structural constraint. The structural constraint implies the operation should work, but the transformation can't happen until the actual value of the type parameter is known. - delay transformations for send statements and return statements if any args/values have type params. - similarly, delay transformation of a call where the function arg has type parameters. This is mainly important for the case where the function arg is a pure type parameter, but has a structural constraint that requires it to be a function. Move the setting of n.Use to transformCall(), since we may not know how many return values there are until then, if the function arg is a type parameter. - set the type of unary expressions from the type2 type (as we do with most other expressions), since that works better with expressions with type params. - deal with these delayed transformations in subster.node() and convert the CALL checks to a switch statement. - make sure ir.CurFunc is set properly during stenciling, including closures (needed for transforming return statements during stenciling). New test file typelist.go with tests for these cases. Change-Id: I1b82f949d8cec47d906429209e846f4ebc8ec85e Reviewed-on: https://go-review.googlesource.com/c/go/+/305729 Trust: Dan Scales <danscales@google.com> Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'test/typeparam/typelist.go')
-rw-r--r--test/typeparam/typelist.go64
1 files changed, 64 insertions, 0 deletions
diff --git a/test/typeparam/typelist.go b/test/typeparam/typelist.go
new file mode 100644
index 0000000000..4ff3ce2f34
--- /dev/null
+++ b/test/typeparam/typelist.go
@@ -0,0 +1,64 @@
+// compile -G=3
+
+// 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 tests type lists & structural constraints.
+
+package p
+
+// Assignability of an unnamed pointer type to a type parameter that
+// has a matching underlying type.
+func _[T interface{}, PT interface{type *T}] (x T) PT {
+ return &x
+}
+
+// Indexing of generic types containing type parameters in their type list:
+func at[T interface{ type []E }, E any](x T, i int) E {
+ return x[i]
+}
+
+// A generic type inside a function acts like a named type. Its underlying
+// type is itself, its "operational type" is defined by the type list in
+// the tybe bound, if any.
+func _[T interface{type int}](x T) {
+ type myint int
+ var _ int = int(x)
+ var _ T = 42
+ var _ T = T(myint(42))
+}
+
+// Indexing a generic type which has a structural contraints to be an array.
+func _[T interface { type [10]int }](x T) {
+ _ = x[9] // ok
+}
+
+// Dereference of a generic type which has a structural contraint to be a pointer.
+func _[T interface{ type *int }](p T) int {
+ return *p
+}
+
+// Channel send and receive on a generic type which has a structural constraint to
+// be a channel.
+func _[T interface{ type chan int }](ch T) int {
+ // This would deadlock if executed (but ok for a compile test)
+ ch <- 0
+ return <- ch
+}
+
+// Calling of a generic type which has a structural constraint to be a function.
+func _[T interface{ type func() }](f T) {
+ f()
+ go f()
+}
+
+// Same, but function has a parameter and return value.
+func _[T interface{ type func(string) int }](f T) int {
+ return f("hello")
+}
+
+// Map access of a generic type which has a structural constraint to be a map.
+func _[V any, T interface { type map[string]V }](p T) V {
+ return p["test"]
+}