aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_syntax/src/grammar/expressions.rs50
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.txt73
3 files changed, 108 insertions, 20 deletions
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs
index 1604d9b5a..0b2f7b116 100644
--- a/crates/ra_syntax/src/grammar/expressions.rs
+++ b/crates/ra_syntax/src/grammar/expressions.rs
@@ -54,6 +54,7 @@ pub(crate) fn block(p: &mut Parser) {
54 _ => { 54 _ => {
55 // test block_items 55 // test block_items
56 // fn a() { fn b() {} } 56 // fn a() { fn b() {} }
57 let has_attrs = p.at(POUND);
57 let m = p.start(); 58 let m = p.start();
58 match items::maybe_item(p, items::ItemFlavor::Mod) { 59 match items::maybe_item(p, items::ItemFlavor::Mod) {
59 items::MaybeItem::Item(kind) => { 60 items::MaybeItem::Item(kind) => {
@@ -66,30 +67,39 @@ pub(crate) fn block(p: &mut Parser) {
66 // test pub_expr 67 // test pub_expr
67 // fn foo() { pub 92; } //FIXME 68 // fn foo() { pub 92; } //FIXME
68 items::MaybeItem::None => { 69 items::MaybeItem::None => {
69 let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; 70 if has_attrs {
70 if p.at(R_CURLY) {
71 m.abandon(p); 71 m.abandon(p);
72 if p.at(LET_KW) {
73 let_stmt(p);
74 } else {
75 p.error("expected a let statement");
76 }
72 } else { 77 } else {
73 // test no_semi_after_block 78 let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block;
74 // fn foo() { 79 if p.at(R_CURLY) {
75 // if true {} 80 m.abandon(p);
76 // loop {}
77 // match () {}
78 // while true {}
79 // for _ in () {}
80 // {}
81 // {}
82 // macro_rules! test {
83 // () => {}
84 // }
85 // test!{}
86 // }
87 if is_blocklike {
88 p.eat(SEMI);
89 } else { 81 } else {
90 p.expect(SEMI); 82 // test no_semi_after_block
83 // fn foo() {
84 // if true {}
85 // loop {}
86 // match () {}
87 // while true {}
88 // for _ in () {}
89 // {}
90 // {}
91 // macro_rules! test {
92 // () => {}
93 // }
94 // test!{}
95 // }
96 if is_blocklike {
97 p.eat(SEMI);
98 } else {
99 p.expect(SEMI);
100 }
101 m.complete(p, EXPR_STMT);
91 } 102 }
92 m.complete(p, EXPR_STMT);
93 } 103 }
94 } 104 }
95 } 105 }
diff --git a/crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.rs b/crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.rs
new file mode 100644
index 000000000..325a97aeb
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.rs
@@ -0,0 +1,5 @@
1// https://github.com/rust-analyzer/rust-analyzer/issues/677
2fn main() {
3 #[cfg(feature = "backtrace")]
4 let exit_code = panic::catch_unwind(move || main());
5}
diff --git a/crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.txt b/crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.txt
new file mode 100644
index 000000000..b3f37dd96
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/ok/0044_let_attrs.txt
@@ -0,0 +1,73 @@
1SOURCE_FILE@[0; 166)
2 FN_DEF@[0; 165)
3 COMMENT@[0; 60)
4 WHITESPACE@[60; 61)
5 FN_KW@[61; 63)
6 WHITESPACE@[63; 64)
7 NAME@[64; 68)
8 IDENT@[64; 68) "main"
9 PARAM_LIST@[68; 70)
10 L_PAREN@[68; 69)
11 R_PAREN@[69; 70)
12 WHITESPACE@[70; 71)
13 BLOCK@[71; 165)
14 L_CURLY@[71; 72)
15 WHITESPACE@[72; 77)
16 ATTR@[77; 106)
17 POUND@[77; 78)
18 TOKEN_TREE@[78; 106)
19 L_BRACK@[78; 79)
20 IDENT@[79; 82) "cfg"
21 TOKEN_TREE@[82; 105)
22 L_PAREN@[82; 83)
23 IDENT@[83; 90) "feature"
24 WHITESPACE@[90; 91)
25 EQ@[91; 92)
26 WHITESPACE@[92; 93)
27 STRING@[93; 104)
28 R_PAREN@[104; 105)
29 R_BRACK@[105; 106)
30 WHITESPACE@[106; 111)
31 LET_STMT@[111; 163)
32 LET_KW@[111; 114)
33 WHITESPACE@[114; 115)
34 BIND_PAT@[115; 124)
35 NAME@[115; 124)
36 IDENT@[115; 124) "exit_code"
37 WHITESPACE@[124; 125)
38 EQ@[125; 126)
39 WHITESPACE@[126; 127)
40 CALL_EXPR@[127; 162)
41 PATH_EXPR@[127; 146)
42 PATH@[127; 146)
43 PATH@[127; 132)
44 PATH_SEGMENT@[127; 132)
45 NAME_REF@[127; 132)
46 IDENT@[127; 132) "panic"
47 COLONCOLON@[132; 134)
48 PATH_SEGMENT@[134; 146)
49 NAME_REF@[134; 146)
50 IDENT@[134; 146) "catch_unwind"
51 ARG_LIST@[146; 162)
52 L_PAREN@[146; 147)
53 LAMBDA_EXPR@[147; 161)
54 MOVE_KW@[147; 151)
55 WHITESPACE@[151; 152)
56 PARAM_LIST@[152; 154)
57 PIPE@[152; 153)
58 PIPE@[153; 154)
59 WHITESPACE@[154; 155)
60 CALL_EXPR@[155; 161)
61 PATH_EXPR@[155; 159)
62 PATH@[155; 159)
63 PATH_SEGMENT@[155; 159)
64 NAME_REF@[155; 159)
65 IDENT@[155; 159) "main"
66 ARG_LIST@[159; 161)
67 L_PAREN@[159; 160)
68 R_PAREN@[160; 161)
69 R_PAREN@[161; 162)
70 SEMI@[162; 163)
71 WHITESPACE@[163; 164)
72 R_CURLY@[164; 165)
73 WHITESPACE@[165; 166)