diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-03 16:33:58 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-03 16:33:58 +0100 |
commit | 84d8665e13007b0ee27e2a42ff74db815923cdce (patch) | |
tree | f60577c56dc805a54683359ecc6f2e08575fd65e | |
parent | f1ac9c8f558832f260bdd8b998fb1d7fbbcb6db5 (diff) | |
parent | 636270f4a4f80f5d24571147bcadfbeaa29310a0 (diff) |
Merge #1101
1101: Parse unsafe async / const unsafe fns properly r=matklad a=robojumper
Also adds tests that `unsafe async fn` as well as `const unsafe fn` parse properly and that these keywords in the reversed order cause parse errors.
[Playground link to verify that this is the correct order.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=7850b8d92579de31c38f835f76afa4ce)
Closes #1086.
Co-authored-by: robojumper <[email protected]>
5 files changed, 95 insertions, 6 deletions
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs index c4b8ef3c7..318fd69a1 100644 --- a/crates/ra_parser/src/grammar/items.rs +++ b/crates/ra_parser/src/grammar/items.rs | |||
@@ -79,19 +79,22 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul | |||
79 | let mut has_mods = false; | 79 | let mut has_mods = false; |
80 | 80 | ||
81 | // modifiers | 81 | // modifiers |
82 | // test_err async_without_semicolon | ||
83 | // fn foo() { let _ = async {} } | ||
84 | has_mods |= p.eat(CONST_KW); | 82 | has_mods |= p.eat(CONST_KW); |
85 | if p.at(ASYNC_KW) && p.nth(1) != L_CURLY && p.nth(1) != MOVE_KW && p.nth(1) != PIPE { | 83 | |
86 | p.eat(ASYNC_KW); | ||
87 | has_mods = true; | ||
88 | } | ||
89 | // test_err unsafe_block_in_mod | 84 | // test_err unsafe_block_in_mod |
90 | // fn foo(){} unsafe { } fn bar(){} | 85 | // fn foo(){} unsafe { } fn bar(){} |
91 | if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY { | 86 | if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY { |
92 | p.eat(UNSAFE_KW); | 87 | p.eat(UNSAFE_KW); |
93 | has_mods = true; | 88 | has_mods = true; |
94 | } | 89 | } |
90 | |||
91 | // test_err async_without_semicolon | ||
92 | // fn foo() { let _ = async {} } | ||
93 | if p.at(ASYNC_KW) && p.nth(1) != L_CURLY && p.nth(1) != MOVE_KW && p.nth(1) != PIPE { | ||
94 | p.eat(ASYNC_KW); | ||
95 | has_mods = true; | ||
96 | } | ||
97 | |||
95 | if p.at(EXTERN_KW) { | 98 | if p.at(EXTERN_KW) { |
96 | has_mods = true; | 99 | has_mods = true; |
97 | abi(p); | 100 | abi(p); |
@@ -124,6 +127,14 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul | |||
124 | 127 | ||
125 | // test unsafe_fn | 128 | // test unsafe_fn |
126 | // unsafe fn foo() {} | 129 | // unsafe fn foo() {} |
130 | |||
131 | // test combined_fns | ||
132 | // unsafe async fn foo() {} | ||
133 | // const unsafe fn bar() {} | ||
134 | |||
135 | // test_err wrong_order_fns | ||
136 | // async unsafe fn foo() {} | ||
137 | // unsafe const fn bar() {} | ||
127 | FN_KW => { | 138 | FN_KW => { |
128 | fn_def(p, flavor); | 139 | fn_def(p, flavor); |
129 | m.complete(p, FN_DEF); | 140 | m.complete(p, FN_DEF); |
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.rs b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.rs new file mode 100644 index 000000000..16edee95d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | async unsafe fn foo() {} | ||
2 | unsafe const fn bar() {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt new file mode 100644 index 000000000..220191ffa --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/err/0010_wrong_order_fns.txt | |||
@@ -0,0 +1,39 @@ | |||
1 | SOURCE_FILE@[0; 50) | ||
2 | ERROR@[0; 5) | ||
3 | ASYNC_KW@[0; 5) "async" | ||
4 | err: `expected fn, trait or impl` | ||
5 | WHITESPACE@[5; 6) " " | ||
6 | FN_DEF@[6; 24) | ||
7 | UNSAFE_KW@[6; 12) "unsafe" | ||
8 | WHITESPACE@[12; 13) " " | ||
9 | FN_KW@[13; 15) "fn" | ||
10 | WHITESPACE@[15; 16) " " | ||
11 | NAME@[16; 19) | ||
12 | IDENT@[16; 19) "foo" | ||
13 | PARAM_LIST@[19; 21) | ||
14 | L_PAREN@[19; 20) "(" | ||
15 | R_PAREN@[20; 21) ")" | ||
16 | WHITESPACE@[21; 22) " " | ||
17 | BLOCK@[22; 24) | ||
18 | L_CURLY@[22; 23) "{" | ||
19 | R_CURLY@[23; 24) "}" | ||
20 | WHITESPACE@[24; 25) "\n" | ||
21 | ERROR@[25; 31) | ||
22 | UNSAFE_KW@[25; 31) "unsafe" | ||
23 | err: `expected fn, trait or impl` | ||
24 | WHITESPACE@[31; 32) " " | ||
25 | FN_DEF@[32; 49) | ||
26 | CONST_KW@[32; 37) "const" | ||
27 | WHITESPACE@[37; 38) " " | ||
28 | FN_KW@[38; 40) "fn" | ||
29 | WHITESPACE@[40; 41) " " | ||
30 | NAME@[41; 44) | ||
31 | IDENT@[41; 44) "bar" | ||
32 | PARAM_LIST@[44; 46) | ||
33 | L_PAREN@[44; 45) "(" | ||
34 | R_PAREN@[45; 46) ")" | ||
35 | WHITESPACE@[46; 47) " " | ||
36 | BLOCK@[47; 49) | ||
37 | L_CURLY@[47; 48) "{" | ||
38 | R_CURLY@[48; 49) "}" | ||
39 | WHITESPACE@[49; 50) "\n" | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0128_combined_fns.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0128_combined_fns.rs new file mode 100644 index 000000000..46af91b82 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0128_combined_fns.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | unsafe async fn foo() {} | ||
2 | const unsafe fn bar() {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0128_combined_fns.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0128_combined_fns.txt new file mode 100644 index 000000000..2a16aeb61 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0128_combined_fns.txt | |||
@@ -0,0 +1,35 @@ | |||
1 | SOURCE_FILE@[0; 50) | ||
2 | FN_DEF@[0; 24) | ||
3 | UNSAFE_KW@[0; 6) "unsafe" | ||
4 | WHITESPACE@[6; 7) " " | ||
5 | ASYNC_KW@[7; 12) "async" | ||
6 | WHITESPACE@[12; 13) " " | ||
7 | FN_KW@[13; 15) "fn" | ||
8 | WHITESPACE@[15; 16) " " | ||
9 | NAME@[16; 19) | ||
10 | IDENT@[16; 19) "foo" | ||
11 | PARAM_LIST@[19; 21) | ||
12 | L_PAREN@[19; 20) "(" | ||
13 | R_PAREN@[20; 21) ")" | ||
14 | WHITESPACE@[21; 22) " " | ||
15 | BLOCK@[22; 24) | ||
16 | L_CURLY@[22; 23) "{" | ||
17 | R_CURLY@[23; 24) "}" | ||
18 | WHITESPACE@[24; 25) "\n" | ||
19 | FN_DEF@[25; 49) | ||
20 | CONST_KW@[25; 30) "const" | ||
21 | WHITESPACE@[30; 31) " " | ||
22 | UNSAFE_KW@[31; 37) "unsafe" | ||
23 | WHITESPACE@[37; 38) " " | ||
24 | FN_KW@[38; 40) "fn" | ||
25 | WHITESPACE@[40; 41) " " | ||
26 | NAME@[41; 44) | ||
27 | IDENT@[41; 44) "bar" | ||
28 | PARAM_LIST@[44; 46) | ||
29 | L_PAREN@[44; 45) "(" | ||
30 | R_PAREN@[45; 46) ")" | ||
31 | WHITESPACE@[46; 47) " " | ||
32 | BLOCK@[47; 49) | ||
33 | L_CURLY@[47; 48) "{" | ||
34 | R_CURLY@[48; 49) "}" | ||
35 | WHITESPACE@[49; 50) "\n" | ||