diff options
Diffstat (limited to 'crates/ra_syntax/src/grammar')
-rw-r--r-- | crates/ra_syntax/src/grammar/attributes.rs | 10 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar/expressions/atom.rs | 33 |
2 files changed, 43 insertions, 0 deletions
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 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | /// Parses both inner & outer attributes. | ||
4 | /// | ||
5 | /// Allowing to run validation for reporting errors | ||
6 | /// regarding attributes | ||
7 | pub(super) fn all_attributes(p: &mut Parser) { | ||
8 | while p.at(POUND) { | ||
9 | attribute(p, p.nth(1) == EXCL) | ||
10 | } | ||
11 | } | ||
12 | |||
3 | pub(super) fn inner_attributes(p: &mut Parser) { | 13 | pub(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 () { |