From a7af474359179062a82429da927407d2d5395acc Mon Sep 17 00:00:00 2001 From: smasher164 Date: Tue, 4 Dec 2018 06:41:39 -0500 Subject: [PATCH] cmd/compile: improve error message for non-final variadic parameter Previously, when a function signature had defined a non-final variadic parameter, the error message always referred to the type associated with that parameter. However, if the offending parameter's name was part of an identifier list with a variadic type, one could misinterpret the message, thinking the problem had been with one of the other names in the identifer list. func bar(a, b ...int) {} clear ~~~~~~~^ ^~~~~~~~ confusing This change updates the error message and sets the column position to that of the offending parameter's name, if it exists. Fixes #28450. Change-Id: I076f560925598ed90e218c25d70f9449ffd9b3ea Reviewed-on: https://go-review.googlesource.com/c/152417 Run-TryBot: Matthew Dempsky Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/gc/noder.go | 6 +++++- test/fixedbugs/issue28450.go | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue28450.go diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index 23c9539b0a1ae5..89e9ddb668b061 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -548,7 +548,11 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node { if !dddOk { yyerror("cannot use ... in receiver or result parameter list") } else if !final { - yyerror("can only use ... with final parameter in list") + if param.Name == nil { + yyerror("cannot use ... with non-final parameter") + } else { + p.yyerrorpos(param.Name.Pos(), "cannot use ... with non-final parameter %s", param.Name.Value) + } } typ.Op = OTARRAY typ.Right = typ.Left diff --git a/test/fixedbugs/issue28450.go b/test/fixedbugs/issue28450.go new file mode 100644 index 00000000000000..21e5e0c5f1cab8 --- /dev/null +++ b/test/fixedbugs/issue28450.go @@ -0,0 +1,18 @@ +// errorcheck + +// Copyright 2018 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 p + +func f(a, b, c, d ...int) {} // ERROR "non-final parameter a" "non-final parameter b" "non-final parameter c" +func g(a ...int, b ...int) {} // ERROR "non-final parameter a" +func h(...int, ...int, float32) {} // ERROR "non-final parameter" + +type a func(...float32, ...interface{}) // ERROR "non-final parameter" +type b interface { + f(...int, ...int) // ERROR "non-final parameter" + g(a ...int, b ...int, c float32) // ERROR "non-final parameter a" "non-final parameter b" + valid(...int) +}