aboutsummaryrefslogtreecommitdiff
path: root/test/typeparam/settable.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-03-09 18:24:51 -0800
committerDan Scales <danscales@google.com>2021-03-11 00:31:14 +0000
commitfdded79e6e3256118af182b42714d4d56f2000b0 (patch)
treef7014aedc7e02bd11a8770e3f2b916b86ffb10f6 /test/typeparam/settable.go
parent1bad3831a0afe76d3403f564e89be6b76f8c6d98 (diff)
downloadgo-fdded79e6e3256118af182b42714d4d56f2000b0.tar.gz
go-fdded79e6e3256118af182b42714d4d56f2000b0.zip
cmd/compile: fix handling of partially inferred type arguments
In the case of partially inferred type arguments, we need to use the IndexExpr as the key in g.info.Inferred[] rather than the CallExpr. Added an extra fromStrings1 call in the settable.go test that tests partially inferred type arguments. This new call uses a new concrete type SettableString as well. I also added another implementation fromStrings3 (derived from a go2go tests) that typechecks but intentionally causes a panic. Change-Id: I74d35c5a741f72f37160a96fbec939451157f392 Reviewed-on: https://go-review.googlesource.com/c/go/+/300309 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Dan Scales <danscales@google.com> Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
Diffstat (limited to 'test/typeparam/settable.go')
-rw-r--r--test/typeparam/settable.go55
1 files changed, 50 insertions, 5 deletions
diff --git a/test/typeparam/settable.go b/test/typeparam/settable.go
index f42c6574fe..29874fb189 100644
--- a/test/typeparam/settable.go
+++ b/test/typeparam/settable.go
@@ -11,11 +11,14 @@ import (
"strconv"
)
+// Various implementations of fromStrings().
+
type _Setter[B any] interface {
Set(string)
type *B
}
+// Takes two type parameters where PT = *T
func fromStrings1[T any, PT _Setter[T]](s []string) []T {
result := make([]T, len(s))
for i, v := range s {
@@ -28,6 +31,7 @@ func fromStrings1[T any, PT _Setter[T]](s []string) []T {
return result
}
+// Takes one type parameter and a set function
func fromStrings2[T any](s []string, set func(*T, string)) []T {
results := make([]T, len(s))
for i, v := range s {
@@ -36,24 +40,65 @@ func fromStrings2[T any](s []string, set func(*T, string)) []T {
return results
}
-type Settable int
+type _Setter2 interface {
+ Set(string)
+}
+
+// Takes only one type parameter, but causes a panic (see below)
+func fromStrings3[T _Setter2](s []string) []T {
+ results := make([]T, len(s))
+ for i, v := range s {
+ // Panics if T is a pointer type because receiver is T(nil).
+ results[i].Set(v)
+ }
+ return results
+}
+
+// Two concrete types with the appropriate Set method.
+
+type SettableInt int
-func (p *Settable) Set(s string) {
+func (p *SettableInt) Set(s string) {
i, err := strconv.Atoi(s)
if err != nil {
panic(err)
}
- *p = Settable(i)
+ *p = SettableInt(i)
+}
+
+type SettableString struct {
+ s string
+}
+
+func (x *SettableString) Set(s string) {
+ x.s = s
}
func main() {
- s := fromStrings1[Settable, *Settable]([]string{"1"})
+ s := fromStrings1[SettableInt, *SettableInt]([]string{"1"})
if len(s) != 1 || s[0] != 1 {
panic(fmt.Sprintf("got %v, want %v", s, []int{1}))
}
- s = fromStrings2([]string{"1"}, func(p *Settable, s string) { p.Set(s) })
+ // Test out constraint type inference, which should determine that the second
+ // type param is *SettableString.
+ ps := fromStrings1[SettableString]([]string{"x", "y"})
+ if len(ps) != 2 || ps[0] != (SettableString{"x"}) || ps[1] != (SettableString{"y"}) {
+ panic(s)
+ }
+
+ s = fromStrings2([]string{"1"}, func(p *SettableInt, s string) { p.Set(s) })
if len(s) != 1 || s[0] != 1 {
panic(fmt.Sprintf("got %v, want %v", s, []int{1}))
}
+
+ defer func() {
+ if recover() == nil {
+ panic("did not panic as expected")
+ }
+ }()
+ // This should type check but should panic at run time,
+ // because it will make a slice of *SettableInt and then call
+ // Set on a nil value.
+ fromStrings3[*SettableInt]([]string{"1"})
}