]> Cypherpunks repositories - gostls13.git/commitdiff
go/parser, syntax: better error message for parameter missing type
authorRobert Griesemer <gri@golang.org>
Mon, 30 Sep 2024 21:10:40 +0000 (14:10 -0700)
committerRobert Griesemer <gri@google.com>
Mon, 30 Sep 2024 22:04:40 +0000 (22:04 +0000)
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>

src/cmd/compile/internal/syntax/parser.go
src/cmd/compile/internal/syntax/testdata/issue69506.go [new file with mode: 0644]
src/cmd/compile/internal/syntax/testdata/tparams.go
src/go/parser/parser.go
src/go/parser/testdata/issue69506.go2 [new file with mode: 0644]
test/fixedbugs/bug388.go
test/func3.go

index cd6b6696a2d0c8bf7e8ef87a0d72e092b2f4c58e..77abdda867ba8f83d044b2b6e06b1b7626c84902 100644 (file)
@@ -2075,26 +2075,31 @@ func (p *parser) paramList(name *Name, typ Expr, close token, requireNames bool)
                        }
                }
                if errPos.IsKnown() {
+                       // Not all parameters are named because named != len(list).
+                       // If named == typed, there must be parameters that have no types.
+                       // They must be at the end of the parameter list, otherwise types
+                       // would have been filled in by the right-to-left sweep above and
+                       // there would be no error.
+                       // If requireNames is set, the parameter list is a type parameter
+                       // list.
                        var msg string
-                       if requireNames {
-                               // Not all parameters are named because named != len(list).
-                               // If named == typed we must have parameters that have no types,
-                               // and they must be at the end of the parameter list, otherwise
-                               // the types would have been filled in by the right-to-left sweep
-                               // above and we wouldn't have an error. Since we are in a type
-                               // parameter list, the missing types are constraints.
-                               if named == typed {
-                                       errPos = end // position error at closing ]
+                       if named == typed {
+                               errPos = end // position error at closing token ) or ]
+                               if requireNames {
                                        msg = "missing type constraint"
                                } else {
+                                       msg = "missing parameter type"
+                               }
+                       } else {
+                               if requireNames {
                                        msg = "missing type parameter name"
                                        // go.dev/issue/60812
                                        if len(list) == 1 {
                                                msg += " or invalid array length"
                                        }
+                               } else {
+                                       msg = "missing parameter name"
                                }
-                       } else {
-                               msg = "mixed named and unnamed parameters"
                        }
                        p.syntaxErrorAt(errPos, msg)
                }
diff --git a/src/cmd/compile/internal/syntax/testdata/issue69506.go b/src/cmd/compile/internal/syntax/testdata/issue69506.go
new file mode 100644 (file)
index 0000000..36e9da7
--- /dev/null
@@ -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)
index 4b68a1585f9635861a19d3cc4f2f8af2f8d79e94..a4967bf70f0f9ce07146a55cac5969024f6dab44 100644 (file)
@@ -13,7 +13,7 @@ type t struct {
 }
 type t interface {
        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]
 }
 
index c9f28a6a69bc2e9e4b580860a65048b183c08b2c..8ed893430dec777eeae37d8e5755315963df554e 100644 (file)
@@ -978,26 +978,30 @@ func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing tok
                        }
                }
                if errPos.IsValid() {
+                       // Not all parameters are named because named != len(list).
+                       // If named == typed, there must be parameters that have no types.
+                       // They must be at the end of the parameter list, otherwise types
+                       // would have been filled in by the right-to-left sweep above and
+                       // there would be no error.
+                       // If tparams is set, the parameter list is a type parameter list.
                        var msg string
-                       if tparams {
-                               // Not all parameters are named because named != len(list).
-                               // If named == typed we must have parameters that have no types,
-                               // and they must be at the end of the parameter list, otherwise
-                               // the types would have been filled in by the right-to-left sweep
-                               // above and we wouldn't have an error. Since we are in a type
-                               // parameter list, the missing types are constraints.
-                               if named == typed {
-                                       errPos = p.pos // position error at closing ]
+                       if named == typed {
+                               errPos = p.pos // position error at closing token ) or ]
+                               if tparams {
                                        msg = "missing type constraint"
                                } else {
+                                       msg = "missing parameter type"
+                               }
+                       } else {
+                               if tparams {
                                        msg = "missing type parameter name"
                                        // go.dev/issue/60812
                                        if len(list) == 1 {
                                                msg += " or invalid array length"
                                        }
+                               } else {
+                                       msg = "missing parameter name"
                                }
-                       } else {
-                               msg = "mixed named and unnamed parameters"
                        }
                        p.error(errPos, msg)
                }
diff --git a/src/go/parser/testdata/issue69506.go2 b/src/go/parser/testdata/issue69506.go2
new file mode 100644 (file)
index 0000000..b93666a
--- /dev/null
@@ -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)
index a060c9fd5a75c66e0f676f37f2dbe32665f5eb0f..0524534bb3f6dcb8a4a555112e37f947bd3be2b7 100644 (file)
@@ -9,7 +9,7 @@
 package main
 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"
 }
 
index 6be3bf0184d386f436fd3d7a1044b26da8084613..861ab2cba524066bfb4d5fe351312fd97026752f 100644 (file)
@@ -13,8 +13,8 @@ type t1 int
 type t2 int
 type t3 int
 
-func f1(*t2, x t3)     // ERROR "named"
-func f2(t1, *t2, x t3) // ERROR "named"
-func f3() (x int, *string)     // ERROR "named"
+func f1(*t2, x t3)     // ERROR "missing parameter name"
+func f2(t1, *t2, x t3) // ERROR "missing parameter name"
+func f3() (x int, *string)     // ERROR "missing parameter name"
 
 func f4() (t1 t1)      // legal - scope of parameter named t1 starts in body of f4.