aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/expressions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/expressions.rs')
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs121
1 files changed, 63 insertions, 58 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 70c71a8e1..5a3b9f589 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -43,65 +43,64 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
43 attributes::inner_attributes(p); 43 attributes::inner_attributes(p);
44 44
45 while !p.at(EOF) && !p.at(R_CURLY) { 45 while !p.at(EOF) && !p.at(R_CURLY) {
46 match p.current() { 46 // test nocontentexpr
47 // test nocontentexpr 47 // fn foo(){
48 // fn foo(){ 48 // ;;;some_expr();;;;{;;;};;;;Ok(())
49 // ;;;some_expr();;;;{;;;};;;;Ok(()) 49 // }
50 // } 50 if p.current() == SEMI {
51 SEMI => p.bump(), 51 p.bump();
52 _ => { 52 continue;
53 // test block_items 53 }
54 // fn a() { fn b() {} } 54
55 let m = p.start(); 55 // test block_items
56 let has_attrs = p.at(POUND); 56 // fn a() { fn b() {} }
57 attributes::outer_attributes(p); 57 let m = p.start();
58 if p.at(LET_KW) { 58 let has_attrs = p.at(POUND);
59 let_stmt(p, m); 59 attributes::outer_attributes(p);
60 if p.at(LET_KW) {
61 let_stmt(p, m);
62 continue;
63 }
64
65 match items::maybe_item(p, items::ItemFlavor::Mod) {
66 items::MaybeItem::Item(kind) => {
67 m.complete(p, kind);
68 }
69 items::MaybeItem::Modifiers => {
70 m.abandon(p);
71 p.error("expected an item");
72 }
73 // test pub_expr
74 // fn foo() { pub 92; } //FIXME
75 items::MaybeItem::None => {
76 if has_attrs {
77 m.abandon(p);
78 p.error("expected a let statement or an item after attributes in block");
60 } else { 79 } else {
61 match items::maybe_item(p, items::ItemFlavor::Mod) { 80 let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block;
62 items::MaybeItem::Item(kind) => { 81 if p.at(R_CURLY) {
63 m.complete(p, kind); 82 m.abandon(p);
64 } 83 } else {
65 items::MaybeItem::Modifiers => { 84 // test no_semi_after_block
66 m.abandon(p); 85 // fn foo() {
67 p.error("expected an item"); 86 // if true {}
68 } 87 // loop {}
69 // test pub_expr 88 // match () {}
70 // fn foo() { pub 92; } //FIXME 89 // while true {}
71 items::MaybeItem::None => { 90 // for _ in () {}
72 if has_attrs { 91 // {}
73 m.abandon(p); 92 // {}
74 p.error( 93 // macro_rules! test {
75 "expected a let statement or an item after attributes in block", 94 // () => {}
76 ); 95 // }
77 } else { 96 // test!{}
78 let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; 97 // }
79 if p.at(R_CURLY) { 98 if is_blocklike {
80 m.abandon(p); 99 p.eat(SEMI);
81 } else { 100 } else {
82 // test no_semi_after_block 101 p.expect(SEMI);
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);
102 }
103 }
104 } 102 }
103 m.complete(p, EXPR_STMT);
105 } 104 }
106 } 105 }
107 } 106 }
@@ -155,6 +154,7 @@ fn current_op(p: &Parser) -> (u8, Op) {
155 (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)), 154 (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)),
156 (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)), 155 (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)),
157 (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)), 156 (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)),
157 (PERCENT, EQ) => return (1, Op::Composite(PERCENTEQ, 2)),
158 (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)), 158 (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)),
159 (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)), 159 (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)),
160 (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)), 160 (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)),
@@ -453,8 +453,13 @@ pub(crate) fn named_field_list(p: &mut Parser) {
453 p.bump(); 453 p.bump();
454 while !p.at(EOF) && !p.at(R_CURLY) { 454 while !p.at(EOF) && !p.at(R_CURLY) {
455 match p.current() { 455 match p.current() {
456 IDENT => { 456 // test struct_literal_field_with_attr
457 // fn main() {
458 // S { #[cfg(test)] field: 1 }
459 // }
460 IDENT | POUND => {
457 let m = p.start(); 461 let m = p.start();
462 attributes::outer_attributes(p);
458 name_ref(p); 463 name_ref(p);
459 if p.eat(COLON) { 464 if p.eat(COLON) {
460 expr(p); 465 expr(p);