refactor/satisfy/find: composite lits may have type parameter type
Fix an oversight in the satisfaction check: composite lits may indeed
have type parameter type, and therefore we must consider their core
type.
Fixes golang/go#61614
Change-Id: I2119ba308816d02742d8e790f8cd00c4d862e789
Reviewed-on: https://go-review.googlesource.com/c/tools/+/513775
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/regtest/marker/testdata/rename/issue61614.txt b/gopls/internal/regtest/marker/testdata/rename/issue61614.txt
new file mode 100644
index 0000000..cfb37b1
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/rename/issue61614.txt
@@ -0,0 +1,35 @@
+This test renames a method of a type in a package that uses type parameter
+composite lits. Previous iterations of the satisfy analysis did not account for
+this language feature.
+
+See issue #60789.
+
+-- flags --
+-min_go=go1.18
+
+-- go.mod --
+module example.com
+go 1.20
+
+-- a.go --
+package a
+
+type I int
+
+func (I) m() {} //@rename("m", M, mToM)
+
+func _[P ~[]int]() {
+ _ = P{}
+}
+
+-- @mToM/a.go --
+package a
+
+type I int
+
+func (I) M() {} //@rename("m", M, mToM)
+
+func _[P ~[]int]() {
+ _ = P{}
+}
+
diff --git a/refactor/satisfy/find.go b/refactor/satisfy/find.go
index 6b4d528..47dc97e 100644
--- a/refactor/satisfy/find.go
+++ b/refactor/satisfy/find.go
@@ -355,8 +355,7 @@
f.sig = saved
case *ast.CompositeLit:
- // No need for coreType here: go1.18 disallows P{...} for type param P.
- switch T := deref(tv.Type).Underlying().(type) {
+ switch T := coreType(tv.Type).(type) {
case *types.Struct:
for i, elem := range e.Elts {
if kv, ok := elem.(*ast.KeyValueExpr); ok {
diff --git a/refactor/satisfy/find_test.go b/refactor/satisfy/find_test.go
index 35a1e87..2cbd8c1 100644
--- a/refactor/satisfy/find_test.go
+++ b/refactor/satisfy/find_test.go
@@ -57,6 +57,8 @@
type T struct{impl}
type U struct{impl}
type V struct{impl}
+type W struct{impl}
+type X struct{impl}
type Generic[T any] struct{impl}
func (Generic[T]) g(T) {}
@@ -164,6 +166,11 @@
// golang/go#56227: the finder should visit calls in the unsafe package.
_ = unsafe.Slice(&x[0], func() int { var _ I = x[0]; return 3 }()) // I <- V
}
+
+func _[P ~struct{F I}]() {
+ _ = P{W{}}
+ _ = P{F: X{}}
+}
`
got := constraints(t, src)
want := []string{
@@ -194,6 +201,8 @@
"p.I <- p.T",
"p.I <- p.U",
"p.I <- p.V",
+ "p.I <- p.W",
+ "p.I <- p.X",
}
if !reflect.DeepEqual(got, want) {
t.Fatalf("found unexpected constraints: got %s, want %s", got, want)