From 216db6d5b43d7b59138e2b8f4381077f495e0a35 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Mon, 6 Oct 2025 12:48:38 +0800 Subject: [PATCH 1/2] Improve parsing error for `static` and `const` Example --- ```rust static C: u32 = 0; ``` -> ```diff -error 8: missing type for `const` or `static` +error 8: `static` may not have generic parameters ``` --- ```rust const C = 0; ``` -> ```diff -error 7: missing type for `const` or `static` +error 7: missing type for `const` ``` --- ```rust static C = 0; ``` -> ```diff -error 8: missing type for `const` or `static` +error 8: missing type for `static` ``` --- crates/parser/src/grammar/items/consts.rs | 12 ++++++++++-- crates/parser/test_data/generated/runner.rs | 8 ++++++++ .../test_data/parser/err/0044_item_modifiers.rast | 2 +- .../parser/inline/err/generic_static.rast | 2 +- .../parser/inline/err/missing_const_type.rast | 14 ++++++++++++++ .../parser/inline/err/missing_const_type.rs | 1 + .../parser/inline/err/missing_static_type.rast | 14 ++++++++++++++ .../parser/inline/err/missing_static_type.rs | 1 + 8 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 crates/parser/test_data/parser/inline/err/missing_const_type.rast create mode 100644 crates/parser/test_data/parser/inline/err/missing_const_type.rs create mode 100644 crates/parser/test_data/parser/inline/err/missing_static_type.rast create mode 100644 crates/parser/test_data/parser/inline/err/missing_static_type.rs diff --git a/crates/parser/src/grammar/items/consts.rs b/crates/parser/src/grammar/items/consts.rs index 8e255985a2..6b53493c9a 100644 --- a/crates/parser/src/grammar/items/consts.rs +++ b/crates/parser/src/grammar/items/consts.rs @@ -32,14 +32,22 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) { // const C<'a>: &'a () = &(); // } generic_params::opt_generic_param_list(p); + } else if p.at(T![<]) { + p.error("`static` may not have generic parameters"); } // test_err generic_static // static C: u32 = 0; if p.at(T![:]) { types::ascription(p); - } else { - p.error("missing type for `const` or `static`"); + } else if is_const { + // test_err missing_const_type + // const C = 0; + p.error("missing type for `const`"); + } else if !p.at(T![<]) { + // test_err missing_static_type + // static C = 0; + p.error("missing type for `static`"); } if p.eat(T![=]) { expressions::expr(p); diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs index a3cfe64e6e..cd6d433d0e 100644 --- a/crates/parser/test_data/generated/runner.rs +++ b/crates/parser/test_data/generated/runner.rs @@ -824,10 +824,18 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/misplaced_label_err.rs"); } #[test] + fn missing_const_type() { + run_and_expect_errors("test_data/parser/inline/err/missing_const_type.rs"); + } + #[test] fn missing_fn_param_type() { run_and_expect_errors("test_data/parser/inline/err/missing_fn_param_type.rs"); } #[test] + fn missing_static_type() { + run_and_expect_errors("test_data/parser/inline/err/missing_static_type.rs"); + } + #[test] fn path_item_without_excl() { run_and_expect_errors("test_data/parser/inline/err/path_item_without_excl.rs"); } diff --git a/crates/parser/test_data/parser/err/0044_item_modifiers.rast b/crates/parser/test_data/parser/err/0044_item_modifiers.rast index d6e3219c39..7a3ca66476 100644 --- a/crates/parser/test_data/parser/err/0044_item_modifiers.rast +++ b/crates/parser/test_data/parser/err/0044_item_modifiers.rast @@ -42,7 +42,7 @@ SOURCE_FILE WHITESPACE "\n" error 6: expected fn, trait or impl error 38: expected a name -error 40: missing type for `const` or `static` +error 40: missing type for `const` error 40: expected SEMICOLON error 44: expected an item error 44: expected an item diff --git a/crates/parser/test_data/parser/inline/err/generic_static.rast b/crates/parser/test_data/parser/inline/err/generic_static.rast index 485ad11f23..0c240b7214 100644 --- a/crates/parser/test_data/parser/inline/err/generic_static.rast +++ b/crates/parser/test_data/parser/inline/err/generic_static.rast @@ -30,7 +30,7 @@ SOURCE_FILE ERROR SEMICOLON ";" WHITESPACE "\n" -error 8: missing type for `const` or `static` +error 8: `static` may not have generic parameters error 8: expected SEMICOLON error 8: expected an item error 12: expected an item diff --git a/crates/parser/test_data/parser/inline/err/missing_const_type.rast b/crates/parser/test_data/parser/inline/err/missing_const_type.rast new file mode 100644 index 0000000000..11097232a6 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/missing_const_type.rast @@ -0,0 +1,14 @@ +SOURCE_FILE + CONST + CONST_KW "const" + WHITESPACE " " + NAME + IDENT "C" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + SEMICOLON ";" + WHITESPACE "\n" +error 7: missing type for `const` diff --git a/crates/parser/test_data/parser/inline/err/missing_const_type.rs b/crates/parser/test_data/parser/inline/err/missing_const_type.rs new file mode 100644 index 0000000000..e3ce44dadf --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/missing_const_type.rs @@ -0,0 +1 @@ +const C = 0; diff --git a/crates/parser/test_data/parser/inline/err/missing_static_type.rast b/crates/parser/test_data/parser/inline/err/missing_static_type.rast new file mode 100644 index 0000000000..a9595401d6 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/missing_static_type.rast @@ -0,0 +1,14 @@ +SOURCE_FILE + STATIC + STATIC_KW "static" + WHITESPACE " " + NAME + IDENT "C" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + SEMICOLON ";" + WHITESPACE "\n" +error 8: missing type for `static` diff --git a/crates/parser/test_data/parser/inline/err/missing_static_type.rs b/crates/parser/test_data/parser/inline/err/missing_static_type.rs new file mode 100644 index 0000000000..33ecedf807 --- /dev/null +++ b/crates/parser/test_data/parser/inline/err/missing_static_type.rs @@ -0,0 +1 @@ +static C = 0; From 2707cf7ce6b1e98a87d04b82b0b9cc22a46ccc87 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Thu, 9 Oct 2025 09:45:42 +0800 Subject: [PATCH 2/2] Allow generic_param_list for `static` items --- crates/parser/src/grammar/items/consts.rs | 21 +++++---- .../parser/inline/err/generic_static.rast | 45 +++++++------------ 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/crates/parser/src/grammar/items/consts.rs b/crates/parser/src/grammar/items/consts.rs index 6b53493c9a..e6a8aca586 100644 --- a/crates/parser/src/grammar/items/consts.rs +++ b/crates/parser/src/grammar/items/consts.rs @@ -25,18 +25,17 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) { } // FIXME: Recover on statics with generic params/where clause. - if is_const { - // test generic_const - // const C: u32 = 0; - // impl Foo { - // const C<'a>: &'a () = &(); - // } - generic_params::opt_generic_param_list(p); - } else if p.at(T![<]) { + if !is_const && p.at(T![<]) { + // test_err generic_static + // static C: u32 = 0; p.error("`static` may not have generic parameters"); } - // test_err generic_static - // static C: u32 = 0; + // test generic_const + // const C: u32 = 0; + // impl Foo { + // const C<'a>: &'a () = &(); + // } + generic_params::opt_generic_param_list(p); if p.at(T![:]) { types::ascription(p); @@ -44,7 +43,7 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) { // test_err missing_const_type // const C = 0; p.error("missing type for `const`"); - } else if !p.at(T![<]) { + } else { // test_err missing_static_type // static C = 0; p.error("missing type for `static`"); diff --git a/crates/parser/test_data/parser/inline/err/generic_static.rast b/crates/parser/test_data/parser/inline/err/generic_static.rast index 0c240b7214..08017cb0fc 100644 --- a/crates/parser/test_data/parser/inline/err/generic_static.rast +++ b/crates/parser/test_data/parser/inline/err/generic_static.rast @@ -4,39 +4,24 @@ SOURCE_FILE WHITESPACE " " NAME IDENT "C" - ERROR - L_ANGLE "<" - ERROR - PATH - PATH_SEGMENT - NAME_REF + GENERIC_PARAM_LIST + L_ANGLE "<" + TYPE_PARAM + NAME IDENT "i32" - ERROR - R_ANGLE ">" - ERROR + R_ANGLE ">" COLON ":" - WHITESPACE " " - ERROR - PATH - PATH_SEGMENT - NAME_REF - IDENT "u32" - WHITESPACE " " - ERROR + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u32" + WHITESPACE " " EQ "=" - WHITESPACE " " - ERROR - INT_NUMBER "0" - ERROR + WHITESPACE " " + LITERAL + INT_NUMBER "0" SEMICOLON ";" WHITESPACE "\n" error 8: `static` may not have generic parameters -error 8: expected SEMICOLON -error 8: expected an item -error 12: expected an item -error 12: expected an item -error 13: expected an item -error 18: expected an item -error 19: expected an item -error 21: expected an item -error 22: expected an item