Skip to content

Commit 8e231bc

Browse files
committed
gopls/internal: check for variadic arguments from string to []byte/[]rune
gopls will correctly convert a string argument to a []byte/[]rune argument, however it will not check if the the target is also variadic.
1 parent 0734f62 commit 8e231bc

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

gopls/internal/golang/completion/completion.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ import (
5252

5353
// A CompletionItem represents a possible completion suggested by the algorithm.
5454
type CompletionItem struct {
55-
5655
// Invariant: CompletionItem does not refer to syntax or types.
5756

5857
// Label is the primary text the user sees for this completion item.
@@ -2965,6 +2964,13 @@ func (ci *candidateInference) candTypeMatches(cand *candidate) bool {
29652964
// If candType doesn't otherwise match, consider if we can
29662965
// convert candType directly to expType.
29672966
if considerTypeConversion(candType, expType, cand.path) {
2967+
// special case: a string to a variadic []byte/[]rune
2968+
typ := deslice(expType)
2969+
isBytesOrRunes := typ != nil && (isBasicKind(typ, types.Byte) || isBasicKind(typ, types.Rune))
2970+
if isBasicType(candType, types.IsString) && isBytesOrRunes && expType == variadicType {
2971+
cand.mods = append(cand.mods, takeDotDotDot)
2972+
}
2973+
29682974
cand.convertTo = expType
29692975
// Give a major score penalty so we always prefer directly
29702976
// assignable candidates, all else equal.
@@ -3045,7 +3051,7 @@ func considerTypeConversion(from, to types.Type, path []types.Object) bool {
30453051

30463052
// Don't offer to convert ints to strings since that probably
30473053
// doesn't do what the user wants.
3048-
if isBasicKind(from, types.IsInteger) && isBasicKind(to, types.IsString) {
3054+
if isBasicType(from, types.IsInteger) && isBasicType(to, types.IsString) {
30493055
return false
30503056
}
30513057

gopls/internal/golang/completion/format.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ Suffixes:
182182
// add the additional text edits needed.
183183
if cand.imp != nil {
184184
addlEdits, err := c.importEdits(cand.imp)
185-
186185
if err != nil {
187186
return CompletionItem{}, err
188187
}
@@ -214,7 +213,7 @@ Suffixes:
214213
}
215214

216215
prefix = typeName + "(" + prefix
217-
suffix = ")"
216+
suffix = ")" + suffix
218217
}
219218

220219
if prefix != "" {

gopls/internal/golang/completion/util.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,15 @@ func formatZeroValue(T types.Type, qf types.Qualifier) string {
300300
}
301301
}
302302

303-
// isBasicKind returns whether t is a basic type of kind k.
304-
func isBasicKind(t types.Type, k types.BasicInfo) bool {
303+
// isBasicType returns whether t has property information i.
304+
func isBasicType(t types.Type, i types.BasicInfo) bool {
305305
b, _ := t.Underlying().(*types.Basic)
306-
return b != nil && b.Info()&k > 0
306+
return b != nil && b.Info()&i > 0
307+
}
308+
309+
func isBasicKind(t types.Type, k types.BasicKind) bool {
310+
b, _ := t.Underlying().(*types.Basic)
311+
return b != nil && b.Kind() == k
307312
}
308313

309314
func (c *completer) editText(from, to token.Pos, newText string) ([]protocol.TextEdit, error) {

0 commit comments

Comments
 (0)