From d85bffdba4f8cb1211c825e3ecc818e9348007e0 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 18 Mar 2025 07:11:34 +0100 Subject: feat: parse `unsafe` record fields --- src/tools/rust-analyzer/crates/syntax/rust.ungram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tools/rust-analyzer/crates/syntax/rust.ungram') diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 70a91af6c47..673334bd225 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -240,7 +240,7 @@ RecordFieldList = '{' fields:(RecordField (',' RecordField)* ','?)? '}' RecordField = - Attr* Visibility? + Attr* Visibility? 'unsafe'? Name ':' Type ('=' Expr)? TupleFieldList = -- cgit 1.4.1-3-g733a5 From c9e272ea0a3a4a1d9be4be634f8985774b36f5d3 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 21 Apr 2025 02:11:56 +0300 Subject: Parse generic consts A lang team experiment, https://github.com/rust-lang/rust/issues/113521. --- .../crates/parser/src/grammar/items/consts.rs | 26 +++++++ .../crates/parser/test_data/generated/runner.rs | 12 +++ .../parser/inline/err/generic_static.rast | 42 ++++++++++ .../test_data/parser/inline/err/generic_static.rs | 1 + .../parser/inline/err/static_where_clause.rast | 44 +++++++++++ .../parser/inline/err/static_where_clause.rs | 2 + .../parser/inline/ok/const_where_clause.rast | 89 ++++++++++++++++++++++ .../parser/inline/ok/const_where_clause.rs | 5 ++ .../test_data/parser/inline/ok/generic_const.rast | 71 +++++++++++++++++ .../test_data/parser/inline/ok/generic_const.rs | 4 + src/tools/rust-analyzer/crates/syntax/rust.ungram | 5 +- .../crates/syntax/src/ast/generated/nodes.rs | 7 +- 12 files changed, 305 insertions(+), 3 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rs create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rs create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rs create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rast create mode 100644 src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rs (limited to 'src/tools/rust-analyzer/crates/syntax/rust.ungram') 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 9549ec9b400..8e255985a20 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 @@ -24,6 +24,18 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) { name(p); } + // 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); + } + // test_err generic_static + // static C: u32 = 0; + if p.at(T![:]) { types::ascription(p); } else { @@ -32,6 +44,20 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) { if p.eat(T![=]) { expressions::expr(p); } + + if is_const { + // test const_where_clause + // const C: u32 = 0 + // where i32: Copy; + // trait Foo { + // const C: i32 where i32: Copy; + // } + generic_params::opt_where_clause(p); + } + // test_err static_where_clause + // static C: u32 = 0 + // where i32: Copy; + p.expect(T![;]); m.complete(p, if is_const { CONST } else { STATIC }); } 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 2ea29345edd..87ffc99539b 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 @@ -139,6 +139,10 @@ mod ok { run_and_expect_no_errors("test_data/parser/inline/ok/const_trait_bound.rs"); } #[test] + fn const_where_clause() { + run_and_expect_no_errors("test_data/parser/inline/ok/const_where_clause.rs"); + } + #[test] fn continue_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/continue_expr.rs"); } #[test] fn crate_path() { run_and_expect_no_errors("test_data/parser/inline/ok/crate_path.rs"); } @@ -278,6 +282,8 @@ mod ok { run_and_expect_no_errors("test_data/parser/inline/ok/generic_arg_bounds.rs"); } #[test] + fn generic_const() { run_and_expect_no_errors("test_data/parser/inline/ok/generic_const.rs"); } + #[test] fn generic_param_attribute() { run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_attribute.rs"); } @@ -764,6 +770,8 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/generic_param_list_recover.rs"); } #[test] + fn generic_static() { run_and_expect_errors("test_data/parser/inline/err/generic_static.rs"); } + #[test] fn impl_type() { run_and_expect_errors("test_data/parser/inline/err/impl_type.rs"); } #[test] fn let_else_right_curly_brace() { @@ -836,6 +844,10 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/recover_from_missing_const_default.rs"); } #[test] + fn static_where_clause() { + run_and_expect_errors("test_data/parser/inline/err/static_where_clause.rs"); + } + #[test] fn struct_field_recover() { run_and_expect_errors("test_data/parser/inline/err/struct_field_recover.rs"); } 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 new file mode 100644 index 00000000000..485ad11f233 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast @@ -0,0 +1,42 @@ +SOURCE_FILE + STATIC + STATIC_KW "static" + WHITESPACE " " + NAME + IDENT "C" + ERROR + L_ANGLE "<" + ERROR + PATH + PATH_SEGMENT + NAME_REF + IDENT "i32" + ERROR + R_ANGLE ">" + ERROR + COLON ":" + WHITESPACE " " + ERROR + PATH + PATH_SEGMENT + NAME_REF + IDENT "u32" + WHITESPACE " " + ERROR + EQ "=" + WHITESPACE " " + ERROR + INT_NUMBER "0" + ERROR + SEMICOLON ";" + WHITESPACE "\n" +error 8: missing type for `const` or `static` +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 diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rs new file mode 100644 index 00000000000..d76aa7a205b --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rs @@ -0,0 +1 @@ +static C: u32 = 0; diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rast new file mode 100644 index 00000000000..cde3e47ad5c --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rast @@ -0,0 +1,44 @@ +SOURCE_FILE + STATIC + STATIC_KW "static" + WHITESPACE " " + NAME + IDENT "C" + COLON ":" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u32" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + WHITESPACE "\n" + ERROR + WHERE_KW "where" + WHITESPACE " " + ERROR + PATH + PATH_SEGMENT + NAME_REF + IDENT "i32" + ERROR + COLON ":" + WHITESPACE " " + ERROR + PATH + PATH_SEGMENT + NAME_REF + IDENT "Copy" + ERROR + SEMICOLON ";" + WHITESPACE "\n" +error 17: expected SEMICOLON +error 18: expected an item +error 27: expected an item +error 27: expected an item +error 33: expected an item +error 33: expected an item diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rs new file mode 100644 index 00000000000..c330f35da24 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/static_where_clause.rs @@ -0,0 +1,2 @@ +static C: u32 = 0 +where i32: Copy; diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rast new file mode 100644 index 00000000000..12148f6afe4 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rast @@ -0,0 +1,89 @@ +SOURCE_FILE + CONST + CONST_KW "const" + WHITESPACE " " + NAME + IDENT "C" + GENERIC_PARAM_LIST + L_ANGLE "<" + TYPE_PARAM + NAME + IDENT "i32" + R_ANGLE ">" + COLON ":" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u32" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + WHERE_PRED + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "i32" + COLON ":" + WHITESPACE " " + TYPE_BOUND_LIST + TYPE_BOUND + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Copy" + SEMICOLON ";" + WHITESPACE "\n" + TRAIT + TRAIT_KW "trait" + WHITESPACE " " + NAME + IDENT "Foo" + WHITESPACE " " + ASSOC_ITEM_LIST + L_CURLY "{" + WHITESPACE "\n " + CONST + CONST_KW "const" + WHITESPACE " " + NAME + IDENT "C" + COLON ":" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "i32" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + WHERE_PRED + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "i32" + COLON ":" + WHITESPACE " " + TYPE_BOUND_LIST + TYPE_BOUND + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Copy" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rs new file mode 100644 index 00000000000..5ad4b2fe832 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_where_clause.rs @@ -0,0 +1,5 @@ +const C: u32 = 0 +where i32: Copy; +trait Foo { + const C: i32 where i32: Copy; +} diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rast new file mode 100644 index 00000000000..bf432b99b9d --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rast @@ -0,0 +1,71 @@ +SOURCE_FILE + CONST + CONST_KW "const" + WHITESPACE " " + NAME + IDENT "C" + GENERIC_PARAM_LIST + L_ANGLE "<" + TYPE_PARAM + NAME + IDENT "i32" + R_ANGLE ">" + COLON ":" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u32" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + SEMICOLON ";" + WHITESPACE "\n" + IMPL + IMPL_KW "impl" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Foo" + WHITESPACE " " + ASSOC_ITEM_LIST + L_CURLY "{" + WHITESPACE "\n " + CONST + CONST_KW "const" + WHITESPACE " " + NAME + IDENT "C" + GENERIC_PARAM_LIST + L_ANGLE "<" + LIFETIME_PARAM + LIFETIME + LIFETIME_IDENT "'a" + R_ANGLE ">" + COLON ":" + WHITESPACE " " + REF_TYPE + AMP "&" + LIFETIME + LIFETIME_IDENT "'a" + WHITESPACE " " + TUPLE_TYPE + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + EQ "=" + WHITESPACE " " + REF_EXPR + AMP "&" + TUPLE_EXPR + L_PAREN "(" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rs new file mode 100644 index 00000000000..ce718a46288 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/generic_const.rs @@ -0,0 +1,4 @@ +const C: u32 = 0; +impl Foo { + const C<'a>: &'a () = &(); +} diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 673334bd225..f8f9a51368e 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -287,8 +287,9 @@ VariantDef = Const = Attr* Visibility? 'default'? - 'const' (Name | '_') ':' Type - ('=' body:Expr)? ';' + 'const' (Name | '_') GenericParamList? ':' Type + ('=' body:Expr)? + WhereClause? ';' Static = Attr* Visibility? diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index fd23cdccd57..21548a8ea63 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -405,6 +405,7 @@ pub struct Const { } impl ast::HasAttrs for Const {} impl ast::HasDocComments for Const {} +impl ast::HasGenericParams for Const {} impl ast::HasName for Const {} impl ast::HasVisibility for Const {} impl Const { @@ -9421,7 +9422,7 @@ impl ast::HasGenericParams for AnyHasGenericParams {} impl AstNode for AnyHasGenericParams { #[inline] fn can_cast(kind: SyntaxKind) -> bool { - matches!(kind, ENUM | FN | IMPL | STRUCT | TRAIT | TRAIT_ALIAS | TYPE_ALIAS | UNION) + matches!(kind, CONST | ENUM | FN | IMPL | STRUCT | TRAIT | TRAIT_ALIAS | TYPE_ALIAS | UNION) } #[inline] fn cast(syntax: SyntaxNode) -> Option { @@ -9445,6 +9446,10 @@ impl fmt::Debug for AnyHasGenericParams { f.debug_struct("AnyHasGenericParams").field("syntax", &self.syntax).finish() } } +impl From for AnyHasGenericParams { + #[inline] + fn from(node: Const) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } } +} impl From for AnyHasGenericParams { #[inline] fn from(node: Enum) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } } -- cgit 1.4.1-3-g733a5 From fb5d3c36cd544774c909cc502e4738d74f9d21cc Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 21 Apr 2025 13:47:42 +0200 Subject: feat: parse `super let` --- .../crates/parser/src/grammar/expressions.rs | 5 +++-- .../test_data/parser/inline/ok/let_stmt.rast | 23 ++++++++++++++++++++++ .../parser/test_data/parser/inline/ok/let_stmt.rs | 2 +- src/tools/rust-analyzer/crates/syntax/rust.ungram | 2 +- .../crates/syntax/src/ast/generated/nodes.rs | 2 ++ 5 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src/tools/rust-analyzer/crates/syntax/rust.ungram') diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs index 5b0085fc2a0..34dcf2a1822 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs @@ -58,7 +58,7 @@ pub(super) fn stmt(p: &mut Parser<'_>, semicolon: Semicolon) { // } attributes::outer_attrs(p); - if p.at(T![let]) { + if p.at(T![let]) || (p.at(T![super]) && p.nth_at(1, T![let])) { let_stmt(p, semicolon); m.complete(p, LET_STMT); return; @@ -113,8 +113,9 @@ pub(super) fn stmt(p: &mut Parser<'_>, semicolon: Semicolon) { } // test let_stmt -// fn f() { let x: i32 = 92; } +// fn f() { let x: i32 = 92; super let y; super::foo; } pub(super) fn let_stmt(p: &mut Parser<'_>, with_semi: Semicolon) { + p.eat(T![super]); p.bump(T![let]); patterns::pattern(p); if p.at(T![:]) { diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rast index de9d0fc19ee..d99dad4cedd 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rast @@ -32,5 +32,28 @@ SOURCE_FILE INT_NUMBER "92" SEMICOLON ";" WHITESPACE " " + LET_STMT + SUPER_KW "super" + WHITESPACE " " + LET_KW "let" + WHITESPACE " " + IDENT_PAT + NAME + IDENT "y" + SEMICOLON ";" + WHITESPACE " " + EXPR_STMT + PATH_EXPR + PATH + PATH + PATH_SEGMENT + NAME_REF + SUPER_KW "super" + COLON2 "::" + PATH_SEGMENT + NAME_REF + IDENT "foo" + SEMICOLON ";" + WHITESPACE " " R_CURLY "}" WHITESPACE "\n" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rs index 8003999fd08..d4cc1be4aec 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/let_stmt.rs @@ -1 +1 @@ -fn f() { let x: i32 = 92; } +fn f() { let x: i32 = 92; super let y; super::foo; } diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 673334bd225..a055ed7f2fc 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -348,7 +348,7 @@ Stmt = | LetStmt LetStmt = - Attr* 'let' Pat (':' Type)? + Attr* 'super'? 'let' Pat (':' Type)? '=' initializer:Expr LetElse? ';' diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index fd23cdccd57..83ef2d24287 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -823,6 +823,8 @@ impl LetStmt { pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![=]) } #[inline] pub fn let_token(&self) -> Option { support::token(&self.syntax, T![let]) } + #[inline] + pub fn super_token(&self) -> Option { support::token(&self.syntax, T![super]) } } pub struct Lifetime { pub(crate) syntax: SyntaxNode, -- cgit 1.4.1-3-g733a5