gopls version
golang.org/x/tools/gopls v0.23.0
go version go1.27.1 darwin/arm64
What did you do?
Two packages in one module, where b does not import a.
a/a.go:
package a
type Alpha [16]byte
type Beta interface{}
type Gamma struct{}
type Zeta func(int)
func New() Alpha { return Alpha{} }
const Delta = 1
var Epsilon = 2
b/b.go:
package b
func f() {
a.
}
Request textDocument/completion at the position after "a.".
What did you expect to see?
All seven exported symbols offered as unimported completions, each with an
auto-import edit. The doc comment at the top of
gopls/internal/golang/completion/unimported.go says as much:
A 'suitable completion' is an exported symbol (so a type, const, var,
or func) from package foo [...]
What did you see instead?
Five of the seven are offered. Driving gopls directly over stdio and printing
the label, detail and kind of every item returned:
gopls: golang.org/x/tools/gopls v0.23.0
items returned: 5
symbol offered detail kind
---------- --------- ------------------------------- ---------
Alpha no
Beta no
Gamma yes var (from "example.com/m/a") Variable
Zeta yes func (from "example.com/m/a") Function
New yes func (from "example.com/m/a") Function
Delta yes const (from "example.com/m/a") Constant
Epsilon yes var (from "example.com/m/a") Variable
Alpha and Beta are missing. Gamma is a type but is labelled "var" and sent as
VariableCompletion. Zeta is a type but is labelled "func". Every item that is
offered does carry a correct auto-import edit.
Note also that no type is ever sent with a type-like completion kind, so the
editor draws a variable icon beside an item whose detail text reads "type".
The icon changes once the import is added and the symbol starts coming from
the normal completion path, which uses ClassCompletion or
InterfaceCompletion.
Cause
pkgIDmatches in unimported.go handles only the Function, Variable, Struct and
Constant symbol kinds. cache/symbols gives a type declaration the Interface
kind for an interface, Struct for a struct, Function for a named func type,
and Class for anything else. Interface and Class have no case and so hit
"default: continue"; Struct shares a case with Variable and so is labelled
"var".
This is the workspace path only. stdlibMatches and modcacheMatches already
have a Type case producing "type (from ...)", so standard library and module
cache types are fine and only the user's own packages break.
I have a fix ready and will send it as a PR.
gopls version
golang.org/x/tools/gopls v0.23.0
go version go1.27.1 darwin/arm64
What did you do?
Two packages in one module, where b does not import a.
a/a.go:
b/b.go:
Request textDocument/completion at the position after "a.".
What did you expect to see?
All seven exported symbols offered as unimported completions, each with an
auto-import edit. The doc comment at the top of
gopls/internal/golang/completion/unimported.go says as much:
What did you see instead?
Five of the seven are offered. Driving gopls directly over stdio and printing
the label, detail and kind of every item returned:
Alpha and Beta are missing. Gamma is a type but is labelled "var" and sent as
VariableCompletion. Zeta is a type but is labelled "func". Every item that is
offered does carry a correct auto-import edit.
Note also that no type is ever sent with a type-like completion kind, so the
editor draws a variable icon beside an item whose detail text reads "type".
The icon changes once the import is added and the symbol starts coming from
the normal completion path, which uses ClassCompletion or
InterfaceCompletion.
Cause
pkgIDmatches in unimported.go handles only the Function, Variable, Struct and
Constant symbol kinds. cache/symbols gives a type declaration the Interface
kind for an interface, Struct for a struct, Function for a named func type,
and Class for anything else. Interface and Class have no case and so hit
"default: continue"; Struct shares a case with Variable and so is labelled
"var".
This is the workspace path only. stdlibMatches and modcacheMatches already
have a Type case producing "type (from ...)", so standard library and module
cache types are fine and only the user's own packages break.
I have a fix ready and will send it as a PR.