Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs8
-rw-r--r--crates/parser/test_data/parser/inline/ok/0205_const_closure.rast42
-rw-r--r--crates/parser/test_data/parser/inline/ok/0205_const_closure.rs1
-rw-r--r--crates/syntax/rust.ungram2
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs1
5 files changed, 50 insertions, 4 deletions
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index efa3997353..a23f900b73 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -152,7 +152,7 @@ pub(super) fn atom_expr(
m.complete(p, BLOCK_EXPR)
}
- T![static] | T![async] | T![move] | T![|] => closure_expr(p),
+ T![const] | T![static] | T![async] | T![move] | T![|] => closure_expr(p),
T![for] if la == T![<] => closure_expr(p),
T![for] => for_expr(p, None),
@@ -255,7 +255,7 @@ fn array_expr(p: &mut Parser<'_>) -> CompletedMarker {
// }
fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker {
assert!(match p.current() {
- T![static] | T![async] | T![move] | T![|] => true,
+ T![const] | T![static] | T![async] | T![move] | T![|] => true,
T![for] => p.nth(1) == T![<],
_ => false,
});
@@ -265,7 +265,9 @@ fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker {
if p.at(T![for]) {
types::for_binder(p);
}
-
+ // test const_closure
+ // fn main() { let cl = const || _ = 0; }
+ p.eat(T![const]);
p.eat(T![static]);
p.eat(T![async]);
p.eat(T![move]);
diff --git a/crates/parser/test_data/parser/inline/ok/0205_const_closure.rast b/crates/parser/test_data/parser/inline/ok/0205_const_closure.rast
new file mode 100644
index 0000000000..06442a1d0f
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0205_const_closure.rast
@@ -0,0 +1,42 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "main"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "cl"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ CLOSURE_EXPR
+ CONST_KW "const"
+ WHITESPACE " "
+ PARAM_LIST
+ PIPE "|"
+ PIPE "|"
+ WHITESPACE " "
+ BIN_EXPR
+ UNDERSCORE_EXPR
+ UNDERSCORE "_"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ LITERAL
+ INT_NUMBER "0"
+ SEMICOLON ";"
+ WHITESPACE " "
+ R_CURLY "}"
+ WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/0205_const_closure.rs b/crates/parser/test_data/parser/inline/ok/0205_const_closure.rs
new file mode 100644
index 0000000000..0c05cc70bd
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0205_const_closure.rs
@@ -0,0 +1 @@
+fn main() { let cl = const || _ = 0; }
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index 2c67586a39..36ad5fddfd 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -452,7 +452,7 @@ FieldExpr =
Attr* Expr '.' NameRef
ClosureExpr =
- Attr* ('for' GenericParamList)? 'static'? 'async'? 'move'? ParamList RetType?
+ Attr* ('for' GenericParamList)? 'const'? 'static'? 'async'? 'move'? ParamList RetType?
body:Expr
IfExpr =
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index a214a5e446..642a3bfc35 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -842,6 +842,7 @@ impl ast::HasAttrs for ClosureExpr {}
impl ClosureExpr {
pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
+ pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
pub fn move_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![move]) }