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>
This commit is contained in:
Rob Findley 2023-07-27 13:08:51 -04:00 коммит произвёл Robert Findley
Родитель bacac14996
Коммит 03562de254
3 изменённых файлов: 45 добавлений и 2 удалений

35
gopls/internal/regtest/marker/testdata/rename/issue61614.txt поставляемый Normal file
Просмотреть файл

@ -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{}
}

Просмотреть файл

@ -355,8 +355,7 @@ func (f *Finder) expr(e ast.Expr) types.Type {
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 {

Просмотреть файл

@ -57,6 +57,8 @@ type S struct{impl}
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 @@ func _() {
// 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 @@ func _() {
"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)