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