diff options
| author | Robert Griesemer <gri@golang.org> | 2023-10-31 13:29:25 -0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-11-01 17:49:03 +0000 |
| commit | b7a695bd684585a86ae883c64eb8cfc2b80d847b (patch) | |
| tree | 30e50640d13a475971274dd6814541f695720887 /src/cmd | |
| parent | 34a5830c267e76bdcf1f1aa6725f140af2e82f62 (diff) | |
| download | go-b7a695bd684585a86ae883c64eb8cfc2b80d847b.tar.xz | |
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>
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/compile/internal/syntax/parser.go | 6 | ||||
| -rw-r--r-- | src/cmd/compile/internal/syntax/testdata/issue43527.go | 14 | ||||
| -rw-r--r-- | src/cmd/compile/internal/syntax/testdata/tparams.go | 11 | ||||
| -rw-r--r-- | src/cmd/compile/internal/syntax/testdata/typeset.go | 14 |
4 files changed, 30 insertions, 15 deletions
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go index b34a58c3c2..140f00537a 100644 --- a/src/cmd/compile/internal/syntax/parser.go +++ b/src/cmd/compile/internal/syntax/parser.go @@ -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" diff --git a/src/cmd/compile/internal/syntax/testdata/issue43527.go b/src/cmd/compile/internal/syntax/testdata/issue43527.go index dd2c9b1272..99a8c0965d 100644 --- a/src/cmd/compile/internal/syntax/testdata/issue43527.go +++ b/src/cmd/compile/internal/syntax/testdata/issue43527.go @@ -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{}]() {} diff --git a/src/cmd/compile/internal/syntax/testdata/tparams.go b/src/cmd/compile/internal/syntax/testdata/tparams.go index 15e92afa81..4b68a1585f 100644 --- a/src/cmd/compile/internal/syntax/testdata/tparams.go +++ b/src/cmd/compile/internal/syntax/testdata/tparams.go @@ -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 +) diff --git a/src/cmd/compile/internal/syntax/testdata/typeset.go b/src/cmd/compile/internal/syntax/testdata/typeset.go index 63cdb079c0..819025c1aa 100644 --- a/src/cmd/compile/internal/syntax/testdata/typeset.go +++ b/src/cmd/compile/internal/syntax/testdata/typeset.go @@ -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 ) |
