aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_syntax/src/ast.rs14
-rw-r--r--crates/ra_syntax/src/ast/generated.rs2
-rw-r--r--crates/ra_syntax/src/grammar.ron4
-rw-r--r--crates/ra_syntax/src/grammar/attributes.rs10
-rw-r--r--crates/ra_syntax/src/grammar/expressions/atom.rs33
-rw-r--r--crates/ra_syntax/src/syntax_node/syntax_error.rs4
-rw-r--r--crates/ra_syntax/src/validation.rs2
-rw-r--r--crates/ra_syntax/src/validation/match_armlist.rs28
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.rs20
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt173
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.rs7
-rw-r--r--crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt64
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.rs8
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.txt74
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.rs12
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt135
16 files changed, 589 insertions, 1 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 22105d6c9..350f01f33 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -153,6 +153,20 @@ impl FnDef {
153} 153}
154 154
155impl Attr { 155impl Attr {
156 pub fn is_inner(&self) -> bool {
157 let tt = match self.value() {
158 None => return false,
159 Some(tt) => tt,
160 };
161
162 let prev = match tt.syntax().prev_sibling() {
163 None => return false,
164 Some(prev) => prev,
165 };
166
167 prev.kind() == EXCL
168 }
169
156 pub fn as_atom(&self) -> Option<SmolStr> { 170 pub fn as_atom(&self) -> Option<SmolStr> {
157 let tt = self.value()?; 171 let tt = self.value()?;
158 let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; 172 let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?;
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index dd91b5063..c7aaccc95 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -1946,6 +1946,7 @@ impl ToOwned for MatchArm {
1946} 1946}
1947 1947
1948 1948
1949impl ast::AttrsOwner for MatchArm {}
1949impl MatchArm { 1950impl MatchArm {
1950 pub fn pats(&self) -> impl Iterator<Item = &Pat> { 1951 pub fn pats(&self) -> impl Iterator<Item = &Pat> {
1951 super::children(self) 1952 super::children(self)
@@ -1986,6 +1987,7 @@ impl ToOwned for MatchArmList {
1986} 1987}
1987 1988
1988 1989
1990impl ast::AttrsOwner for MatchArmList {}
1989impl MatchArmList { 1991impl MatchArmList {
1990 pub fn arms(&self) -> impl Iterator<Item = &MatchArm> { 1992 pub fn arms(&self) -> impl Iterator<Item = &MatchArm> {
1991 super::children(self) 1993 super::children(self)
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 27a123681..193b563aa 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -413,13 +413,15 @@ Grammar(
413 ), 413 ),
414 "MatchArmList": ( 414 "MatchArmList": (
415 collections: [ ["arms", "MatchArm"] ], 415 collections: [ ["arms", "MatchArm"] ],
416 traits: [ "AttrsOwner" ]
416 ), 417 ),
417 "MatchArm": ( 418 "MatchArm": (
418 options: [ 419 options: [
419 [ "guard", "MatchGuard" ], 420 [ "guard", "MatchGuard" ],
420 "Expr", 421 "Expr",
421 ], 422 ],
422 collections: [ [ "pats", "Pat" ] ] 423 collections: [ [ "pats", "Pat" ] ],
424 traits: [ "AttrsOwner" ]
423 ), 425 ),
424 "MatchGuard": (options: ["Expr"]), 426 "MatchGuard": (options: ["Expr"]),
425 "StructLit": (options: ["Path", "NamedFieldList", ["spread", "Expr"]]), 427 "StructLit": (options: ["Path", "NamedFieldList", ["spread", "Expr"]]),
diff --git a/crates/ra_syntax/src/grammar/attributes.rs b/crates/ra_syntax/src/grammar/attributes.rs
index cd30e8a45..2624d2e16 100644
--- a/crates/ra_syntax/src/grammar/attributes.rs
+++ b/crates/ra_syntax/src/grammar/attributes.rs
@@ -1,5 +1,15 @@
1use super::*; 1use super::*;
2 2
3/// Parses both inner & outer attributes.
4///
5/// Allowing to run validation for reporting errors
6/// regarding attributes
7pub(super) fn all_attributes(p: &mut Parser) {
8 while p.at(POUND) {
9 attribute(p, p.nth(1) == EXCL)
10 }
11}
12
3pub(super) fn inner_attributes(p: &mut Parser) { 13pub(super) fn inner_attributes(p: &mut Parser) {
4 while p.current() == POUND && p.nth(1) == EXCL { 14 while p.current() == POUND && p.nth(1) == EXCL {
5 attribute(p, true) 15 attribute(p, true)
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs
index 27ba87657..67cd7e6b0 100644
--- a/crates/ra_syntax/src/grammar/expressions/atom.rs
+++ b/crates/ra_syntax/src/grammar/expressions/atom.rs
@@ -313,11 +313,44 @@ pub(crate) fn match_arm_list(p: &mut Parser) {
313 assert!(p.at(L_CURLY)); 313 assert!(p.at(L_CURLY));
314 let m = p.start(); 314 let m = p.start();
315 p.eat(L_CURLY); 315 p.eat(L_CURLY);
316
317 // test match_arms_inner_attribute
318 // fn foo() {
319 // match () {
320 // #![doc("Inner attribute")]
321 // #![doc("Can be")]
322 // #![doc("Stacked")]
323 // _ => (),
324 // }
325 // }
326 attributes::inner_attributes(p);
327
316 while !p.at(EOF) && !p.at(R_CURLY) { 328 while !p.at(EOF) && !p.at(R_CURLY) {
317 if p.at(L_CURLY) { 329 if p.at(L_CURLY) {
318 error_block(p, "expected match arm"); 330 error_block(p, "expected match arm");
319 continue; 331 continue;
320 } 332 }
333
334 // This may result in invalid attributes
335 // if there are inner attributes mixed in together
336 // with the outer attributes, but we allow parsing
337 // those so we can run validation and report better errors
338
339 // test match_arms_outer_attributes
340 // fn foo() {
341 // match () {
342 // #[cfg(feature = "some")]
343 // _ => (),
344 // #[cfg(feature = "other")]
345 // _ => (),
346 // #[cfg(feature = "many")]
347 // #[cfg(feature = "attributes")]
348 // #[cfg(feature = "before")]
349 // _ => (),
350 // }
351 // }
352 attributes::all_attributes(p);
353
321 // test match_arms_commas 354 // test match_arms_commas
322 // fn foo() { 355 // fn foo() {
323 // match () { 356 // match () {
diff --git a/crates/ra_syntax/src/syntax_node/syntax_error.rs b/crates/ra_syntax/src/syntax_node/syntax_error.rs
index 412cf82cc..4ff998090 100644
--- a/crates/ra_syntax/src/syntax_node/syntax_error.rs
+++ b/crates/ra_syntax/src/syntax_node/syntax_error.rs
@@ -92,6 +92,7 @@ pub enum SyntaxErrorKind {
92 UnclosedString, 92 UnclosedString,
93 InvalidSuffix, 93 InvalidSuffix,
94 InvalidBlockAttr, 94 InvalidBlockAttr,
95 InvalidMatchInnerAttr,
95} 96}
96 97
97#[derive(Debug, Clone, PartialEq, Eq, Hash)] 98#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -136,6 +137,9 @@ impl fmt::Display for SyntaxErrorKind {
136 InvalidBlockAttr => { 137 InvalidBlockAttr => {
137 write!(f, "A block in this position cannot accept inner attributes") 138 write!(f, "A block in this position cannot accept inner attributes")
138 } 139 }
140 InvalidMatchInnerAttr => {
141 write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression")
142 }
139 ParseError(msg) => write!(f, "{}", msg.0), 143 ParseError(msg) => write!(f, "{}", msg.0),
140 } 144 }
141 } 145 }
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
index 10672d6bf..27a465a78 100644
--- a/crates/ra_syntax/src/validation.rs
+++ b/crates/ra_syntax/src/validation.rs
@@ -3,6 +3,7 @@ mod byte_string;
3mod char; 3mod char;
4mod string; 4mod string;
5mod block; 5mod block;
6mod match_armlist;
6 7
7use crate::{ 8use crate::{
8 SourceFile, syntax_node::SyntaxError, AstNode, 9 SourceFile, syntax_node::SyntaxError, AstNode,
@@ -19,6 +20,7 @@ pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> {
19 .visit::<ast::Char, _>(self::char::validate_char_node) 20 .visit::<ast::Char, _>(self::char::validate_char_node)
20 .visit::<ast::String, _>(self::string::validate_string_node) 21 .visit::<ast::String, _>(self::string::validate_string_node)
21 .visit::<ast::Block, _>(self::block::validate_block_node) 22 .visit::<ast::Block, _>(self::block::validate_block_node)
23 .visit::<ast::MatchArmList, _>(self::match_armlist::validate_match_armlist)
22 .accept(node); 24 .accept(node);
23 } 25 }
24 errors 26 errors
diff --git a/crates/ra_syntax/src/validation/match_armlist.rs b/crates/ra_syntax/src/validation/match_armlist.rs
new file mode 100644
index 000000000..c43ed7092
--- /dev/null
+++ b/crates/ra_syntax/src/validation/match_armlist.rs
@@ -0,0 +1,28 @@
1use crate::{
2 ast::{self, AttrsOwner, AstNode},
3 syntax_node::{
4 SyntaxError,
5 SyntaxErrorKind::*,
6 Direction,
7 },
8};
9
10pub(crate) fn validate_match_armlist(node: &ast::MatchArmList, errors: &mut Vec<SyntaxError>) {
11 // Report errors for any inner attribute
12 // which has a preceding matcharm or an outer attribute
13 for inner_attr in node.attrs().filter(|s| s.is_inner()) {
14 let any_errors = inner_attr.syntax().siblings(Direction::Prev).any(|s| {
15 match (ast::MatchArm::cast(s), ast::Attr::cast(s)) {
16 (Some(_), _) => true,
17 // Outer attributes which preceed an inner attribute are not allowed
18 (_, Some(a)) if !a.is_inner() => true,
19 (_, Some(_)) => false,
20 (None, None) => false,
21 }
22 });
23
24 if any_errors {
25 errors.push(SyntaxError::new(InvalidMatchInnerAttr, inner_attr.syntax().range()));
26 }
27 }
28}
diff --git a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.rs b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.rs
new file mode 100644
index 000000000..06aa47770
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.rs
@@ -0,0 +1,20 @@
1fn foo() {
2 match () {
3 _ => (),
4 #![doc("Not allowed here")]
5 _ => (),
6 }
7
8 match () {
9 _ => (),
10 _ => (),
11 #![doc("Nor here")]
12 }
13
14 match () {
15 #[cfg(test)]
16 #![doc("Nor here")]
17 _ => (),
18 _ => (),
19 }
20}
diff --git a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt
new file mode 100644
index 000000000..b3ff36364
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt
@@ -0,0 +1,173 @@
1SOURCE_FILE@[0; 293)
2 FN_DEF@[0; 292)
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; 292)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 EXPR_STMT@[15; 101)
15 MATCH_EXPR@[15; 101)
16 MATCH_KW@[15; 20)
17 WHITESPACE@[20; 21)
18 TUPLE_EXPR@[21; 23)
19 L_PAREN@[21; 22)
20 R_PAREN@[22; 23)
21 WHITESPACE@[23; 24)
22 MATCH_ARM_LIST@[24; 101)
23 L_CURLY@[24; 25)
24 WHITESPACE@[25; 34)
25 MATCH_ARM@[34; 41)
26 PLACEHOLDER_PAT@[34; 35)
27 UNDERSCORE@[34; 35)
28 WHITESPACE@[35; 36)
29 FAT_ARROW@[36; 38)
30 WHITESPACE@[38; 39)
31 TUPLE_EXPR@[39; 41)
32 L_PAREN@[39; 40)
33 R_PAREN@[40; 41)
34 COMMA@[41; 42)
35 WHITESPACE@[42; 51)
36 err: `Inner attributes are only allowed directly after the opening brace of the match expression`
37 ATTR@[51; 78)
38 POUND@[51; 52)
39 EXCL@[52; 53)
40 TOKEN_TREE@[53; 78)
41 L_BRACK@[53; 54)
42 IDENT@[54; 57) "doc"
43 TOKEN_TREE@[57; 77)
44 L_PAREN@[57; 58)
45 STRING@[58; 76)
46 R_PAREN@[76; 77)
47 R_BRACK@[77; 78)
48 WHITESPACE@[78; 87)
49 MATCH_ARM@[87; 94)
50 PLACEHOLDER_PAT@[87; 88)
51 UNDERSCORE@[87; 88)
52 WHITESPACE@[88; 89)
53 FAT_ARROW@[89; 91)
54 WHITESPACE@[91; 92)
55 TUPLE_EXPR@[92; 94)
56 L_PAREN@[92; 93)
57 R_PAREN@[93; 94)
58 COMMA@[94; 95)
59 WHITESPACE@[95; 100)
60 R_CURLY@[100; 101)
61 WHITESPACE@[101; 107)
62 EXPR_STMT@[107; 185)
63 MATCH_EXPR@[107; 185)
64 MATCH_KW@[107; 112)
65 WHITESPACE@[112; 113)
66 TUPLE_EXPR@[113; 115)
67 L_PAREN@[113; 114)
68 R_PAREN@[114; 115)
69 WHITESPACE@[115; 116)
70 MATCH_ARM_LIST@[116; 185)
71 L_CURLY@[116; 117)
72 WHITESPACE@[117; 126)
73 MATCH_ARM@[126; 133)
74 PLACEHOLDER_PAT@[126; 127)
75 UNDERSCORE@[126; 127)
76 WHITESPACE@[127; 128)
77 FAT_ARROW@[128; 130)
78 WHITESPACE@[130; 131)
79 TUPLE_EXPR@[131; 133)
80 L_PAREN@[131; 132)
81 R_PAREN@[132; 133)
82 COMMA@[133; 134)
83 WHITESPACE@[134; 143)
84 MATCH_ARM@[143; 150)
85 PLACEHOLDER_PAT@[143; 144)
86 UNDERSCORE@[143; 144)
87 WHITESPACE@[144; 145)
88 FAT_ARROW@[145; 147)
89 WHITESPACE@[147; 148)
90 TUPLE_EXPR@[148; 150)
91 L_PAREN@[148; 149)
92 R_PAREN@[149; 150)
93 COMMA@[150; 151)
94 WHITESPACE@[151; 160)
95 err: `Inner attributes are only allowed directly after the opening brace of the match expression`
96 ATTR@[160; 179)
97 POUND@[160; 161)
98 EXCL@[161; 162)
99 TOKEN_TREE@[162; 179)
100 L_BRACK@[162; 163)
101 IDENT@[163; 166) "doc"
102 TOKEN_TREE@[166; 178)
103 L_PAREN@[166; 167)
104 STRING@[167; 177)
105 R_PAREN@[177; 178)
106 R_BRACK@[178; 179)
107 WHITESPACE@[179; 184)
108 err: `expected pattern`
109 err: `expected FAT_ARROW`
110 err: `expected expression`
111 MATCH_ARM@[184; 184)
112 R_CURLY@[184; 185)
113 WHITESPACE@[185; 191)
114 MATCH_EXPR@[191; 290)
115 MATCH_KW@[191; 196)
116 WHITESPACE@[196; 197)
117 TUPLE_EXPR@[197; 199)
118 L_PAREN@[197; 198)
119 R_PAREN@[198; 199)
120 WHITESPACE@[199; 200)
121 MATCH_ARM_LIST@[200; 290)
122 L_CURLY@[200; 201)
123 WHITESPACE@[201; 210)
124 ATTR@[210; 222)
125 POUND@[210; 211)
126 TOKEN_TREE@[211; 222)
127 L_BRACK@[211; 212)
128 IDENT@[212; 215) "cfg"
129 TOKEN_TREE@[215; 221)
130 L_PAREN@[215; 216)
131 IDENT@[216; 220) "test"
132 R_PAREN@[220; 221)
133 R_BRACK@[221; 222)
134 WHITESPACE@[222; 231)
135 err: `Inner attributes are only allowed directly after the opening brace of the match expression`
136 ATTR@[231; 250)
137 POUND@[231; 232)
138 EXCL@[232; 233)
139 TOKEN_TREE@[233; 250)
140 L_BRACK@[233; 234)
141 IDENT@[234; 237) "doc"
142 TOKEN_TREE@[237; 249)
143 L_PAREN@[237; 238)
144 STRING@[238; 248)
145 R_PAREN@[248; 249)
146 R_BRACK@[249; 250)
147 WHITESPACE@[250; 259)
148 MATCH_ARM@[259; 266)
149 PLACEHOLDER_PAT@[259; 260)
150 UNDERSCORE@[259; 260)
151 WHITESPACE@[260; 261)
152 FAT_ARROW@[261; 263)
153 WHITESPACE@[263; 264)
154 TUPLE_EXPR@[264; 266)
155 L_PAREN@[264; 265)
156 R_PAREN@[265; 266)
157 COMMA@[266; 267)
158 WHITESPACE@[267; 276)
159 MATCH_ARM@[276; 283)
160 PLACEHOLDER_PAT@[276; 277)
161 UNDERSCORE@[276; 277)
162 WHITESPACE@[277; 278)
163 FAT_ARROW@[278; 280)
164 WHITESPACE@[280; 281)
165 TUPLE_EXPR@[281; 283)
166 L_PAREN@[281; 282)
167 R_PAREN@[282; 283)
168 COMMA@[283; 284)
169 WHITESPACE@[284; 289)
170 R_CURLY@[289; 290)
171 WHITESPACE@[290; 291)
172 R_CURLY@[291; 292)
173 WHITESPACE@[292; 293)
diff --git a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.rs b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.rs
new file mode 100644
index 000000000..4635222da
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.rs
@@ -0,0 +1,7 @@
1fn foo() {
2 match () {
3 _ => (),
4 _ => (),
5 #[cfg(test)]
6 }
7}
diff --git a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt
new file mode 100644
index 000000000..7f8767001
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt
@@ -0,0 +1,64 @@
1SOURCE_FILE@[0; 89)
2 FN_DEF@[0; 88)
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; 88)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 MATCH_EXPR@[15; 86)
15 MATCH_KW@[15; 20)
16 WHITESPACE@[20; 21)
17 TUPLE_EXPR@[21; 23)
18 L_PAREN@[21; 22)
19 R_PAREN@[22; 23)
20 WHITESPACE@[23; 24)
21 MATCH_ARM_LIST@[24; 86)
22 L_CURLY@[24; 25)
23 WHITESPACE@[25; 34)
24 MATCH_ARM@[34; 41)
25 PLACEHOLDER_PAT@[34; 35)
26 UNDERSCORE@[34; 35)
27 WHITESPACE@[35; 36)
28 FAT_ARROW@[36; 38)
29 WHITESPACE@[38; 39)
30 TUPLE_EXPR@[39; 41)
31 L_PAREN@[39; 40)
32 R_PAREN@[40; 41)
33 COMMA@[41; 42)
34 WHITESPACE@[42; 51)
35 MATCH_ARM@[51; 58)
36 PLACEHOLDER_PAT@[51; 52)
37 UNDERSCORE@[51; 52)
38 WHITESPACE@[52; 53)
39 FAT_ARROW@[53; 55)
40 WHITESPACE@[55; 56)
41 TUPLE_EXPR@[56; 58)
42 L_PAREN@[56; 57)
43 R_PAREN@[57; 58)
44 COMMA@[58; 59)
45 WHITESPACE@[59; 68)
46 ATTR@[68; 80)
47 POUND@[68; 69)
48 TOKEN_TREE@[69; 80)
49 L_BRACK@[69; 70)
50 IDENT@[70; 73) "cfg"
51 TOKEN_TREE@[73; 79)
52 L_PAREN@[73; 74)
53 IDENT@[74; 78) "test"
54 R_PAREN@[78; 79)
55 R_BRACK@[79; 80)
56 WHITESPACE@[80; 85)
57 err: `expected pattern`
58 err: `expected FAT_ARROW`
59 err: `expected expression`
60 MATCH_ARM@[85; 85)
61 R_CURLY@[85; 86)
62 WHITESPACE@[86; 87)
63 R_CURLY@[87; 88)
64 WHITESPACE@[88; 89)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.rs
new file mode 100644
index 000000000..54a67c9d7
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.rs
@@ -0,0 +1,8 @@
1fn foo() {
2 match () {
3 #![doc("Inner attribute")]
4 #![doc("Can be")]
5 #![doc("Stacked")]
6 _ => (),
7 }
8}
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.txt
new file mode 100644
index 000000000..b39a217bd
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.txt
@@ -0,0 +1,74 @@
1SOURCE_FILE@[0; 139)
2 FN_DEF@[0; 138)
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; 138)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 MATCH_EXPR@[15; 136)
15 MATCH_KW@[15; 20)
16 WHITESPACE@[20; 21)
17 TUPLE_EXPR@[21; 23)
18 L_PAREN@[21; 22)
19 R_PAREN@[22; 23)
20 WHITESPACE@[23; 24)
21 MATCH_ARM_LIST@[24; 136)
22 L_CURLY@[24; 25)
23 WHITESPACE@[25; 34)
24 ATTR@[34; 60)
25 POUND@[34; 35)
26 EXCL@[35; 36)
27 TOKEN_TREE@[36; 60)
28 L_BRACK@[36; 37)
29 IDENT@[37; 40) "doc"
30 TOKEN_TREE@[40; 59)
31 L_PAREN@[40; 41)
32 STRING@[41; 58)
33 R_PAREN@[58; 59)
34 R_BRACK@[59; 60)
35 WHITESPACE@[60; 69)
36 ATTR@[69; 86)
37 POUND@[69; 70)
38 EXCL@[70; 71)
39 TOKEN_TREE@[71; 86)
40 L_BRACK@[71; 72)
41 IDENT@[72; 75) "doc"
42 TOKEN_TREE@[75; 85)
43 L_PAREN@[75; 76)
44 STRING@[76; 84)
45 R_PAREN@[84; 85)
46 R_BRACK@[85; 86)
47 WHITESPACE@[86; 95)
48 ATTR@[95; 113)
49 POUND@[95; 96)
50 EXCL@[96; 97)
51 TOKEN_TREE@[97; 113)
52 L_BRACK@[97; 98)
53 IDENT@[98; 101) "doc"
54 TOKEN_TREE@[101; 112)
55 L_PAREN@[101; 102)
56 STRING@[102; 111)
57 R_PAREN@[111; 112)
58 R_BRACK@[112; 113)
59 WHITESPACE@[113; 122)
60 MATCH_ARM@[122; 129)
61 PLACEHOLDER_PAT@[122; 123)
62 UNDERSCORE@[122; 123)
63 WHITESPACE@[123; 124)
64 FAT_ARROW@[124; 126)
65 WHITESPACE@[126; 127)
66 TUPLE_EXPR@[127; 129)
67 L_PAREN@[127; 128)
68 R_PAREN@[128; 129)
69 COMMA@[129; 130)
70 WHITESPACE@[130; 135)
71 R_CURLY@[135; 136)
72 WHITESPACE@[136; 137)
73 R_CURLY@[137; 138)
74 WHITESPACE@[138; 139)
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.rs
new file mode 100644
index 000000000..676db42d1
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.rs
@@ -0,0 +1,12 @@
1fn foo() {
2 match () {
3 #[cfg(feature = "some")]
4 _ => (),
5 #[cfg(feature = "other")]
6 _ => (),
7 #[cfg(feature = "many")]
8 #[cfg(feature = "attributes")]
9 #[cfg(feature = "before")]
10 _ => (),
11 }
12}
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt
new file mode 100644
index 000000000..c888fb8f0
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt
@@ -0,0 +1,135 @@
1SOURCE_FILE@[0; 259)
2 FN_DEF@[0; 258)
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; 258)
12 L_CURLY@[9; 10)
13 WHITESPACE@[10; 15)
14 MATCH_EXPR@[15; 256)
15 MATCH_KW@[15; 20)
16 WHITESPACE@[20; 21)
17 TUPLE_EXPR@[21; 23)
18 L_PAREN@[21; 22)
19 R_PAREN@[22; 23)
20 WHITESPACE@[23; 24)
21 MATCH_ARM_LIST@[24; 256)
22 L_CURLY@[24; 25)
23 WHITESPACE@[25; 34)
24 ATTR@[34; 58)
25 POUND@[34; 35)
26 TOKEN_TREE@[35; 58)
27 L_BRACK@[35; 36)
28 IDENT@[36; 39) "cfg"
29 TOKEN_TREE@[39; 57)
30 L_PAREN@[39; 40)
31 IDENT@[40; 47) "feature"
32 WHITESPACE@[47; 48)
33 EQ@[48; 49)
34 WHITESPACE@[49; 50)
35 STRING@[50; 56)
36 R_PAREN@[56; 57)
37 R_BRACK@[57; 58)
38 WHITESPACE@[58; 67)
39 MATCH_ARM@[67; 74)
40 PLACEHOLDER_PAT@[67; 68)
41 UNDERSCORE@[67; 68)
42 WHITESPACE@[68; 69)
43 FAT_ARROW@[69; 71)
44 WHITESPACE@[71; 72)
45 TUPLE_EXPR@[72; 74)
46 L_PAREN@[72; 73)
47 R_PAREN@[73; 74)
48 COMMA@[74; 75)
49 WHITESPACE@[75; 84)
50 ATTR@[84; 109)
51 POUND@[84; 85)
52 TOKEN_TREE@[85; 109)
53 L_BRACK@[85; 86)
54 IDENT@[86; 89) "cfg"
55 TOKEN_TREE@[89; 108)
56 L_PAREN@[89; 90)
57 IDENT@[90; 97) "feature"
58 WHITESPACE@[97; 98)
59 EQ@[98; 99)
60 WHITESPACE@[99; 100)
61 STRING@[100; 107)
62 R_PAREN@[107; 108)
63 R_BRACK@[108; 109)
64 WHITESPACE@[109; 118)
65 MATCH_ARM@[118; 125)
66 PLACEHOLDER_PAT@[118; 119)
67 UNDERSCORE@[118; 119)
68 WHITESPACE@[119; 120)
69 FAT_ARROW@[120; 122)
70 WHITESPACE@[122; 123)
71 TUPLE_EXPR@[123; 125)
72 L_PAREN@[123; 124)
73 R_PAREN@[124; 125)
74 COMMA@[125; 126)
75 WHITESPACE@[126; 135)
76 ATTR@[135; 159)
77 POUND@[135; 136)
78 TOKEN_TREE@[136; 159)
79 L_BRACK@[136; 137)
80 IDENT@[137; 140) "cfg"
81 TOKEN_TREE@[140; 158)
82 L_PAREN@[140; 141)
83 IDENT@[141; 148) "feature"
84 WHITESPACE@[148; 149)
85 EQ@[149; 150)
86 WHITESPACE@[150; 151)
87 STRING@[151; 157)
88 R_PAREN@[157; 158)
89 R_BRACK@[158; 159)
90 WHITESPACE@[159; 168)
91 ATTR@[168; 198)
92 POUND@[168; 169)
93 TOKEN_TREE@[169; 198)
94 L_BRACK@[169; 170)
95 IDENT@[170; 173) "cfg"
96 TOKEN_TREE@[173; 197)
97 L_PAREN@[173; 174)
98 IDENT@[174; 181) "feature"
99 WHITESPACE@[181; 182)
100 EQ@[182; 183)
101 WHITESPACE@[183; 184)
102 STRING@[184; 196)
103 R_PAREN@[196; 197)
104 R_BRACK@[197; 198)
105 WHITESPACE@[198; 207)
106 ATTR@[207; 233)
107 POUND@[207; 208)
108 TOKEN_TREE@[208; 233)
109 L_BRACK@[208; 209)
110 IDENT@[209; 212) "cfg"
111 TOKEN_TREE@[212; 232)
112 L_PAREN@[212; 213)
113 IDENT@[213; 220) "feature"
114 WHITESPACE@[220; 221)
115 EQ@[221; 222)
116 WHITESPACE@[222; 223)
117 STRING@[223; 231)
118 R_PAREN@[231; 232)
119 R_BRACK@[232; 233)
120 WHITESPACE@[233; 242)
121 MATCH_ARM@[242; 249)
122 PLACEHOLDER_PAT@[242; 243)
123 UNDERSCORE@[242; 243)
124 WHITESPACE@[243; 244)
125 FAT_ARROW@[244; 246)
126 WHITESPACE@[246; 247)
127 TUPLE_EXPR@[247; 249)
128 L_PAREN@[247; 248)
129 R_PAREN@[248; 249)
130 COMMA@[249; 250)
131 WHITESPACE@[250; 255)
132 R_CURLY@[255; 256)
133 WHITESPACE@[256; 257)
134 R_CURLY@[257; 258)
135 WHITESPACE@[258; 259)