diff options
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 40 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/types.rs | 15 |
2 files changed, 40 insertions, 15 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index c486c0211..cb30b25a8 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -339,7 +339,8 @@ fn expr_bp(p: &mut Parser, mut r: Restrictions, bp: u8) -> (Option<CompletedMark | |||
339 | (Some(lhs), BlockLike::NotBlock) | 339 | (Some(lhs), BlockLike::NotBlock) |
340 | } | 340 | } |
341 | 341 | ||
342 | const LHS_FIRST: TokenSet = atom::ATOM_EXPR_FIRST.union(token_set![AMP, STAR, EXCL, DOT, MINUS]); | 342 | const LHS_FIRST: TokenSet = |
343 | atom::ATOM_EXPR_FIRST.union(token_set![T![&], T![*], T![!], T![.], T![-]]); | ||
343 | 344 | ||
344 | fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> { | 345 | fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> { |
345 | let m; | 346 | let m; |
@@ -618,26 +619,39 @@ pub(crate) fn record_field_list(p: &mut Parser) { | |||
618 | let m = p.start(); | 619 | let m = p.start(); |
619 | p.bump(T!['{']); | 620 | p.bump(T!['{']); |
620 | while !p.at(EOF) && !p.at(T!['}']) { | 621 | while !p.at(EOF) && !p.at(T!['}']) { |
622 | let m = p.start(); | ||
623 | // test record_literal_field_with_attr | ||
624 | // fn main() { | ||
625 | // S { #[cfg(test)] field: 1 } | ||
626 | // } | ||
627 | attributes::outer_attributes(p); | ||
628 | |||
621 | match p.current() { | 629 | match p.current() { |
622 | // test record_literal_field_with_attr | 630 | IDENT | INT_NUMBER => { |
623 | // fn main() { | 631 | // test_err record_literal_before_ellipsis_recovery |
624 | // S { #[cfg(test)] field: 1 } | 632 | // fn main() { |
625 | // } | 633 | // S { field ..S::default() } |
626 | IDENT | INT_NUMBER | T![#] => { | 634 | // } |
627 | let m = p.start(); | 635 | if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) { |
628 | attributes::outer_attributes(p); | 636 | name_ref_or_index(p); |
629 | name_ref_or_index(p); | 637 | p.expect(T![:]); |
630 | if p.eat(T![:]) { | ||
631 | expr(p); | ||
632 | } | 638 | } |
639 | expr(p); | ||
633 | m.complete(p, RECORD_FIELD); | 640 | m.complete(p, RECORD_FIELD); |
634 | } | 641 | } |
635 | T![.] if p.at(T![..]) => { | 642 | T![.] if p.at(T![..]) => { |
643 | m.abandon(p); | ||
636 | p.bump(T![..]); | 644 | p.bump(T![..]); |
637 | expr(p); | 645 | expr(p); |
638 | } | 646 | } |
639 | T!['{'] => error_block(p, "expected a field"), | 647 | T!['{'] => { |
640 | _ => p.err_and_bump("expected identifier"), | 648 | error_block(p, "expected a field"); |
649 | m.abandon(p); | ||
650 | } | ||
651 | _ => { | ||
652 | p.err_and_bump("expected identifier"); | ||
653 | m.abandon(p); | ||
654 | } | ||
641 | } | 655 | } |
642 | if !p.at(T!['}']) { | 656 | if !p.at(T!['}']) { |
643 | p.expect(T![,]); | 657 | p.expect(T![,]); |
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs index 386969d2d..fe1a039cb 100644 --- a/crates/ra_parser/src/grammar/types.rs +++ b/crates/ra_parser/src/grammar/types.rs | |||
@@ -3,8 +3,19 @@ | |||
3 | use super::*; | 3 | use super::*; |
4 | 4 | ||
5 | pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(token_set![ | 5 | pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(token_set![ |
6 | L_PAREN, EXCL, STAR, L_BRACK, AMP, UNDERSCORE, FN_KW, UNSAFE_KW, EXTERN_KW, FOR_KW, IMPL_KW, | 6 | T!['('], |
7 | DYN_KW, L_ANGLE, | 7 | T!['['], |
8 | T![<], | ||
9 | T![!], | ||
10 | T![*], | ||
11 | T![&], | ||
12 | T![_], | ||
13 | T![fn], | ||
14 | T![unsafe], | ||
15 | T![extern], | ||
16 | T![for], | ||
17 | T![impl], | ||
18 | T![dyn], | ||
8 | ]); | 19 | ]); |
9 | 20 | ||
10 | const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA, L_DOLLAR]; | 21 | const TYPE_RECOVERY_SET: TokenSet = token_set![R_PAREN, COMMA, L_DOLLAR]; |