diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 9f282c74d3..53bb26c5ff 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs @@ -93,6 +93,11 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar } } + ASYNC_KW if la == L_CURLY => { + let m = p.start(); + p.bump(); + block_expr(p, Some(m)) + } MATCH_KW => match_expr(p), UNSAFE_KW if la == L_CURLY => { let m = p.start(); diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index ab9d2de906..91f9bfe8a7 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs @@ -86,9 +86,14 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { } let mut has_mods = false; - // modifiers - has_mods |= p.eat(CONST_KW); + // modifiers + + has_mods |= p.eat(CONST_KW); + if p.at(ASYNC_KW) && p.nth(1) != L_CURLY { + p.eat(ASYNC_KW); + has_mods = true; + } // test_err unsafe_block_in_mod // fn foo(){} unsafe { } fn bar(){} if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY { @@ -110,6 +115,9 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { // items let kind = match p.current() { + // test async_fn + // async fn foo() {} + // test extern_fn // extern fn foo() {} diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 0eed44ecfd..03247ae38c 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs @@ -66,6 +66,7 @@ pub enum SyntaxKind { SHR, SHLEQ, SHREQ, + ASYNC_KW, USE_KW, FN_KW, STRUCT_KW, @@ -233,6 +234,7 @@ use self::SyntaxKind::*; impl SyntaxKind { pub fn is_keyword(self) -> bool { match self { + | ASYNC_KW | USE_KW | FN_KW | STRUCT_KW @@ -403,6 +405,7 @@ impl SyntaxKind { SHR => &SyntaxInfo { name: "SHR" }, SHLEQ => &SyntaxInfo { name: "SHLEQ" }, SHREQ => &SyntaxInfo { name: "SHREQ" }, + ASYNC_KW => &SyntaxInfo { name: "ASYNC_KW" }, USE_KW => &SyntaxInfo { name: "USE_KW" }, FN_KW => &SyntaxInfo { name: "FN_KW" }, STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" }, @@ -570,6 +573,7 @@ impl SyntaxKind { } pub fn from_keyword(ident: &str) -> Option { let kw = match ident { + "async" => ASYNC_KW, "use" => USE_KW, "fn" => FN_KW, "struct" => STRUCT_KW, diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index b7a2d1c01b..66f1339c10 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -59,6 +59,7 @@ Grammar( [">>=", "SHREQ"], ], keywords: [ + "async", "use", "fn", "struct", diff --git a/crates/ra_syntax/tests/data/lexer/0011_keywords.rs b/crates/ra_syntax/tests/data/lexer/0011_keywords.rs index e6bf64d4d6..1e91bff4e7 100644 --- a/crates/ra_syntax/tests/data/lexer/0011_keywords.rs +++ b/crates/ra_syntax/tests/data/lexer/0011_keywords.rs @@ -1,3 +1,3 @@ -fn use struct trait enum impl true false as extern crate +async fn use struct trait enum impl true false as extern crate mod pub self super in where for loop while if match const static mut type ref let else move return diff --git a/crates/ra_syntax/tests/data/lexer/0011_keywords.txt b/crates/ra_syntax/tests/data/lexer/0011_keywords.txt index d6a1abe8ac..22c00eefb6 100644 --- a/crates/ra_syntax/tests/data/lexer/0011_keywords.txt +++ b/crates/ra_syntax/tests/data/lexer/0011_keywords.txt @@ -1,3 +1,5 @@ +ASYNC_KW 5 "async" +WHITESPACE 1 " " FN_KW 2 "fn" WHITESPACE 1 " " USE_KW 3 "use" diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0124_async_fn.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0124_async_fn.rs new file mode 100644 index 0000000000..f4adcb62b3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0124_async_fn.rs @@ -0,0 +1 @@ +async fn foo() {} diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0124_async_fn.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0124_async_fn.txt new file mode 100644 index 0000000000..d1a706ecc3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0124_async_fn.txt @@ -0,0 +1,16 @@ +SOURCE_FILE@[0; 18) + FN_DEF@[0; 17) + ASYNC_KW@[0; 5) + WHITESPACE@[5; 6) + FN_KW@[6; 8) + WHITESPACE@[8; 9) + NAME@[9; 12) + IDENT@[9; 12) "foo" + PARAM_LIST@[12; 14) + L_PAREN@[12; 13) + R_PAREN@[13; 14) + WHITESPACE@[14; 15) + BLOCK@[15; 17) + L_CURLY@[15; 16) + R_CURLY@[16; 17) + WHITESPACE@[17; 18)