gopls/completion: don't take address of interfaces for "%p" values When completing printf calls, we previously only preferred pointers and slices. This meant to make an interface object acceptable for "%p", we would take its address to turn it into a pointer. Change "%p" to also prefer interface types in addition to chan, map, and func, which all have pointer semantics. Note that interface types don't necessarily contain pointers, but they might, so tacking on "&" automatically is annoying. Fixes golang/go#65609 Change-Id: Idf2ba9cf27fa4ea8e721396cded5a7743d79807b Reviewed-on: https://go-review.googlesource.com/c/tools/+/593575 Reviewed-by: Robert Findley <rfindley@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Robert Findley <rfindley@google.com> Reviewed-by: Alan Donovan <adonovan@google.com>
diff --git a/gopls/internal/golang/completion/completion.go b/gopls/internal/golang/completion/completion.go index bdd1218..cc235ce 100644 --- a/gopls/internal/golang/completion/completion.go +++ b/gopls/internal/golang/completion/completion.go
@@ -2128,6 +2128,7 @@ kindBool kindBytes kindPtr + kindInterface kindFloat kindComplex kindError @@ -3270,6 +3271,8 @@ if _, isArray := t.Elem().Underlying().(*types.Array); isArray { kind |= kindArray } + case *types.Interface: + kind |= kindInterface case *types.Basic: switch info := t.Info(); { case info&types.IsString > 0:
diff --git a/gopls/internal/golang/completion/printf.go b/gopls/internal/golang/completion/printf.go index a7413bc..958d77e 100644 --- a/gopls/internal/golang/completion/printf.go +++ b/gopls/internal/golang/completion/printf.go
@@ -152,7 +152,9 @@ // Omit kindStringer and kindError though technically allowed. addVerb(kindString | kindBytes | kindInt | kindFloat | kindComplex) case 'p': - addVerb(kindPtr | kindSlice) + // Accept kindInterface even though it doesn't necessarily contain a pointer. + // This avoids us offering "&foo" when "foo" is an interface type. + addVerb(kindPtr | kindSlice | kindMap | kindFunc | kindInterface) case 'w': addVerb(kindError) case '+', '-', '#', ' ', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
diff --git a/gopls/internal/golang/completion/printf_test.go b/gopls/internal/golang/completion/printf_test.go index 19d295b..1a3d971 100644 --- a/gopls/internal/golang/completion/printf_test.go +++ b/gopls/internal/golang/completion/printf_test.go
@@ -41,7 +41,7 @@ {"%s", 1, kindString | kindBytes | kindStringer | kindError}, {"%x", 1, kindString | kindBytes | kindInt | kindFloat | kindComplex}, {"%X", 1, kindString | kindBytes | kindInt | kindFloat | kindComplex}, - {"%p", 1, kindPtr | kindSlice}, + {"%p", 1, kindPtr | kindSlice | kindMap | kindFunc | kindInterface}, {"%w", 1, kindError}, {"%1.2f", 1, kindFloat | kindComplex},
diff --git a/gopls/internal/test/marker/testdata/completion/printf.txt b/gopls/internal/test/marker/testdata/completion/printf.txt index 99b8a1e..270927e 100644 --- a/gopls/internal/test/marker/testdata/completion/printf.txt +++ b/gopls/internal/test/marker/testdata/completion/printf.txt
@@ -36,4 +36,7 @@ a, //@rank(",", printfInt, printfFloat) a, //@rank(",", printfFloat, printfInt) ) + + // Don't insert as "&aStringer" + fmt.Printf("%p", a) //@snippet(")", printfStringer, "aStringer") }