From b7a695bd684585a86ae883c64eb8cfc2b80d847b Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 31 Oct 2023 13:29:25 -0700 Subject: [PATCH] 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 Run-TryBot: Robert Griesemer Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer Reviewed-by: Robert Findley --- src/cmd/compile/internal/syntax/parser.go | 6 +++++- .../compile/internal/syntax/testdata/issue43527.go | 14 +++++++------- .../compile/internal/syntax/testdata/tparams.go | 11 +++++++++++ .../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 ) -- 2.44.0