From 7b9e26ea6cd7a109f55f8d483528e06309c71e30 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Mon, 6 Oct 2025 12:48:38 +0800 Subject: [PATCH] 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 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs index 8e255985a205..6b53493c9a36 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index a3cfe64e6e73..cd6d433d0efa 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast index d6e3219c3957..7a3ca66476e3 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast index 485ad11f233a..0c240b7214f4 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rast new file mode 100644 index 000000000000..11097232a683 --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs new file mode 100644 index 000000000000..e3ce44dadfbd --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs @@ -0,0 +1 @@ +const C = 0; diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rast new file mode 100644 index 000000000000..a9595401d6d6 --- /dev/null +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs new file mode 100644 index 000000000000..33ecedf80772 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs @@ -0,0 +1 @@ +static C = 0;