aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs35
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs4
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt55
3 files changed, 82 insertions, 12 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index e35c46a5e..c8ce07179 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -38,6 +38,13 @@ pub(crate) fn block(p: &mut Parser) {
38 m.complete(p, BLOCK); 38 m.complete(p, BLOCK);
39} 39}
40 40
41fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
42 match kind {
43 BIN_EXPR | RANGE_EXPR | IF_EXPR => false,
44 _ => true,
45 }
46}
47
41pub(crate) fn expr_block_contents(p: &mut Parser) { 48pub(crate) fn expr_block_contents(p: &mut Parser) {
42 // This is checked by a validator 49 // This is checked by a validator
43 attributes::inner_attributes(p); 50 attributes::inner_attributes(p);
@@ -62,6 +69,7 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
62 // #[C] #[D] {} 69 // #[C] #[D] {}
63 // #[D] return (); 70 // #[D] return ();
64 // } 71 // }
72 let has_attrs = p.at(POUND);
65 attributes::outer_attributes(p); 73 attributes::outer_attributes(p);
66 if p.at(LET_KW) { 74 if p.at(LET_KW) {
67 let_stmt(p, m); 75 let_stmt(p, m);
@@ -74,18 +82,17 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
74 }; 82 };
75 83
76 let (cm, blocklike) = expr_stmt(p); 84 let (cm, blocklike) = expr_stmt(p);
77 let cm = match cm { 85
78 None => { 86 if let Some(cm) = &cm {
79 if p.at(R_CURLY) { 87 if has_attrs && !is_expr_stmt_attr_allowed(cm.kind()) {
80 m.abandon(p); 88 // test_err attr_on_expr_not_allowed
81 } else { 89 // fn foo() {
82 p.expect(SEMI); 90 // #[A] 1 + 2;
83 m.complete(p, EXPR_STMT); 91 // #[B] if true {};
84 } 92 // }
85 continue; 93 p.error(format!("attributes are not allowed on {:?}", cm.kind()));
86 } 94 }
87 Some(cm) => cm, 95 }
88 };
89 96
90 if p.at(R_CURLY) { 97 if p.at(R_CURLY) {
91 // test attr_on_last_expr_in_block 98 // test attr_on_last_expr_in_block
@@ -93,7 +100,11 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
93 // { #[A] bar!()? } 100 // { #[A] bar!()? }
94 // #[B] &() 101 // #[B] &()
95 // } 102 // }
96 m.contract_child(p, cm); 103 if let Some(cm) = cm {
104 m.contract_child(p, cm);
105 } else {
106 m.abandon(p);
107 }
97 } else { 108 } else {
98 // test no_semi_after_block 109 // test no_semi_after_block
99 // fn foo() { 110 // fn foo() {
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs
new file mode 100644
index 000000000..d725a07ce
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.rs
@@ -0,0 +1,4 @@
1fn foo() {
2 #[A] 1 + 2;
3 #[B] if true {};
4}
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
new file mode 100644
index 000000000..fdea1ec1e
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0009_attr_on_expr_not_allowed.txt
@@ -0,0 +1,55 @@
1SOURCE_FILE@[0; 48)
2 FN_DEF@[0; 47)
3 FN_KW@[0; 2)
4 WHITESPACE@[2; 3)
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 47)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 14)
14 EXPR_STMT@[14; 25)
15 ATTR@[14; 18)
16 POUND@[14; 15)
17 TOKEN_TREE@[15; 18)
18 L_BRACK@[15; 16)
19 IDENT@[16; 17) "A"
20 R_BRACK@[17; 18)
21 WHITESPACE@[18; 19)
22 BIN_EXPR@[19; 24)
23 LITERAL@[19; 20)
24 INT_NUMBER@[19; 20) "1"
25 WHITESPACE@[20; 21)
26 PLUS@[21; 22)
27 WHITESPACE@[22; 23)
28 LITERAL@[23; 24)
29 INT_NUMBER@[23; 24) "2"
30 err: `attributes are not allowed on BIN_EXPR`
31 SEMI@[24; 25)
32 WHITESPACE@[25; 29)
33 EXPR_STMT@[29; 45)
34 ATTR@[29; 33)
35 POUND@[29; 30)
36 TOKEN_TREE@[30; 33)
37 L_BRACK@[30; 31)
38 IDENT@[31; 32) "B"
39 R_BRACK@[32; 33)
40 WHITESPACE@[33; 34)
41 IF_EXPR@[34; 44)
42 IF_KW@[34; 36)
43 WHITESPACE@[36; 37)
44 CONDITION@[37; 41)
45 LITERAL@[37; 41)
46 TRUE_KW@[37; 41)
47 WHITESPACE@[41; 42)
48 BLOCK@[42; 44)
49 L_CURLY@[42; 43)
50 R_CURLY@[43; 44)
51 err: `attributes are not allowed on IF_EXPR`
52 SEMI@[44; 45)
53 WHITESPACE@[45; 46)
54 R_CURLY@[46; 47)
55 WHITESPACE@[47; 48)