Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls: bad completion candidate for variadic call where method returns slice #42691

Open
myitcv opened this issue Nov 18, 2020 · 3 comments
Open

Comments

@myitcv
Copy link
Member

@myitcv myitcv commented Nov 18, 2020

What version of Go are you using (go version)?

$ go version
go version devel +869e2957b9 Mon Nov 16 22:24:14 2020 +0000 linux/amd64
$ go list -m golang.org/x/tools
golang.org/x/tools v0.0.0-20201111213328-5794f8bd7a57
$ go list -m golang.org/x/tools/gopls
golang.org/x/tools/gopls v0.0.0-20201111213328-5794f8bd7a57

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/myitcv/.cache/go-build"
GOENV="/home/myitcv/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/myitcv/gostuff/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/myitcv/gostuff"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/myitcv/gos"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/myitcv/gos/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="devel +869e2957b9 Mon Nov 16 22:24:14 2020 +0000"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/myitcv/.vim/plugged/govim/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build353352024=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Consider:

package main

import (
	"fmt"
)

type S struct {
	vals []string
}

func (s S) Vals() []string {
	return s.vals
}

func X(vs ...string) {
	fmt.Println(vs)
}

func main() {
	var s S
	X(s._)
}

with the cursor at the _ position. Attempt completion and you get the following candidates:

&protocol.CompletionList{
    IsIncomplete: true,
    Items:        {
        {
            Label:            "vals",
            Kind:             5,
            Tags:             nil,
            Detail:           "[]string",
            Documentation:    "",
            Deprecated:       false,
            Preselect:        true,
            SortText:         "00000",
            FilterText:       "vals...",
            InsertText:       "",
            InsertTextFormat: 1,
            TextEdit:         &protocol.TextEdit{
                Range: protocol.Range{
                    Start: protocol.Position{Line:20, Character:5},
                    End:   protocol.Position{Line:20, Character:5},
                },
                NewText: "vals...",
            },
            AdditionalTextEdits: nil,
            CommitCharacters:    nil,
            Command:             (*protocol.Command)(nil),
            Data:                nil,
        },
        {
            Label:            "Vals",
            Kind:             2,
            Tags:             nil,
            Detail:           "func() []string",
            Documentation:    "",
            Deprecated:       false,
            Preselect:        false,
            SortText:         "00001",
            FilterText:       "Vals...",
            InsertText:       "",
            InsertTextFormat: 1,
            TextEdit:         &protocol.TextEdit{
                Range: protocol.Range{
                    Start: protocol.Position{Line:20, Character:5},
                    End:   protocol.Position{Line:20, Character:5},
                },
                NewText: "Vals...",
            },
            AdditionalTextEdits: nil,
            CommitCharacters:    nil,
            Command:             (*protocol.Command)(nil),
            Data:                nil,
        },
    },
}

Note that the new text for the Vals candidate is wrong: it applies the ... without the parentheses required to first call the method.

What did you expect to see?

The candidate Vals()...

What did you see instead?

As above.


cc @stamblerre @muirdm

FYI @leitzler

@muirdm
Copy link

@muirdm muirdm commented Nov 19, 2020

This is because the non-snippet insert text doesn't get the invocation () parens, but it does tack on the ....

It would be easy to fix the insert text to yield Vals()..., but the below behavior would also change:

func foo() []int {
  return nil
}
var _ []int = f<> // would complete to "foo()" instead of "foo"

Do non-snippet users want the invocation parens when the function takes no arguments?

@myitcv
Copy link
Member Author

@myitcv myitcv commented Nov 19, 2020

Thanks.

Do non-snippet users want the invocation parens when the function takes no arguments?

Would another option be to not add the ... when a call expression is involved?

@muirdm
Copy link

@muirdm muirdm commented Nov 19, 2020

Would another option be to not add the ... when a call expression is involved?

Yes, that is definitely an option too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.