aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-08-17 11:45:05 -0700
committerRobert Griesemer <gri@golang.org>2021-08-17 20:57:49 +0000
commit9d9e3291faee4b01165247956e8555eb1bb291f1 (patch)
tree358e204f790dc3f2bd6d2be7ed1ce0655c82503f /src/cmd/compile/internal
parentcf12b0d1f96242eefbe64dbf449f30cce2756560 (diff)
downloadgo-9d9e3291faee4b01165247956e8555eb1bb291f1.tar.gz
go-9d9e3291faee4b01165247956e8555eb1bb291f1.zip
cmd/compile/internal/types2: fix method lookup for type-parameter based types
Pointers to type parameters don't have methods, but pointers to defined types whose underlying types are type parameters may have methods. Fix the respective test. For #47747. Change-Id: I1de47be094ed9297f0e7782538011657c37c5adc Reviewed-on: https://go-review.googlesource.com/c/go/+/342990 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal')
-rw-r--r--src/cmd/compile/internal/types2/lookup.go9
-rw-r--r--src/cmd/compile/internal/types2/testdata/fixedbugs/issue47747.go268
2 files changed, 74 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go
index 3779d17b3d..668c5ff3ec 100644
--- a/src/cmd/compile/internal/types2/lookup.go
+++ b/src/cmd/compile/internal/types2/lookup.go
@@ -74,9 +74,12 @@ func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o
typ, isPtr := deref(T)
// *typ where typ is an interface or type parameter has no methods.
- switch under(typ).(type) {
- case *Interface, *TypeParam:
- if isPtr {
+ if isPtr {
+ // don't look at under(typ) here - was bug (issue #47747)
+ if _, ok := typ.(*TypeParam); ok {
+ return
+ }
+ if _, ok := under(typ).(*Interface); ok {
return
}
}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47747.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47747.go2
new file mode 100644
index 0000000000..af52056bef
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47747.go2
@@ -0,0 +1,68 @@
+// 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.
+
+package p
+
+type T1[P any] P
+
+func (T1[_]) m() {}
+
+func _[P any](x *T1[P]) {
+ // x.m exists because x is of type *T1 where T1 is a defined type
+ // (even though under(T1) is a type parameter)
+ x.m()
+}
+
+
+func _[P interface{ m() }](x P) {
+ x.m()
+ // (&x).m doesn't exist because &x is of type *P
+ // and pointers to type parameters don't have methods
+ (&x).m /* ERROR \*P has no field or method m */ ()
+}
+
+
+type T2 interface{ m() }
+
+func _(x *T2) {
+ // x.m doesn't exists because x is of type *T2
+ // and pointers to interfaces don't have methods
+ x.m /* ERROR \*T2 has no field or method m */()
+}
+
+// Test case 1 from issue
+
+type Fooer1[t any] interface {
+ Foo(Barer[t])
+}
+type Barer[t any] interface {
+ Bar(t)
+}
+
+type Foo1[t any] t
+type Bar[t any] t
+
+func (l Foo1[t]) Foo(v Barer[t]) { v.Bar(t(l)) }
+func (b *Bar[t]) Bar(l t) { *b = Bar[t](l) }
+
+func _[t any](f Fooer1[t]) t {
+ var b Bar[t]
+ f.Foo(&b)
+ return t(b)
+}
+
+// Test case 2 from issue
+
+type Fooer2[t any] interface {
+ Foo()
+}
+
+type Foo2[t any] t
+
+func (f *Foo2[t]) Foo() {}
+
+func _[t any](v t) {
+ var f = Foo2[t](v)
+ _ = Fooer2[t](&f)
+}