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)