Skip to content

Commit 4e080d1

Browse files
committed
gopls/internal/lsp/source: fix panic on T(x) conversion
Fixes golang/go#63804 Change-Id: I027580c32ac41d4c70a5643a3bc2837bbac7a58a Reviewed-on: https://go-review.googlesource.com/c/tools/+/542057 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Alan Donovan <[email protected]>
1 parent 9d19bff commit 4e080d1

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

gopls/internal/lsp/regtest/marker.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,9 @@ func tokenMarker(mark marker, loc protocol.Location, tokenType, mod string) {
19311931
func signatureMarker(mark marker, src protocol.Location, label string, active int64) {
19321932
got := mark.run.env.SignatureHelp(src)
19331933
if label == "" {
1934+
// A null result is expected.
1935+
// (There's no point having a @signatureerr marker
1936+
// because the server handler suppresses all errors.)
19341937
if got != nil && len(got.Signatures) > 0 {
19351938
mark.errorf("signatureHelp = %v, want 0 signatures", got)
19361939
}

gopls/internal/lsp/source/signature_help.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,27 +62,40 @@ FindCall:
6262
return nil, 0, fmt.Errorf("cannot find an enclosing function")
6363
}
6464

65-
qf := Qualifier(pgf.File, pkg.GetTypes(), pkg.GetTypesInfo())
65+
info := pkg.GetTypesInfo()
66+
67+
// Get the type information for the function being called.
68+
var sig *types.Signature
69+
if tv, ok := info.Types[callExpr.Fun]; !ok {
70+
return nil, 0, fmt.Errorf("cannot get type for Fun %[1]T (%[1]v)", callExpr.Fun)
71+
} else if tv.IsType() {
72+
return nil, 0, fmt.Errorf("this is a conversion to %s, not a call", tv.Type)
73+
} else if sig, ok = tv.Type.Underlying().(*types.Signature); !ok {
74+
return nil, 0, fmt.Errorf("cannot find signature for Fun %[1]T (%[1]v)", callExpr.Fun)
75+
}
76+
// Inv: sig != nil
77+
78+
qf := Qualifier(pgf.File, pkg.GetTypes(), info)
6679

6780
// Get the object representing the function, if available.
6881
// There is no object in certain cases such as calling a function returned by
6982
// a function (e.g. "foo()()").
7083
var obj types.Object
7184
switch t := callExpr.Fun.(type) {
7285
case *ast.Ident:
73-
obj = pkg.GetTypesInfo().ObjectOf(t)
86+
obj = info.ObjectOf(t)
7487
case *ast.SelectorExpr:
75-
obj = pkg.GetTypesInfo().ObjectOf(t.Sel)
88+
obj = info.ObjectOf(t.Sel)
7689
}
7790

78-
// Built-in?
91+
// Call to built-in?
7992
if obj != nil && !obj.Pos().IsValid() {
80-
// built-in function?
93+
// function?
8194
if obj, ok := obj.(*types.Builtin); ok {
8295
return builtinSignature(ctx, snapshot, callExpr, obj.Name(), pos)
8396
}
8497

85-
// error.Error?
98+
// method (only error.Error)?
8699
if fn, ok := obj.(*types.Func); ok && fn.Name() == "Error" {
87100
return &protocol.SignatureInformation{
88101
Label: "Error()",
@@ -93,17 +106,6 @@ FindCall:
93106
return nil, 0, bug.Errorf("call to unexpected built-in %v (%T)", obj, obj)
94107
}
95108

96-
// Get the type information for the function being called.
97-
sigType := pkg.GetTypesInfo().TypeOf(callExpr.Fun)
98-
if sigType == nil {
99-
return nil, 0, fmt.Errorf("cannot get type for Fun %[1]T (%[1]v)", callExpr.Fun)
100-
}
101-
102-
sig, _ := sigType.Underlying().(*types.Signature)
103-
if sig == nil {
104-
return nil, 0, fmt.Errorf("cannot find signature for Fun %[1]T (%[1]v)", callExpr.Fun)
105-
}
106-
107109
activeParam := activeParameter(callExpr, sig.Params().Len(), sig.Variadic(), pos)
108110

109111
var (
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Regresson test for #63804: conversion to built-in type caused panic.
2+
3+
the server's Signature method never returns an actual error,
4+
so the best we can assert is that there is no result.
5+
6+
-- go.mod --
7+
module testdata
8+
go 1.18
9+
10+
-- a/a.go --
11+
package a
12+
13+
var _ = int(123) //@signature("123", "", 0)

0 commit comments

Comments
 (0)