diff options
author | Dan Scales <danscales@google.com> | 2021-03-29 08:28:01 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-03-30 03:05:45 +0000 |
commit | eeadfa2d3810c252f86a88ddd282b48be5abc6df (patch) | |
tree | cbc38592e0a2dbad05d343271124278d028bcf95 /test/typeparam/typelist.go | |
parent | a95454b6f31a982f064d262987199fba19f085e9 (diff) | |
download | go-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.go | 64 |
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"] +} |