cmd/compile/internal/syntax: better error messages for incorrect type parameter list

When parsing a declaration of the form

        type a [b[c]]d

where a, b, c, d stand for identifiers, b[c] is parsed as a type
constraint (because an array length must be constant and an index
expression b[c] is never constant, even if b is a constant string
and c a constant index - this is crucial for disambiguation of the
various possibilities).

As a result, the error message referred to a missing type parameter
name and not an invalid array declaration.

Recognize this special case and report both possibilities (because
we can't be sure without type information) with the new error:

       "missing type parameter name or invalid array length"

ALso, change the previous error message

        "type parameter must be named"

to

        "missing type parameter name"

which is more fitting as the error refers to an absent type parameter
(rather than a type parameter that's somehow invisibly present but
unnamed).

Fixes #60812.

Change-Id: Iaad3b3a9aeff9dfe2184779f3d799f16c7500b34
Reviewed-on: https://go-review.googlesource.com/c/go/+/538856
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2023-10-31 13:29:25 -07:00 committed by Gopher Robot
parent 34a5830c26
commit b7a695bd68
4 changed files with 30 additions and 15 deletions

View File

@ -2057,7 +2057,11 @@ func (p *parser) paramList(name *Name, typ Expr, close token, requireNames bool)
pos = end // position error at closing ]
msg = "missing type constraint"
} else {
msg = "type parameters must be named"
msg = "missing type parameter name"
// go.dev/issue/60812
if len(list) == 1 {
msg += " or invalid array length"
}
}
} else {
msg = "mixed named and unnamed parameters"

View File

@ -7,17 +7,17 @@ package p
type (
// 0 and 1-element []-lists are syntactically valid
_[A, B /* ERROR missing type constraint */ ] int
_[A, /* ERROR type parameters must be named */ interface{}] int
_[A, /* ERROR missing type parameter name */ interface{}] int
_[A, B, C /* ERROR missing type constraint */ ] int
_[A B, C /* ERROR missing type constraint */ ] int
_[A B, /* ERROR type parameters must be named */ interface{}] int
_[A B, /* ERROR type parameters must be named */ interface{}, C D] int
_[A B, /* ERROR type parameters must be named */ interface{}, C, D] int
_[A B, /* ERROR type parameters must be named */ interface{}, C, interface{}] int
_[A B, C interface{}, D, /* ERROR type parameters must be named */ interface{}] int
_[A B, /* ERROR missing type parameter name */ interface{}] int
_[A B, /* ERROR missing type parameter name */ interface{}, C D] int
_[A B, /* ERROR missing type parameter name */ interface{}, C, D] int
_[A B, /* ERROR missing type parameter name */ interface{}, C, interface{}] int
_[A B, C interface{}, D, /* ERROR missing type parameter name */ interface{}] int
)
// function type parameters use the same parsing routine - just have a couple of tests
func _[A, B /* ERROR missing type constraint */ ]() {}
func _[A, /* ERROR type parameters must be named */ interface{}]() {}
func _[A, /* ERROR missing type parameter name */ interface{}]() {}

View File

@ -44,3 +44,14 @@ type (
t[a ([]t)] struct{}
t[a ([]t)|t] struct{}
)
// go.dev/issue/60812
type (
t [t]struct{}
t [[]t]struct{}
t [[t]t]struct{}
t [/* ERROR missing type parameter name or invalid array length */ t[t]]struct{}
t [t t[t], /* ERROR missing type parameter name */ t[t]]struct{}
t [/* ERROR missing type parameter name */ t[t], t t[t]]struct{}
t [/* ERROR missing type parameter name */ t[t], t[t]]struct{} // report only first error
)

View File

@ -49,7 +49,7 @@ type (
_[_ [1]t]t
_[_ ~[]t]t
_[_ ~[1]t]t
t [ /* ERROR type parameters must be named */ t[0]]t
t [ /* ERROR missing type parameter name */ t[0]]t
)
// test cases for go.dev/issue/49174
@ -81,11 +81,11 @@ type (
type (
_[_ t, t /* ERROR missing type constraint */ ] t
_[_ ~t, t /* ERROR missing type constraint */ ] t
_[_ t, /* ERROR type parameters must be named */ ~t] t
_[_ ~t, /* ERROR type parameters must be named */ ~t] t
_[_ t, /* ERROR missing type parameter name */ ~t] t
_[_ ~t, /* ERROR missing type parameter name */ ~t] t
_[_ t|t, /* ERROR type parameters must be named */ t|t] t
_[_ ~t|t, /* ERROR type parameters must be named */ t|t] t
_[_ t|t, /* ERROR type parameters must be named */ ~t|t] t
_[_ ~t|t, /* ERROR type parameters must be named */ ~t|t] t
_[_ t|t, /* ERROR missing type parameter name */ t|t] t
_[_ ~t|t, /* ERROR missing type parameter name */ t|t] t
_[_ t|t, /* ERROR missing type parameter name */ ~t|t] t
_[_ ~t|t, /* ERROR missing type parameter name */ ~t|t] t
)