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: panic in deslice when completing unknown type in append #38091

Closed
chlunde opened this issue Mar 26, 2020 · 2 comments
Closed

x/tools/gopls: panic in deslice when completing unknown type in append #38091

chlunde opened this issue Mar 26, 2020 · 2 comments

Comments

@chlunde
Copy link
Contributor

@chlunde chlunde commented Mar 26, 2020

What did you do?

Type t in struct in an append variadic arg for a slice with a type now yet defined.

package bad

func _() {
       a := unknown
       a = append(a, struct) //@complete(")")
}

What did you expect to see?

Not much

What did you see instead?

Crash

Stack trace
panic: runtime error: invalid memory address or nil pointer dereference                                                                                                                                                                        
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x79e7db]                                                                                                                                                                        

goroutine 10025 [running]:
golang.org/x/tools/internal/lsp/source.deslice(...)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/source/util.go:429
golang.org/x/tools/internal/lsp/source.(*completer).builtinArgType(0xc0086f0600, 0xe25040, 0xc000100cd0, 0xc0071bc240, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/source/completion_builtin.go:70 +0x3bb
golang.org/x/tools/internal/lsp/source.expectedCandidate.func1(0xc0086f0600, 0xe25040, 0xc000100cd0, 0xc0071bc240, 0xc01032c160)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/source/completion.go:1481 +0xd1
golang.org/x/tools/internal/lsp/source.expectedCandidate(0xc0086f0600, 0xc00025b4b0, 0xc010ae66c0, 0xc0000c5300, 0x116f, 0x1300, 0xb9e2e2, 0x52, 0xc0101eb990, 0x6, ...)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/source/completion.go:1565 +0x3c7
golang.org/x/tools/internal/lsp/source.Completion(0xe12e60, 0xc010ae66c0, 0xe24f00, 0xc012cc2120, 0xe11560, 0xc012cc20c0, 0x4065a00000000000, 0x4045000000000000, 0x0, 0x0, ...)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/source/completion.go:517 +0x9eb
golang.org/x/tools/internal/lsp.(*Server).completion(0xc0002e6680, 0xe12e60, 0xc010b00450, 0xc010536060, 0x0, 0x0, 0xc01032c000)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/completion.go:27 +0x6b0
golang.org/x/tools/internal/lsp.(*Server).Completion(0xc0002e6680, 0xe12e60, 0xc010b00450, 0xc010536060, 0xc010536060, 0x0, 0x0)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/server_gen.go:24 +0x49
golang.org/x/tools/internal/lsp/protocol.serverHandler.Deliver(0xe2d340, 0xc0002e6680, 0xe12e60, 0xc010b00450, 0xc010a7e1c0, 0xae8c00, 0xe10000)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/lsp/protocol/tsserver.go:345 +0x2064
golang.org/x/tools/internal/jsonrpc2.(*Conn).Run.func1(0xc0075ec4e0, 0xc010a7e1c0, 0xc0002eaba0, 0xe12e60, 0xc010b00450, 0x0, 0x0, 0xc0071500f0)
/home/chlunde/opt/gotoolpath/pkg/mod/golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a/internal/jsonrpc2/jsonrpc2.go:372 +0x160
created by golang.org/x/tools/internal/jsonrpc2.(*Conn).Run

Build info

gopls v0.3.4
golang.org/x/tools/gopls v0.3.4
    golang.org/x/tools/gopls@v0.3.4 h1:4GC7q/pXQ/tsxHBGVdsMdlB4gCxVC06m/7rIXg1Px4E=
    github.com/BurntSushi/toml@v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
    github.com/sergi/go-diff@v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
    golang.org/x/mod@v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
    golang.org/x/sync@v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
    golang.org/x/tools@v0.0.0-20200316194252-fafb6e2e8a4a h1:hKrQy/q8/Xivoqgw6nGiz1jqpn1WGBLDcWLZwW0983E=
    golang.org/x/xerrors@v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
    honnef.co/go/tools@v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
    mvdan.cc/xurls/v2@v2.1.0 h1:KaMb5GLhlcSX+e+qhbRJODnUUBvlw01jt4yrjFIHAuA=

Hack/patch

Not sure if this is the right approach ¯\(ツ)

diff --git a/internal/lsp/testdata/lsp/primarymod/bad/bad2.go b/internal/lsp/testdata/lsp/primarymod/bad/bad2.go
new file mode 100644
index 00000000..acce3e45
--- /dev/null
+++ b/internal/lsp/testdata/lsp/primarymod/bad/bad2.go
@@ -0,0 +1,6 @@
+package bad
+
+func _() {
+       a := unknown
+       a = append(a, struct) //@complete(")")
+}
diff --git a/internal/lsp/testdata/lsp/summary.txt.golden b/internal/lsp/testdata/lsp/summary.txt.golden
index c4e7d68d..ece318e5 100644
--- a/internal/lsp/testdata/lsp/summary.txt.golden
+++ b/internal/lsp/testdata/lsp/summary.txt.golden
@@ -1,6 +1,6 @@
 -- summary --
 CodeLensCount = 2
-CompletionsCount = 237
+CompletionsCount = 238
 CompletionSnippetCount = 75
 UnimportedCompletionsCount = 11
 DeepCompletionsCount = 5
diff --git a/internal/lsp/source/completion_builtin.go b/internal/lsp/source/completion_builtin.go
index d65eb8f4..26c553f0 100644
--- a/internal/lsp/source/completion_builtin.go
+++ b/internal/lsp/source/completion_builtin.go
@@ -64,7 +64,7 @@ func (c *completer) builtinArgType(obj types.Object, call *ast.CallExpr, parentI
                // Check if we are completing the variadic append() param.
                if exprIdx == 1 && len(call.Args) <= 2 {
                        inf.variadicType = deslice(inf.objType)
-               } else if exprIdx > 0 {
+               } else if exprIdx > 0 && inf.objType != nil {
                        // If we are completing an individual element of the variadic
                        // param, "deslice" the expected type.
                        inf.objType = deslice(inf.objType)
@gopherbot gopherbot added this to the Unreleased milestone Mar 26, 2020
@stamblerre
Copy link
Contributor

@stamblerre stamblerre commented Mar 26, 2020

Thanks for the report! The patch you proposed above sounds reasonable to me - please send us a PR if you're interested in contributing :)

/cc @muirdm

@gopherbot
Copy link

@gopherbot gopherbot commented Apr 2, 2020

Change https://golang.org/cl/227026 mentions this issue: internal/lsp: fix panic in builtin completions

@golang golang locked and limited conversation to collaborators Apr 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants