mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
go/parser, syntax: better error message for parameter missing type
Fixes #69506. Change-Id: I18215e11f214b12d5f65be1d1740181e427f8817 Reviewed-on: https://go-review.googlesource.com/c/go/+/617015 Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
0206eb9679
commit
bae2e968e2
@ -2075,26 +2075,31 @@ func (p *parser) paramList(name *Name, typ Expr, close token, requireNames bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if errPos.IsKnown() {
|
if errPos.IsKnown() {
|
||||||
var msg string
|
|
||||||
if requireNames {
|
|
||||||
// Not all parameters are named because named != len(list).
|
// Not all parameters are named because named != len(list).
|
||||||
// If named == typed we must have parameters that have no types,
|
// If named == typed, there must be parameters that have no types.
|
||||||
// and they must be at the end of the parameter list, otherwise
|
// They must be at the end of the parameter list, otherwise types
|
||||||
// the types would have been filled in by the right-to-left sweep
|
// would have been filled in by the right-to-left sweep above and
|
||||||
// above and we wouldn't have an error. Since we are in a type
|
// there would be no error.
|
||||||
// parameter list, the missing types are constraints.
|
// If requireNames is set, the parameter list is a type parameter
|
||||||
|
// list.
|
||||||
|
var msg string
|
||||||
if named == typed {
|
if named == typed {
|
||||||
errPos = end // position error at closing ]
|
errPos = end // position error at closing token ) or ]
|
||||||
|
if requireNames {
|
||||||
msg = "missing type constraint"
|
msg = "missing type constraint"
|
||||||
} else {
|
} else {
|
||||||
|
msg = "missing parameter type"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if requireNames {
|
||||||
msg = "missing type parameter name"
|
msg = "missing type parameter name"
|
||||||
// go.dev/issue/60812
|
// go.dev/issue/60812
|
||||||
if len(list) == 1 {
|
if len(list) == 1 {
|
||||||
msg += " or invalid array length"
|
msg += " or invalid array length"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
msg = "mixed named and unnamed parameters"
|
msg = "missing parameter name"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.syntaxErrorAt(errPos, msg)
|
p.syntaxErrorAt(errPos, msg)
|
||||||
}
|
}
|
||||||
|
9
src/cmd/compile/internal/syntax/testdata/issue69506.go
vendored
Normal file
9
src/cmd/compile/internal/syntax/testdata/issue69506.go
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2024 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 _(a int, b /* ERROR missing parameter type */ )
|
||||||
|
func _(a int, /* ERROR missing parameter name */ []int)
|
||||||
|
func _(a int, /* ERROR missing parameter name */ []int, c int)
|
@ -13,7 +13,7 @@ type t struct {
|
|||||||
}
|
}
|
||||||
type t interface {
|
type t interface {
|
||||||
t[a]
|
t[a]
|
||||||
m /* ERROR method must have no type parameters */ [_ _, /* ERROR mixed */ _]()
|
m /* ERROR method must have no type parameters */ [_ _, _ /* ERROR missing parameter type */ ]()
|
||||||
t[a, b]
|
t[a, b]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,26 +978,30 @@ func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing tok
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if errPos.IsValid() {
|
if errPos.IsValid() {
|
||||||
var msg string
|
|
||||||
if tparams {
|
|
||||||
// Not all parameters are named because named != len(list).
|
// Not all parameters are named because named != len(list).
|
||||||
// If named == typed we must have parameters that have no types,
|
// If named == typed, there must be parameters that have no types.
|
||||||
// and they must be at the end of the parameter list, otherwise
|
// They must be at the end of the parameter list, otherwise types
|
||||||
// the types would have been filled in by the right-to-left sweep
|
// would have been filled in by the right-to-left sweep above and
|
||||||
// above and we wouldn't have an error. Since we are in a type
|
// there would be no error.
|
||||||
// parameter list, the missing types are constraints.
|
// If tparams is set, the parameter list is a type parameter list.
|
||||||
|
var msg string
|
||||||
if named == typed {
|
if named == typed {
|
||||||
errPos = p.pos // position error at closing ]
|
errPos = p.pos // position error at closing token ) or ]
|
||||||
|
if tparams {
|
||||||
msg = "missing type constraint"
|
msg = "missing type constraint"
|
||||||
} else {
|
} else {
|
||||||
|
msg = "missing parameter type"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if tparams {
|
||||||
msg = "missing type parameter name"
|
msg = "missing type parameter name"
|
||||||
// go.dev/issue/60812
|
// go.dev/issue/60812
|
||||||
if len(list) == 1 {
|
if len(list) == 1 {
|
||||||
msg += " or invalid array length"
|
msg += " or invalid array length"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
msg = "mixed named and unnamed parameters"
|
msg = "missing parameter name"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.error(errPos, msg)
|
p.error(errPos, msg)
|
||||||
}
|
}
|
||||||
|
9
src/go/parser/testdata/issue69506.go2
vendored
Normal file
9
src/go/parser/testdata/issue69506.go2
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2024 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 _(a int, b) /* ERROR "missing parameter type" */
|
||||||
|
func _(a int, [ /* ERROR "missing parameter name" */ ]int)
|
||||||
|
func _(a int, [ /* ERROR "missing parameter name" */ ]int, c int)
|
@ -9,7 +9,7 @@
|
|||||||
package main
|
package main
|
||||||
import "runtime"
|
import "runtime"
|
||||||
|
|
||||||
func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|mixed named and unnamed|undefined identifier"
|
func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|missing parameter name|undefined identifier"
|
||||||
println(i, runtime.UintType) // GCCGO_ERROR "undefined identifier"
|
println(i, runtime.UintType) // GCCGO_ERROR "undefined identifier"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ type t1 int
|
|||||||
type t2 int
|
type t2 int
|
||||||
type t3 int
|
type t3 int
|
||||||
|
|
||||||
func f1(*t2, x t3) // ERROR "named"
|
func f1(*t2, x t3) // ERROR "missing parameter name"
|
||||||
func f2(t1, *t2, x t3) // ERROR "named"
|
func f2(t1, *t2, x t3) // ERROR "missing parameter name"
|
||||||
func f3() (x int, *string) // ERROR "named"
|
func f3() (x int, *string) // ERROR "missing parameter name"
|
||||||
|
|
||||||
func f4() (t1 t1) // legal - scope of parameter named t1 starts in body of f4.
|
func f4() (t1 t1) // legal - scope of parameter named t1 starts in body of f4.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user