mirror of
https://github.com/golang/go
synced 2024-09-05 16:04:50 +00:00
cmd/compile: improve not enough / too many arguments errors
Use "have" and "want" and multiple lines like other similar error messages. Also, fix handling of ... and multi-value function calls. Fixes #17650. Change-Id: I4850e79c080eac8df3b92a4accf9e470dff63c9a Reviewed-on: https://go-review.googlesource.com/32261 Reviewed-by: Robert Griesemer <gri@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
1bd39e79db
commit
ec5b6406b7
|
@ -2692,12 +2692,12 @@ notenough:
|
|||
// Method expressions have the form T.M, and the compiler has
|
||||
// rewritten those to ONAME nodes but left T in Left.
|
||||
if call.Op == ONAME && call.Left != nil && call.Left.Op == OTYPE {
|
||||
yyerror("not enough arguments in call to method expression %v, got %s want %v", call, nl.retsigerr(), tstruct)
|
||||
yyerror("not enough arguments in call to method expression %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
|
||||
} else {
|
||||
yyerror("not enough arguments in call to %v, got %s want %v", call, nl.retsigerr(), tstruct)
|
||||
yyerror("not enough arguments in call to %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
|
||||
}
|
||||
} else {
|
||||
yyerror("not enough arguments to %v, got %s want %v", op, nl.retsigerr(), tstruct)
|
||||
yyerror("not enough arguments to %v\n\thave %s\n\twant %v", op, nl.retsigerr(isddd), tstruct)
|
||||
}
|
||||
if n != nil {
|
||||
n.Diag = 1
|
||||
|
@ -2708,9 +2708,9 @@ notenough:
|
|||
|
||||
toomany:
|
||||
if call != nil {
|
||||
yyerror("too many arguments in call to %v, got %s want %v", call, nl.retsigerr(), tstruct)
|
||||
yyerror("too many arguments in call to %v\n\thave %s\n\twant %v", call, nl.retsigerr(isddd), tstruct)
|
||||
} else {
|
||||
yyerror("too many arguments to %v, got %s want %v", op, nl.retsigerr(), tstruct)
|
||||
yyerror("too many arguments to %v\n\thave %s\n\twant %v", op, nl.retsigerr(isddd), tstruct)
|
||||
}
|
||||
goto out
|
||||
}
|
||||
|
@ -2738,17 +2738,27 @@ func (t *Type) sigrepr() string {
|
|||
|
||||
// retsigerr returns the signature of the types
|
||||
// at the respective return call site of a function.
|
||||
func (nl Nodes) retsigerr() string {
|
||||
func (nl Nodes) retsigerr(isddd bool) string {
|
||||
if nl.Len() < 1 {
|
||||
return "()"
|
||||
}
|
||||
|
||||
var typeStrings []string
|
||||
for _, n := range nl.Slice() {
|
||||
typeStrings = append(typeStrings, n.Type.sigrepr())
|
||||
if nl.Len() == 1 && nl.First().Type != nil && nl.First().Type.IsFuncArgStruct() {
|
||||
for _, f := range nl.First().Type.Fields().Slice() {
|
||||
typeStrings = append(typeStrings, f.Type.sigrepr())
|
||||
}
|
||||
} else {
|
||||
for _, n := range nl.Slice() {
|
||||
typeStrings = append(typeStrings, n.Type.sigrepr())
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", "))
|
||||
ddd := ""
|
||||
if isddd {
|
||||
ddd = "..."
|
||||
}
|
||||
return fmt.Sprintf("(%s%s)", strings.Join(typeStrings, ", "), ddd)
|
||||
}
|
||||
|
||||
// type check composite
|
||||
|
|
|
@ -27,9 +27,9 @@ func tuple() (int, int, int) { return 1, 2, 3 }
|
|||
|
||||
var (
|
||||
_ = sum(tuple())
|
||||
_ = sum(tuple()...) // ERROR "multiple-value|[.][.][.]"
|
||||
_ = sum(tuple()...) // ERROR "multiple-value"
|
||||
_ = sum3(tuple())
|
||||
_ = sum3(tuple()...) // ERROR "multiple-value|[.][.][.]" "not enough"
|
||||
_ = sum3(tuple()...) // ERROR "multiple-value" "not enough"
|
||||
)
|
||||
|
||||
type T []T
|
||||
|
@ -59,4 +59,3 @@ func bad(args ...int) {
|
|||
_ = [...]byte("foo") // ERROR "[.][.][.]"
|
||||
_ = [...][...]int{{1,2,3},{4,5,6}} // ERROR "[.][.][.]"
|
||||
}
|
||||
|
||||
|
|
|
@ -7,28 +7,28 @@
|
|||
package main
|
||||
|
||||
func foo() (int, int) {
|
||||
return 2.3 // ERROR "not enough arguments to return, got \(number\) want \(int, int\)"
|
||||
return 2.3 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int\)"
|
||||
}
|
||||
|
||||
func foo2() {
|
||||
return int(2), 2 // ERROR "too many arguments to return, got \(int, number\) want \(\)"
|
||||
return int(2), 2 // ERROR "too many arguments to return\n\thave \(int, number\)\n\twant \(\)"
|
||||
}
|
||||
|
||||
func foo3(v int) (a, b, c, d int) {
|
||||
if v >= 0 {
|
||||
return 1 // ERROR "not enough arguments to return, got \(number\) want \(int, int, int, int\)"
|
||||
return 1 // ERROR "not enough arguments to return\n\thave \(number\)\n\twant \(int, int, int, int\)"
|
||||
}
|
||||
return 2, 3 // ERROR "not enough arguments to return, got \(number, number\) want \(int, int, int, int\)"
|
||||
return 2, 3 // ERROR "not enough arguments to return\n\thave \(number, number\)\n\twant \(int, int, int, int\)"
|
||||
}
|
||||
|
||||
func foo4(name string) (string, int) {
|
||||
switch name {
|
||||
case "cow":
|
||||
return "moo" // ERROR "not enough arguments to return, got \(string\) want \(string, int\)"
|
||||
return "moo" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)"
|
||||
case "dog":
|
||||
return "dog", 10, true // ERROR "too many arguments to return, got \(string, number, bool\) want \(string, int\)"
|
||||
return "dog", 10, true // ERROR "too many arguments to return\n\thave \(string, number, bool\)\n\twant \(string, int\)"
|
||||
case "fish":
|
||||
return "" // ERROR "not enough arguments to return, got \(string\) want \(string, int\)"
|
||||
return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(string, int\)"
|
||||
default:
|
||||
return "lizard", 10
|
||||
}
|
||||
|
@ -40,14 +40,14 @@ type U float64
|
|||
|
||||
func foo5() (S, T, U) {
|
||||
if false {
|
||||
return "" // ERROR "not enough arguments to return, got \(string\) want \(S, T, U\)"
|
||||
return "" // ERROR "not enough arguments to return\n\thave \(string\)\n\twant \(S, T, U\)"
|
||||
} else {
|
||||
ptr := new(T)
|
||||
return ptr // ERROR "not enough arguments to return, got \(\*T\) want \(S, T, U\)"
|
||||
return ptr // ERROR "not enough arguments to return\n\thave \(\*T\)\n\twant \(S, T, U\)"
|
||||
}
|
||||
return new(S), 12.34, 1 + 0i, 'r', true // ERROR "too many arguments to return, got \(\*S, number, number, number, bool\) want \(S, T, U\)"
|
||||
return new(S), 12.34, 1 + 0i, 'r', true // ERROR "too many arguments to return\n\thave \(\*S, number, number, number, bool\)\n\twant \(S, T, U\)"
|
||||
}
|
||||
|
||||
func foo6() (T, string) {
|
||||
return "T", true, true // ERROR "too many arguments to return, got \(string, bool, bool\) want \(T, string\)"
|
||||
return "T", true, true // ERROR "too many arguments to return\n\thave \(string, bool, bool\)\n\twant \(T, string\)"
|
||||
}
|
||||
|
|
|
@ -18,5 +18,5 @@ func printmany(nums ...int) {
|
|||
func main() {
|
||||
printmany(1, 2, 3)
|
||||
printmany([]int{1, 2, 3}...)
|
||||
printmany(1, "abc", []int{2, 3}...) // ERROR "too many arguments in call to printmany, got \(number, string, \[\]int\) want \(...int\)"
|
||||
printmany(1, "abc", []int{2, 3}...) // ERROR "too many arguments in call to printmany\n\thave \(number, string, \[\]int\.\.\.\)\n\twant \(...int\)"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue