]> git.lizzy.rs Git - rust.git/blob - crates/ra_parser/src/grammar/expressions/atom.rs
6f5545a83a6ac0521183778927abb064131043a7
[rust.git] / crates / ra_parser / src / grammar / expressions / atom.rs
1 //! FIXME: write short doc here
2
3 use super::*;
4
5 // test expr_literals
6 // fn foo() {
7 //     let _ = true;
8 //     let _ = false;
9 //     let _ = 1;
10 //     let _ = 2.0;
11 //     let _ = b'a';
12 //     let _ = 'b';
13 //     let _ = "c";
14 //     let _ = r"d";
15 //     let _ = b"e";
16 //     let _ = br"f";
17 // }
18 pub(crate) const LITERAL_FIRST: TokenSet = token_set![
19     TRUE_KW,
20     FALSE_KW,
21     INT_NUMBER,
22     FLOAT_NUMBER,
23     BYTE,
24     CHAR,
25     STRING,
26     RAW_STRING,
27     BYTE_STRING,
28     RAW_BYTE_STRING
29 ];
30
31 pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
32     if !p.at_ts(LITERAL_FIRST) {
33         return None;
34     }
35     let m = p.start();
36     p.bump_any();
37     Some(m.complete(p, LITERAL))
38 }
39
40 // E.g. for after the break in `if break {}`, this should not match
41 pub(super) const ATOM_EXPR_FIRST: TokenSet =
42     LITERAL_FIRST.union(paths::PATH_FIRST).union(token_set![
43         T!['('],
44         T!['{'],
45         T!['['],
46         L_DOLLAR,
47         T![|],
48         T![move],
49         T![box],
50         T![if],
51         T![while],
52         T![match],
53         T![unsafe],
54         T![return],
55         T![break],
56         T![continue],
57         T![async],
58         T![try],
59         T![loop],
60         T![for],
61         LIFETIME,
62     ]);
63
64 const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW];
65
66 pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
67     if let Some(m) = literal(p) {
68         return Some((m, BlockLike::NotBlock));
69     }
70     if paths::is_path_start(p) {
71         return Some(path_expr(p, r));
72     }
73     let la = p.nth(1);
74     let done = match p.current() {
75         T!['('] => tuple_expr(p),
76         T!['['] => array_expr(p),
77         L_DOLLAR => meta_var_expr(p),
78         T![|] => lambda_expr(p),
79         T![move] if la == T![|] => lambda_expr(p),
80         T![async] if la == T![|] || (la == T![move] && p.nth(2) == T![|]) => lambda_expr(p),
81         T![if] => if_expr(p),
82
83         T![loop] => loop_expr(p, None),
84         T![box] => box_expr(p, None),
85         T![for] => for_expr(p, None),
86         T![while] => while_expr(p, None),
87         T![try] => try_block_expr(p, None),
88         LIFETIME if la == T![:] => {
89             let m = p.start();
90             label(p);
91             match p.current() {
92                 T![loop] => loop_expr(p, Some(m)),
93                 T![for] => for_expr(p, Some(m)),
94                 T![while] => while_expr(p, Some(m)),
95                 T!['{'] => block_expr(p, Some(m)),
96                 _ => {
97                     // test_err misplaced_label_err
98                     // fn main() {
99                     //     'loop: impl
100                     // }
101                     p.error("expected a loop");
102                     m.complete(p, ERROR);
103                     return None;
104                 }
105             }
106         }
107         T![async] if la == T!['{'] || (la == T![move] && p.nth(2) == T!['{']) => {
108             let m = p.start();
109             p.bump(T![async]);
110             p.eat(T![move]);
111             block_expr(p, Some(m))
112         }
113         T![match] => match_expr(p),
114         T![unsafe] if la == T!['{'] => {
115             let m = p.start();
116             p.bump(T![unsafe]);
117             block_expr(p, Some(m))
118         }
119         T!['{'] => {
120             // test for_range_from
121             // fn foo() {
122             //    for x in 0 .. {
123             //        break;
124             //    }
125             // }
126             block_expr(p, None)
127         }
128         T![return] => return_expr(p),
129         T![continue] => continue_expr(p),
130         T![break] => break_expr(p, r),
131         _ => {
132             p.err_recover("expected expression", EXPR_RECOVERY_SET);
133             return None;
134         }
135     };
136     let blocklike = match done.kind() {
137         IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => {
138             BlockLike::Block
139         }
140         _ => BlockLike::NotBlock,
141     };
142     Some((done, blocklike))
143 }
144
145 // test tuple_expr
146 // fn foo() {
147 //     ();
148 //     (1);
149 //     (1,);
150 // }
151 fn tuple_expr(p: &mut Parser) -> CompletedMarker {
152     assert!(p.at(T!['(']));
153     let m = p.start();
154     p.expect(T!['(']);
155
156     let mut saw_comma = false;
157     let mut saw_expr = false;
158     while !p.at(EOF) && !p.at(T![')']) {
159         saw_expr = true;
160         if !p.at_ts(EXPR_FIRST) {
161             p.error("expected expression");
162             break;
163         }
164         expr(p);
165         if !p.at(T![')']) {
166             saw_comma = true;
167             p.expect(T![,]);
168         }
169     }
170     p.expect(T![')']);
171     m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
172 }
173
174 // test array_expr
175 // fn foo() {
176 //     [];
177 //     [1];
178 //     [1, 2,];
179 //     [1; 2];
180 // }
181 fn array_expr(p: &mut Parser) -> CompletedMarker {
182     assert!(p.at(T!['[']));
183     let m = p.start();
184     p.bump(T!['[']);
185     if p.eat(T![']']) {
186         return m.complete(p, ARRAY_EXPR);
187     }
188
189     // test first_array_member_attributes
190     // pub const A: &[i64] = &[
191     //    #[cfg(test)]
192     //    1,
193     //    2,
194     // ];
195     attributes::outer_attributes(p);
196
197     expr(p);
198     if p.eat(T![;]) {
199         expr(p);
200         p.expect(T![']']);
201         return m.complete(p, ARRAY_EXPR);
202     }
203     while !p.at(EOF) && !p.at(T![']']) {
204         p.expect(T![,]);
205         if p.at(T![']']) {
206             break;
207         }
208
209         // test subsequent_array_member_attributes
210         // pub const A: &[i64] = &[
211         //    1,
212         //    #[cfg(test)]
213         //    2,
214         // ];
215         attributes::outer_attributes(p);
216         if !p.at_ts(EXPR_FIRST) {
217             p.error("expected expression");
218             break;
219         }
220         expr(p);
221     }
222     p.expect(T![']']);
223     m.complete(p, ARRAY_EXPR)
224 }
225
226 // test lambda_expr
227 // fn foo() {
228 //     || ();
229 //     || -> i32 { 92 };
230 //     |x| x;
231 //     move |x: i32,| x;
232 //     async || {};
233 //     move || {};
234 //     async move || {};
235 // }
236 fn lambda_expr(p: &mut Parser) -> CompletedMarker {
237     assert!(
238         p.at(T![|])
239             || (p.at(T![move]) && p.nth(1) == T![|])
240             || (p.at(T![async]) && p.nth(1) == T![|])
241             || (p.at(T![async]) && p.nth(1) == T![move] && p.nth(2) == T![|])
242     );
243     let m = p.start();
244     p.eat(T![async]);
245     p.eat(T![move]);
246     params::param_list_opt_types(p);
247     if opt_fn_ret_type(p) {
248         if !p.at(T!['{']) {
249             p.error("expected `{`");
250         }
251     }
252
253     if p.at_ts(EXPR_FIRST) {
254         expr(p);
255     } else {
256         p.error("expected expression");
257     }
258     m.complete(p, LAMBDA_EXPR)
259 }
260
261 // test if_expr
262 // fn foo() {
263 //     if true {};
264 //     if true {} else {};
265 //     if true {} else if false {} else {};
266 //     if S {};
267 //     if { true } { } else { };
268 // }
269 fn if_expr(p: &mut Parser) -> CompletedMarker {
270     assert!(p.at(T![if]));
271     let m = p.start();
272     p.bump(T![if]);
273     cond(p);
274     block(p);
275     if p.at(T![else]) {
276         p.bump(T![else]);
277         if p.at(T![if]) {
278             if_expr(p);
279         } else {
280             block(p);
281         }
282     }
283     m.complete(p, IF_EXPR)
284 }
285
286 // test label
287 // fn foo() {
288 //     'a: loop {}
289 //     'b: while true {}
290 //     'c: for x in () {}
291 // }
292 fn label(p: &mut Parser) {
293     assert!(p.at(LIFETIME) && p.nth(1) == T![:]);
294     let m = p.start();
295     p.bump(LIFETIME);
296     p.bump_any();
297     m.complete(p, LABEL);
298 }
299
300 // test loop_expr
301 // fn foo() {
302 //     loop {};
303 // }
304 fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
305     assert!(p.at(T![loop]));
306     let m = m.unwrap_or_else(|| p.start());
307     p.bump(T![loop]);
308     block(p);
309     m.complete(p, LOOP_EXPR)
310 }
311
312 // test while_expr
313 // fn foo() {
314 //     while true {};
315 //     while let Some(x) = it.next() {};
316 //     while { true } {};
317 // }
318 fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
319     assert!(p.at(T![while]));
320     let m = m.unwrap_or_else(|| p.start());
321     p.bump(T![while]);
322     cond(p);
323     block(p);
324     m.complete(p, WHILE_EXPR)
325 }
326
327 // test for_expr
328 // fn foo() {
329 //     for x in [] {};
330 // }
331 fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
332     assert!(p.at(T![for]));
333     let m = m.unwrap_or_else(|| p.start());
334     p.bump(T![for]);
335     patterns::pattern(p);
336     p.expect(T![in]);
337     expr_no_struct(p);
338     block(p);
339     m.complete(p, FOR_EXPR)
340 }
341
342 // test cond
343 // fn foo() { if let Some(_) = None {} }
344 // fn bar() {
345 //     if let Some(_) | Some(_) = None {}
346 //     if let | Some(_) = None {}
347 //     while let Some(_) | Some(_) = None {}
348 //     while let | Some(_) = None {}
349 // }
350 fn cond(p: &mut Parser) {
351     let m = p.start();
352     if p.eat(T![let]) {
353         patterns::pattern_list(p);
354         p.expect(T![=]);
355     }
356     expr_no_struct(p);
357     m.complete(p, CONDITION);
358 }
359
360 // test match_expr
361 // fn foo() {
362 //     match () { };
363 //     match S {};
364 //     match { } { _ => () };
365 //     match { S {} } {};
366 // }
367 fn match_expr(p: &mut Parser) -> CompletedMarker {
368     assert!(p.at(T![match]));
369     let m = p.start();
370     p.bump(T![match]);
371     expr_no_struct(p);
372     if p.at(T!['{']) {
373         match_arm_list(p);
374     } else {
375         p.error("expected `{`")
376     }
377     m.complete(p, MATCH_EXPR)
378 }
379
380 pub(crate) fn match_arm_list(p: &mut Parser) {
381     assert!(p.at(T!['{']));
382     let m = p.start();
383     p.eat(T!['{']);
384
385     // test match_arms_inner_attribute
386     // fn foo() {
387     //     match () {
388     //         #![doc("Inner attribute")]
389     //         #![doc("Can be")]
390     //         #![doc("Stacked")]
391     //         _ => (),
392     //     }
393     // }
394     attributes::inner_attributes(p);
395
396     while !p.at(EOF) && !p.at(T!['}']) {
397         if p.at(T!['{']) {
398             error_block(p, "expected match arm");
399             continue;
400         }
401
402         // test match_arms_commas
403         // fn foo() {
404         //     match () {
405         //         _ => (),
406         //         _ => {}
407         //         _ => ()
408         //     }
409         // }
410         if match_arm(p).is_block() {
411             p.eat(T![,]);
412         } else if !p.at(T!['}']) {
413             p.expect(T![,]);
414         }
415     }
416     p.expect(T!['}']);
417     m.complete(p, MATCH_ARM_LIST);
418 }
419
420 // test match_arm
421 // fn foo() {
422 //     match () {
423 //         _ => (),
424 //         _ if Test > Test{field: 0} => (),
425 //         X | Y if Z => (),
426 //         | X | Y if Z => (),
427 //         | X => (),
428 //     };
429 // }
430 fn match_arm(p: &mut Parser) -> BlockLike {
431     let m = p.start();
432     // test match_arms_outer_attributes
433     // fn foo() {
434     //     match () {
435     //         #[cfg(feature = "some")]
436     //         _ => (),
437     //         #[cfg(feature = "other")]
438     //         _ => (),
439     //         #[cfg(feature = "many")]
440     //         #[cfg(feature = "attributes")]
441     //         #[cfg(feature = "before")]
442     //         _ => (),
443     //     }
444     // }
445     attributes::outer_attributes(p);
446
447     patterns::pattern_list_r(p, TokenSet::empty());
448     if p.at(T![if]) {
449         match_guard(p);
450     }
451     p.expect(T![=>]);
452     let blocklike = expr_stmt(p).1;
453     m.complete(p, MATCH_ARM);
454     blocklike
455 }
456
457 // test match_guard
458 // fn foo() {
459 //     match () {
460 //         _ if foo => (),
461 //     }
462 // }
463 fn match_guard(p: &mut Parser) -> CompletedMarker {
464     assert!(p.at(T![if]));
465     let m = p.start();
466     p.bump(T![if]);
467     expr(p);
468     m.complete(p, MATCH_GUARD)
469 }
470
471 // test block_expr
472 // fn foo() {
473 //     {};
474 //     unsafe {};
475 //     'label: {};
476 // }
477 pub(super) fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
478     assert!(p.at(T!['{']));
479     let m = m.unwrap_or_else(|| p.start());
480     naked_block(p);
481     m.complete(p, BLOCK_EXPR)
482 }
483
484 // test return_expr
485 // fn foo() {
486 //     return;
487 //     return 92;
488 // }
489 fn return_expr(p: &mut Parser) -> CompletedMarker {
490     assert!(p.at(T![return]));
491     let m = p.start();
492     p.bump(T![return]);
493     if p.at_ts(EXPR_FIRST) {
494         expr(p);
495     }
496     m.complete(p, RETURN_EXPR)
497 }
498
499 // test continue_expr
500 // fn foo() {
501 //     loop {
502 //         continue;
503 //         continue 'l;
504 //     }
505 // }
506 fn continue_expr(p: &mut Parser) -> CompletedMarker {
507     assert!(p.at(T![continue]));
508     let m = p.start();
509     p.bump(T![continue]);
510     p.eat(LIFETIME);
511     m.complete(p, CONTINUE_EXPR)
512 }
513
514 // test break_expr
515 // fn foo() {
516 //     loop {
517 //         break;
518 //         break 'l;
519 //         break 92;
520 //         break 'l 92;
521 //     }
522 // }
523 fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
524     assert!(p.at(T![break]));
525     let m = p.start();
526     p.bump(T![break]);
527     p.eat(LIFETIME);
528     // test break_ambiguity
529     // fn foo(){
530     //     if break {}
531     //     while break {}
532     //     for i in break {}
533     //     match break {}
534     // }
535     if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
536         expr(p);
537     }
538     m.complete(p, BREAK_EXPR)
539 }
540
541 // test try_block_expr
542 // fn foo() {
543 //     let _ = try {};
544 // }
545 fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
546     assert!(p.at(T![try]));
547     let m = m.unwrap_or_else(|| p.start());
548     p.bump(T![try]);
549     block(p);
550     m.complete(p, TRY_EXPR)
551 }
552
553 // test box_expr
554 // fn foo() {
555 //     let x = box 1i32;
556 //     let y = (box 1i32, box 2i32);
557 //     let z = Foo(box 1i32, box 2i32);
558 // }
559 fn box_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
560     assert!(p.at(T![box]));
561     let m = m.unwrap_or_else(|| p.start());
562     p.bump(T![box]);
563     if p.at_ts(EXPR_FIRST) {
564         expr(p);
565     }
566     m.complete(p, BOX_EXPR)
567 }
568
569 /// Expression from `$var` macro expansion, wrapped in dollars
570 fn meta_var_expr(p: &mut Parser) -> CompletedMarker {
571     assert!(p.at(L_DOLLAR));
572     let m = p.start();
573     p.bump(L_DOLLAR);
574     let (completed, _is_block) =
575         expr_bp(p, Restrictions { forbid_structs: false, prefer_stmt: false }, 1);
576
577     match (completed, p.current()) {
578         (Some(it), R_DOLLAR) => {
579             p.bump(R_DOLLAR);
580             m.abandon(p);
581             it
582         }
583         _ => {
584             while !p.at(R_DOLLAR) {
585                 p.bump_any()
586             }
587             p.bump(R_DOLLAR);
588             m.complete(p, ERROR)
589         }
590     }
591 }