internal/lsp/source: fix panic in formatZeroValue for invalid type
formatZeroValue is currently only used when formatting return values for
statement completion. Per golang/go#40956, it must be possible to hit
this codepath with an invalid type.
In this case, the empty string seems like a reasonable value. Perhaps we
could do better, but fix the panic for now.
Fixes golang/go#40956
Change-Id: I45b559d41001c857cef34aea2a5ac4a9096fe950
Reviewed-on: https://go-review.googlesource.com/c/tools/+/249818
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/internal/lsp/source/util.go b/internal/lsp/source/util.go
index a043a17..63bfd4e 100644
--- a/internal/lsp/source/util.go
+++ b/internal/lsp/source/util.go
@@ -582,7 +582,8 @@
return nil
}
-// formatZeroValue produces Go code representing the zero value of T.
+// formatZeroValue produces Go code representing the zero value of T. It
+// returns the empty string if T is invalid.
func formatZeroValue(T types.Type, qf types.Qualifier) string {
switch u := T.Underlying().(type) {
case *types.Basic:
@@ -594,7 +595,7 @@
case u.Info()&types.IsBoolean > 0:
return "false"
default:
- panic(fmt.Sprintf("unhandled basic type: %v", u))
+ return ""
}
case *types.Pointer, *types.Interface, *types.Chan, *types.Map, *types.Slice, *types.Signature:
return "nil"
diff --git a/internal/lsp/source/util_test.go b/internal/lsp/source/util_test.go
new file mode 100644
index 0000000..0dfa0b0
--- /dev/null
+++ b/internal/lsp/source/util_test.go
@@ -0,0 +1,28 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package source
+
+import (
+ "go/types"
+ "testing"
+)
+
+func TestFormatZeroValue(t *testing.T) {
+ tests := []struct {
+ typ types.Type
+ want string
+ }{
+ {types.Typ[types.String], `""`},
+ {types.Typ[types.Byte], "0"},
+ {types.Typ[types.Invalid], ""},
+ {types.Universe.Lookup("error").Type(), "nil"},
+ }
+
+ for _, test := range tests {
+ if got := formatZeroValue(test.typ, nil); got != test.want {
+ t.Errorf("formatZeroValue(%v) = %q, want %q", test.typ, got, test.want)
+ }
+ }
+}