Skip to content

Commit bcb934a

Browse files
griesemergopherbot
authored andcommitted
go/types, types2: fix printing of error message with variadic calls
Distinguish between variadic signatures and argument lists to (possibly variadic) functions and place `...` before or after the last type in the list of types. Fixes a panic. Fixes #70526. Change-Id: I77aba8f50984a21ebcdb62582030f2d0fe0eb097 Reviewed-on: https://go-review.googlesource.com/c/go/+/632275 Reviewed-by: Alan Donovan <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 91d7ab2 commit bcb934a

File tree

6 files changed

+63
-22
lines changed

6 files changed

+63
-22
lines changed

src/cmd/compile/internal/types2/assignments.go

+22-8
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,11 @@ func varTypes(list []*Var) (res []Type) {
295295
// ti's are user-friendly string representations for the given types.
296296
// If variadic is set and the last type is a slice, its string is of
297297
// the form "...E" where E is the slice's element type.
298-
func (check *Checker) typesSummary(list []Type, variadic bool) string {
298+
// If hasDots is set, the last argument string is of the form "T..."
299+
// where T is the last type.
300+
// Only one of variadic and hasDots may be set.
301+
func (check *Checker) typesSummary(list []Type, variadic, hasDots bool) string {
302+
assert(!(variadic && hasDots))
299303
var res []string
300304
for i, t := range list {
301305
var s string
@@ -304,7 +308,7 @@ func (check *Checker) typesSummary(list []Type, variadic bool) string {
304308
fallthrough // should not happen but be cautious
305309
case !isValid(t):
306310
s = "unknown type"
307-
case isUntyped(t):
311+
case isUntyped(t): // => *Basic
308312
if isNumeric(t) {
309313
// Do not imply a specific type requirement:
310314
// "have number, want float64" is better than
@@ -316,12 +320,22 @@ func (check *Checker) typesSummary(list []Type, variadic bool) string {
316320
// for compactness.
317321
s = strings.Replace(t.(*Basic).name, "untyped ", "", -1)
318322
}
319-
case variadic && i == len(list)-1:
320-
s = check.sprintf("...%s", t.(*Slice).elem)
321-
}
322-
if s == "" {
323+
default:
323324
s = check.sprintf("%s", t)
324325
}
326+
// handle ... parameters/arguments
327+
if i == len(list)-1 {
328+
switch {
329+
case variadic:
330+
// In correct code, the parameter type is a slice, but be careful.
331+
if t, _ := t.(*Slice); t != nil {
332+
s = check.sprintf("%s", t.elem)
333+
}
334+
s = "..." + s
335+
case hasDots:
336+
s += "..."
337+
}
338+
}
325339
res = append(res, s)
326340
}
327341
return "(" + strings.Join(res, ", ") + ")"
@@ -359,8 +373,8 @@ func (check *Checker) returnError(at poser, lhs []*Var, rhs []*operand) {
359373
}
360374
err := check.newError(WrongResultCount)
361375
err.addf(at, "%s return values", qualifier)
362-
err.addf(nopos, "have %s", check.typesSummary(operandTypes(rhs), false))
363-
err.addf(nopos, "want %s", check.typesSummary(varTypes(lhs), false))
376+
err.addf(nopos, "have %s", check.typesSummary(operandTypes(rhs), false, false))
377+
err.addf(nopos, "want %s", check.typesSummary(varTypes(lhs), false, false))
364378
err.report()
365379
}
366380

src/cmd/compile/internal/types2/call.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,8 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
530530
}
531531
err := check.newError(WrongArgCount)
532532
err.addf(at, "%s arguments in call to %s", qualifier, call.Fun)
533-
err.addf(nopos, "have %s", check.typesSummary(operandTypes(args), ddd))
534-
err.addf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
533+
err.addf(nopos, "have %s", check.typesSummary(operandTypes(args), false, ddd))
534+
err.addf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic, false))
535535
err.report()
536536
return
537537
}

src/go/types/assignments.go

+22-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/go/types/call.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,8 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
530530
}
531531
err := check.newError(WrongArgCount)
532532
err.addf(at, "%s arguments in call to %s", qualifier, call.Fun)
533-
err.addf(noposn, "have %s", check.typesSummary(operandTypes(args), ddd))
534-
err.addf(noposn, "want %s", check.typesSummary(varTypes(params), sig.variadic))
533+
err.addf(noposn, "have %s", check.typesSummary(operandTypes(args), false, ddd))
534+
err.addf(noposn, "want %s", check.typesSummary(varTypes(params), sig.variadic, false))
535535
err.report()
536536
return
537537
}

src/internal/types/testdata/fixedbugs/issue70150.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ package p
77
func _() {
88
var values []int
99
vf(values /* ERROR "(variable of type []int) as string value" */)
10-
vf(values...) /* ERROR "have (...int)" */
11-
vf("ab", "cd", values /* ERROR "have (string, string, ...int)" */ ...)
10+
vf(values...) /* ERROR "have ([]int...)\n\twant (string, ...int)" */
11+
vf("ab", "cd", values /* ERROR "have (string, string, []int...)\n\twant (string, ...int)" */ ...)
1212
}
1313

1414
func vf(method string, values ...int) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
func f(...any)
8+
9+
func _(x int, s []int) {
10+
f(0, x /* ERROR "have (number, int...)\n\twant (...any)" */ ...)
11+
f(0, s /* ERROR "have (number, []int...)\n\twant (...any)" */ ...)
12+
f(0, 0 /* ERROR "have (number, number...)\n\twant (...any)" */ ...)
13+
}

0 commit comments

Comments
 (0)