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.rs156
1 files changed, 78 insertions, 78 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 9fe529f53..bb6c78b5f 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -36,14 +36,14 @@ fn expr_no_struct(p: &mut Parser) {
36// fn c() { 1; 2; } 36// fn c() { 1; 2; }
37// fn d() { 1; 2 } 37// fn d() { 1; 2 }
38pub(crate) fn block(p: &mut Parser) { 38pub(crate) fn block(p: &mut Parser) {
39 if !p.at(L_CURLY) { 39 if !p.at(T!['{']) {
40 p.error("expected a block"); 40 p.error("expected a block");
41 return; 41 return;
42 } 42 }
43 let m = p.start(); 43 let m = p.start();
44 p.bump(); 44 p.bump();
45 expr_block_contents(p); 45 expr_block_contents(p);
46 p.expect(R_CURLY); 46 p.expect(T!['}']);
47 m.complete(p, BLOCK); 47 m.complete(p, BLOCK);
48} 48}
49 49
@@ -65,10 +65,10 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
65 // #[C] #[D] {} 65 // #[C] #[D] {}
66 // #[D] return (); 66 // #[D] return ();
67 // } 67 // }
68 let has_attrs = p.at(POUND); 68 let has_attrs = p.at(T![#]);
69 attributes::outer_attributes(p); 69 attributes::outer_attributes(p);
70 70
71 if p.at(LET_KW) { 71 if p.at(T![let]) {
72 let_stmt(p, m, with_semi); 72 let_stmt(p, m, with_semi);
73 return; 73 return;
74 } 74 }
@@ -90,7 +90,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
90 p.error(format!("attributes are not allowed on {:?}", kind)); 90 p.error(format!("attributes are not allowed on {:?}", kind));
91 } 91 }
92 92
93 if p.at(R_CURLY) { 93 if p.at(T!['}']) {
94 // test attr_on_last_expr_in_block 94 // test attr_on_last_expr_in_block
95 // fn foo() { 95 // fn foo() {
96 // { #[A] bar!()? } 96 // { #[A] bar!()? }
@@ -121,15 +121,15 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
121 match with_semi { 121 match with_semi {
122 StmtWithSemi::Yes => { 122 StmtWithSemi::Yes => {
123 if blocklike.is_block() { 123 if blocklike.is_block() {
124 p.eat(SEMI); 124 p.eat(T![;]);
125 } else { 125 } else {
126 p.expect(SEMI); 126 p.expect(T![;]);
127 } 127 }
128 } 128 }
129 StmtWithSemi::No => {} 129 StmtWithSemi::No => {}
130 StmtWithSemi::Optional => { 130 StmtWithSemi::Optional => {
131 if p.at(SEMI) { 131 if p.at(T![;]) {
132 p.eat(SEMI); 132 p.eat(T![;]);
133 } 133 }
134 } 134 }
135 } 135 }
@@ -145,24 +145,24 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
145 // let d: i32 = 92; 145 // let d: i32 = 92;
146 // } 146 // }
147 fn let_stmt(p: &mut Parser, m: Marker, with_semi: StmtWithSemi) { 147 fn let_stmt(p: &mut Parser, m: Marker, with_semi: StmtWithSemi) {
148 assert!(p.at(LET_KW)); 148 assert!(p.at(T![let]));
149 p.bump(); 149 p.bump();
150 patterns::pattern(p); 150 patterns::pattern(p);
151 if p.at(COLON) { 151 if p.at(T![:]) {
152 types::ascription(p); 152 types::ascription(p);
153 } 153 }
154 if p.eat(EQ) { 154 if p.eat(T![=]) {
155 expressions::expr(p); 155 expressions::expr(p);
156 } 156 }
157 157
158 match with_semi { 158 match with_semi {
159 StmtWithSemi::Yes => { 159 StmtWithSemi::Yes => {
160 p.expect(SEMI); 160 p.expect(T![;]);
161 } 161 }
162 StmtWithSemi::No => {} 162 StmtWithSemi::No => {}
163 StmtWithSemi::Optional => { 163 StmtWithSemi::Optional => {
164 if p.at(SEMI) { 164 if p.at(T![;]) {
165 p.eat(SEMI); 165 p.eat(T![;]);
166 } 166 }
167 } 167 }
168 } 168 }
@@ -174,12 +174,12 @@ pub(crate) fn expr_block_contents(p: &mut Parser) {
174 // This is checked by a validator 174 // This is checked by a validator
175 attributes::inner_attributes(p); 175 attributes::inner_attributes(p);
176 176
177 while !p.at(EOF) && !p.at(R_CURLY) { 177 while !p.at(EOF) && !p.at(T!['}']) {
178 // test nocontentexpr 178 // test nocontentexpr
179 // fn foo(){ 179 // fn foo(){
180 // ;;;some_expr();;;;{;;;};;;;Ok(()) 180 // ;;;some_expr();;;;{;;;};;;;Ok(())
181 // } 181 // }
182 if p.current() == SEMI { 182 if p.current() == T![;] {
183 p.bump(); 183 p.bump();
184 continue; 184 continue;
185 } 185 }
@@ -202,41 +202,41 @@ enum Op {
202fn current_op(p: &Parser) -> (u8, Op) { 202fn current_op(p: &Parser) -> (u8, Op) {
203 if let Some(t) = p.current3() { 203 if let Some(t) = p.current3() {
204 match t { 204 match t {
205 (L_ANGLE, L_ANGLE, EQ) => return (1, Op::Composite(SHLEQ, 3)), 205 (T![<], T![<], T![=]) => return (1, Op::Composite(T![<<=], 3)),
206 (R_ANGLE, R_ANGLE, EQ) => return (1, Op::Composite(SHREQ, 3)), 206 (T![>], T![>], T![=]) => return (1, Op::Composite(T![>>=], 3)),
207 _ => (), 207 _ => (),
208 } 208 }
209 } 209 }
210 210
211 if let Some(t) = p.current2() { 211 if let Some(t) = p.current2() {
212 match t { 212 match t {
213 (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)), 213 (T![+], T![=]) => return (1, Op::Composite(T![+=], 2)),
214 (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)), 214 (T![-], T![=]) => return (1, Op::Composite(T![-=], 2)),
215 (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)), 215 (T![*], T![=]) => return (1, Op::Composite(T![*=], 2)),
216 (PERCENT, EQ) => return (1, Op::Composite(PERCENTEQ, 2)), 216 (T![%], T![=]) => return (1, Op::Composite(T![%=], 2)),
217 (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)), 217 (T![/], T![=]) => return (1, Op::Composite(T![/=], 2)),
218 (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)), 218 (T![|], T![=]) => return (1, Op::Composite(T![|=], 2)),
219 (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)), 219 (T![&], T![=]) => return (1, Op::Composite(T![&=], 2)),
220 (CARET, EQ) => return (1, Op::Composite(CARETEQ, 2)), 220 (T![^], T![=]) => return (1, Op::Composite(T![^=], 2)),
221 (PIPE, PIPE) => return (3, Op::Composite(PIPEPIPE, 2)), 221 (T![|], T![|]) => return (3, Op::Composite(T![||], 2)),
222 (AMP, AMP) => return (4, Op::Composite(AMPAMP, 2)), 222 (T![&], T![&]) => return (4, Op::Composite(T![&&], 2)),
223 (L_ANGLE, EQ) => return (5, Op::Composite(LTEQ, 2)), 223 (T![<], T![=]) => return (5, Op::Composite(T![<=], 2)),
224 (R_ANGLE, EQ) => return (5, Op::Composite(GTEQ, 2)), 224 (T![>], T![=]) => return (5, Op::Composite(T![>=], 2)),
225 (L_ANGLE, L_ANGLE) => return (9, Op::Composite(SHL, 2)), 225 (T![<], T![<]) => return (9, Op::Composite(T![<<], 2)),
226 (R_ANGLE, R_ANGLE) => return (9, Op::Composite(SHR, 2)), 226 (T![>], T![>]) => return (9, Op::Composite(T![>>], 2)),
227 _ => (), 227 _ => (),
228 } 228 }
229 } 229 }
230 230
231 let bp = match p.current() { 231 let bp = match p.current() {
232 EQ => 1, 232 T![=] => 1,
233 DOTDOT | DOTDOTEQ => 2, 233 T![..] | T![..=] => 2,
234 EQEQ | NEQ | L_ANGLE | R_ANGLE => 5, 234 T![==] | T![!=] | T![<] | T![>] => 5,
235 PIPE => 6, 235 T![|] => 6,
236 CARET => 7, 236 T![^] => 7,
237 AMP => 8, 237 T![&] => 8,
238 MINUS | PLUS => 10, 238 T![-] | T![+] => 10,
239 STAR | SLASH | PERCENT => 11, 239 T![*] | T![/] | T![%] => 11,
240 _ => 0, 240 _ => 0,
241 }; 241 };
242 (bp, Op::Simple) 242 (bp, Op::Simple)
@@ -284,7 +284,7 @@ fn expr_bp(
284 newly_dollar_open = false; 284 newly_dollar_open = false;
285 } 285 }
286 286
287 let is_range = p.current() == DOTDOT || p.current() == DOTDOTEQ; 287 let is_range = p.current() == T![..] || p.current() == T![..=];
288 let (op_bp, op) = current_op(p); 288 let (op_bp, op) = current_op(p);
289 if op_bp < bp { 289 if op_bp < bp {
290 break; 290 break;
@@ -318,10 +318,10 @@ fn lhs(
318 // let _ = &1; 318 // let _ = &1;
319 // let _ = &mut &f(); 319 // let _ = &mut &f();
320 // } 320 // }
321 AMP => { 321 T![&] => {
322 m = p.start(); 322 m = p.start();
323 p.bump(); 323 p.bump();
324 p.eat(MUT_KW); 324 p.eat(T![mut]);
325 REF_EXPR 325 REF_EXPR
326 } 326 }
327 // test unary_expr 327 // test unary_expr
@@ -330,14 +330,14 @@ fn lhs(
330 // !!true; 330 // !!true;
331 // --1; 331 // --1;
332 // } 332 // }
333 STAR | EXCL | MINUS => { 333 T![*] | T![!] | T![-] => {
334 m = p.start(); 334 m = p.start();
335 p.bump(); 335 p.bump();
336 PREFIX_EXPR 336 PREFIX_EXPR
337 } 337 }
338 // test full_range_expr 338 // test full_range_expr
339 // fn foo() { xs[..]; } 339 // fn foo() { xs[..]; }
340 DOTDOT | DOTDOTEQ => { 340 T![..] | T![..=] => {
341 m = p.start(); 341 m = p.start();
342 p.bump(); 342 p.bump();
343 if p.at_ts(EXPR_FIRST) { 343 if p.at_ts(EXPR_FIRST) {
@@ -375,21 +375,21 @@ fn postfix_expr(
375 // [] => {} 375 // [] => {}
376 // } 376 // }
377 // } 377 // }
378 L_PAREN if allow_calls => call_expr(p, lhs), 378 T!['('] if allow_calls => call_expr(p, lhs),
379 L_BRACK if allow_calls => index_expr(p, lhs), 379 T!['['] if allow_calls => index_expr(p, lhs),
380 DOT if p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) => { 380 T![.] if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::]) => {
381 method_call_expr(p, lhs) 381 method_call_expr(p, lhs)
382 } 382 }
383 DOT => field_expr(p, lhs), 383 T![.] => field_expr(p, lhs),
384 // test postfix_range 384 // test postfix_range
385 // fn foo() { let x = 1..; } 385 // fn foo() { let x = 1..; }
386 DOTDOT | DOTDOTEQ if !EXPR_FIRST.contains(p.nth(1)) => { 386 T![..] | T![..=] if !EXPR_FIRST.contains(p.nth(1)) => {
387 let m = lhs.precede(p); 387 let m = lhs.precede(p);
388 p.bump(); 388 p.bump();
389 m.complete(p, RANGE_EXPR) 389 m.complete(p, RANGE_EXPR)
390 } 390 }
391 QUESTION => try_expr(p, lhs), 391 T![?] => try_expr(p, lhs),
392 AS_KW => cast_expr(p, lhs), 392 T![as] => cast_expr(p, lhs),
393 _ => break, 393 _ => break,
394 }; 394 };
395 allow_calls = true 395 allow_calls = true
@@ -405,7 +405,7 @@ fn postfix_expr(
405// f(<Foo as Trait>::func()); 405// f(<Foo as Trait>::func());
406// } 406// }
407fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 407fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
408 assert!(p.at(L_PAREN)); 408 assert!(p.at(T!['(']));
409 let m = lhs.precede(p); 409 let m = lhs.precede(p);
410 arg_list(p); 410 arg_list(p);
411 m.complete(p, CALL_EXPR) 411 m.complete(p, CALL_EXPR)
@@ -416,11 +416,11 @@ fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
416// x[1][2]; 416// x[1][2];
417// } 417// }
418fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 418fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
419 assert!(p.at(L_BRACK)); 419 assert!(p.at(T!['[']));
420 let m = lhs.precede(p); 420 let m = lhs.precede(p);
421 p.bump(); 421 p.bump();
422 expr(p); 422 expr(p);
423 p.expect(R_BRACK); 423 p.expect(T![']']);
424 m.complete(p, INDEX_EXPR) 424 m.complete(p, INDEX_EXPR)
425} 425}
426 426
@@ -430,12 +430,12 @@ fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
430// y.bar::<T>(1, 2,); 430// y.bar::<T>(1, 2,);
431// } 431// }
432fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 432fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
433 assert!(p.at(DOT) && p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON)); 433 assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth(2) == T![::]));
434 let m = lhs.precede(p); 434 let m = lhs.precede(p);
435 p.bump(); 435 p.bump();
436 name_ref(p); 436 name_ref(p);
437 type_args::opt_type_arg_list(p, true); 437 type_args::opt_type_arg_list(p, true);
438 if p.at(L_PAREN) { 438 if p.at(T!['(']) {
439 arg_list(p); 439 arg_list(p);
440 } 440 }
441 m.complete(p, METHOD_CALL_EXPR) 441 m.complete(p, METHOD_CALL_EXPR)
@@ -455,7 +455,7 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
455// x.0x01; 455// x.0x01;
456// } 456// }
457fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 457fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
458 assert!(p.at(DOT)); 458 assert!(p.at(T![.]));
459 let m = lhs.precede(p); 459 let m = lhs.precede(p);
460 p.bump(); 460 p.bump();
461 if p.at(IDENT) { 461 if p.at(IDENT) {
@@ -463,7 +463,7 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
463 } else if p.at(INT_NUMBER) { 463 } else if p.at(INT_NUMBER) {
464 p.bump(); 464 p.bump();
465 } else if p.at(FLOAT_NUMBER) { 465 } else if p.at(FLOAT_NUMBER) {
466 // FIXME: How to recover and instead parse INT + DOT? 466 // FIXME: How to recover and instead parse INT + T![.]?
467 p.bump(); 467 p.bump();
468 } else { 468 } else {
469 p.error("expected field name or number") 469 p.error("expected field name or number")
@@ -476,7 +476,7 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
476// x?; 476// x?;
477// } 477// }
478fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 478fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
479 assert!(p.at(QUESTION)); 479 assert!(p.at(T![?]));
480 let m = lhs.precede(p); 480 let m = lhs.precede(p);
481 p.bump(); 481 p.bump();
482 m.complete(p, TRY_EXPR) 482 m.complete(p, TRY_EXPR)
@@ -490,7 +490,7 @@ fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
490// 0x36 as u8 <= 0x37; 490// 0x36 as u8 <= 0x37;
491// } 491// }
492fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { 492fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
493 assert!(p.at(AS_KW)); 493 assert!(p.at(T![as]));
494 let m = lhs.precede(p); 494 let m = lhs.precede(p);
495 p.bump(); 495 p.bump();
496 // Use type_no_bounds(), because cast expressions are not 496 // Use type_no_bounds(), because cast expressions are not
@@ -500,20 +500,20 @@ fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
500} 500}
501 501
502fn arg_list(p: &mut Parser) { 502fn arg_list(p: &mut Parser) {
503 assert!(p.at(L_PAREN)); 503 assert!(p.at(T!['(']));
504 let m = p.start(); 504 let m = p.start();
505 p.bump(); 505 p.bump();
506 while !p.at(R_PAREN) && !p.at(EOF) { 506 while !p.at(T![')']) && !p.at(EOF) {
507 if !p.at_ts(EXPR_FIRST) { 507 if !p.at_ts(EXPR_FIRST) {
508 p.error("expected expression"); 508 p.error("expected expression");
509 break; 509 break;
510 } 510 }
511 expr(p); 511 expr(p);
512 if !p.at(R_PAREN) && !p.expect(COMMA) { 512 if !p.at(T![')']) && !p.expect(T![,]) {
513 break; 513 break;
514 } 514 }
515 } 515 }
516 p.eat(R_PAREN); 516 p.eat(T![')']);
517 m.complete(p, ARG_LIST); 517 m.complete(p, ARG_LIST);
518} 518}
519 519
@@ -525,15 +525,15 @@ fn arg_list(p: &mut Parser) {
525// let _ = format!(); 525// let _ = format!();
526// } 526// }
527fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) { 527fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
528 assert!(paths::is_path_start(p) || p.at(L_ANGLE)); 528 assert!(paths::is_path_start(p) || p.at(T![<]));
529 let m = p.start(); 529 let m = p.start();
530 paths::expr_path(p); 530 paths::expr_path(p);
531 match p.current() { 531 match p.current() {
532 L_CURLY if !r.forbid_structs => { 532 T!['{'] if !r.forbid_structs => {
533 named_field_list(p); 533 named_field_list(p);
534 (m.complete(p, STRUCT_LIT), BlockLike::NotBlock) 534 (m.complete(p, STRUCT_LIT), BlockLike::NotBlock)
535 } 535 }
536 EXCL => { 536 T![!] => {
537 let block_like = items::macro_call_after_excl(p); 537 let block_like = items::macro_call_after_excl(p);
538 (m.complete(p, MACRO_CALL), block_like) 538 (m.complete(p, MACRO_CALL), block_like)
539 } 539 }
@@ -548,35 +548,35 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
548// S { x, y: 32, ..Default::default() }; 548// S { x, y: 32, ..Default::default() };
549// } 549// }
550pub(crate) fn named_field_list(p: &mut Parser) { 550pub(crate) fn named_field_list(p: &mut Parser) {
551 assert!(p.at(L_CURLY)); 551 assert!(p.at(T!['{']));
552 let m = p.start(); 552 let m = p.start();
553 p.bump(); 553 p.bump();
554 while !p.at(EOF) && !p.at(R_CURLY) { 554 while !p.at(EOF) && !p.at(T!['}']) {
555 match p.current() { 555 match p.current() {
556 // test struct_literal_field_with_attr 556 // test struct_literal_field_with_attr
557 // fn main() { 557 // fn main() {
558 // S { #[cfg(test)] field: 1 } 558 // S { #[cfg(test)] field: 1 }
559 // } 559 // }
560 IDENT | POUND => { 560 IDENT | T![#] => {
561 let m = p.start(); 561 let m = p.start();
562 attributes::outer_attributes(p); 562 attributes::outer_attributes(p);
563 name_ref(p); 563 name_ref(p);
564 if p.eat(COLON) { 564 if p.eat(T![:]) {
565 expr(p); 565 expr(p);
566 } 566 }
567 m.complete(p, NAMED_FIELD); 567 m.complete(p, NAMED_FIELD);
568 } 568 }
569 DOTDOT => { 569 T![..] => {
570 p.bump(); 570 p.bump();
571 expr(p); 571 expr(p);
572 } 572 }
573 L_CURLY => error_block(p, "expected a field"), 573 T!['{'] => error_block(p, "expected a field"),
574 _ => p.err_and_bump("expected identifier"), 574 _ => p.err_and_bump("expected identifier"),
575 } 575 }
576 if !p.at(R_CURLY) { 576 if !p.at(T!['}']) {
577 p.expect(COMMA); 577 p.expect(T![,]);
578 } 578 }
579 } 579 }
580 p.expect(R_CURLY); 580 p.expect(T!['}']);
581 m.complete(p, NAMED_FIELD_LIST); 581 m.complete(p, NAMED_FIELD_LIST);
582} 582}