16 pub(crate) const LITERAL_FIRST: TokenSet = TokenSet::new(&[
27 pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
28 if !p.at_ts(LITERAL_FIRST) {
33 Some(m.complete(p, LITERAL))
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(&[
61 const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[T![let]]);
63 pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
64 if let Some(m) = literal(p) {
65 return Some((m, BlockLike::NotBlock));
67 if paths::is_path_start(p) {
68 return Some(path_expr(p, r));
71 let done = match p.current() {
72 T!['('] => tuple_expr(p),
73 T!['['] => array_expr(p),
74 T![|] => closure_expr(p),
75 T![static] | T![async] | T![move] if la == T![|] => closure_expr(p),
76 T![static] | T![async] if la == T![move] && p.nth(2) == T![|] => closure_expr(p),
77 T![static] if la == T![async] && p.nth(2) == T![|] => closure_expr(p),
78 T![static] if la == T![async] && p.nth(2) == T![move] && p.nth(3) == T![|] => {
82 T![let] => let_expr(p),
84 T![loop] => loop_expr(p, None),
85 T![box] => box_expr(p, None),
86 T![for] => for_expr(p, None),
87 T![while] => while_expr(p, None),
88 T![try] => try_block_expr(p, None),
89 LIFETIME_IDENT if la == T![:] => {
93 T![loop] => loop_expr(p, Some(m)),
94 T![for] => for_expr(p, Some(m)),
95 T![while] => while_expr(p, Some(m)),
97 // fn f() { 'label: {}; }
100 m.complete(p, BLOCK_EXPR)
103 // test_err misplaced_label_err
107 p.error("expected a loop");
108 m.complete(p, ERROR);
113 T![async] if la == T!['{'] || (la == T![move] && p.nth(2) == T!['{']) => {
118 m.complete(p, BLOCK_EXPR)
120 T![match] => match_expr(p),
122 // fn f() { unsafe { } }
123 T![unsafe] if la == T!['{'] => {
127 m.complete(p, BLOCK_EXPR)
130 // fn f() { const { } }
131 T![const] if la == T!['{'] => {
135 m.complete(p, BLOCK_EXPR)
138 // test for_range_from
146 m.complete(p, BLOCK_EXPR)
148 T![return] => return_expr(p),
149 T![yield] => yield_expr(p),
150 T![continue] => continue_expr(p),
151 T![break] => break_expr(p, r),
153 p.err_recover("expected expression", EXPR_RECOVERY_SET);
157 let blocklike = match done.kind() {
158 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => BlockLike::Block,
159 _ => BlockLike::NotBlock,
161 Some((done, blocklike))
170 fn tuple_expr(p: &mut Parser) -> CompletedMarker {
171 assert!(p.at(T!['(']));
175 let mut saw_comma = false;
176 let mut saw_expr = false;
177 while !p.at(EOF) && !p.at(T![')']) {
181 // const A: (i64, i64) = (1, #[cfg(test)] 2);
192 m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
202 fn array_expr(p: &mut Parser) -> CompletedMarker {
203 assert!(p.at(T!['[']));
206 let mut n_exprs = 0u32;
207 let mut has_semi = false;
210 while !p.at(EOF) && !p.at(T![']']) {
214 // const A: &[i64] = &[1, #[cfg(test)] 2];
219 if n_exprs == 1 && p.eat(T![;]) {
224 if has_semi || !p.at(T![']']) && !p.expect(T![,]) {
230 m.complete(p, ARRAY_EXPR)
243 // static move || {};
244 // static async || {};
245 // static async move || {};
247 fn closure_expr(p: &mut Parser) -> CompletedMarker {
250 || (p.at(T![move]) && p.nth(1) == T![|])
251 || (p.at(T![async]) && p.nth(1) == T![|])
252 || (p.at(T![async]) && p.nth(1) == T![move] && p.nth(2) == T![|])
253 || (p.at(T![static]) && p.nth(1) == T![|])
254 || (p.at(T![static]) && p.nth(1) == T![move] && p.nth(2) == T![|])
255 || (p.at(T![static]) && p.nth(1) == T![async] && p.nth(2) == T![|])
257 && p.nth(1) == T![async]
258 && p.nth(2) == T![move]
259 && p.nth(3) == T![|])
265 params::param_list_closure(p);
267 // test lambda_ret_block
268 // fn main() { || -> i32 { 92 }(); }
270 } else if p.at_ts(EXPR_FIRST) {
273 p.error("expected expression");
275 m.complete(p, CLOSURE_EXPR)
281 // if true {} else {};
282 // if true {} else if false {} else {};
284 // if { true } { } else { };
286 fn if_expr(p: &mut Parser) -> CompletedMarker {
287 assert!(p.at(T![if]));
300 m.complete(p, IF_EXPR)
307 // 'c: for x in () {}
309 fn label(p: &mut Parser) {
310 assert!(p.at(LIFETIME_IDENT) && p.nth(1) == T![:]);
314 m.complete(p, LABEL);
321 fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
322 assert!(p.at(T![loop]));
323 let m = m.unwrap_or_else(|| p.start());
326 m.complete(p, LOOP_EXPR)
332 // while let Some(x) = it.next() {};
333 // while { true } {};
335 fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
336 assert!(p.at(T![while]));
337 let m = m.unwrap_or_else(|| p.start());
341 m.complete(p, WHILE_EXPR)
348 fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
349 assert!(p.at(T![for]));
350 let m = m.unwrap_or_else(|| p.start());
352 patterns::pattern(p);
356 m.complete(p, FOR_EXPR)
361 // if let Some(_) = None && true {}
362 // while 1 == 5 && (let None = None) {}
364 fn let_expr(p: &mut Parser) -> CompletedMarker {
367 patterns::pattern_top(p);
370 m.complete(p, LET_EXPR)
377 // match { } { _ => () };
378 // match { S {} } {};
380 fn match_expr(p: &mut Parser) -> CompletedMarker {
381 assert!(p.at(T![match]));
388 p.error("expected `{`");
390 m.complete(p, MATCH_EXPR)
393 pub(crate) fn match_arm_list(p: &mut Parser) {
394 assert!(p.at(T!['{']));
398 // test match_arms_inner_attribute
401 // #![doc("Inner attribute")]
403 // #![doc("Stacked")]
407 attributes::inner_attrs(p);
409 while !p.at(EOF) && !p.at(T!['}']) {
411 error_block(p, "expected match arm");
417 m.complete(p, MATCH_ARM_LIST);
424 // _ if Test > Test{field: 0} => (),
426 // | X | Y if Z => (),
430 fn match_arm(p: &mut Parser) {
432 // test match_arms_outer_attributes
435 // #[cfg(feature = "some")]
437 // #[cfg(feature = "other")]
439 // #[cfg(feature = "many")]
440 // #[cfg(feature = "attributes")]
441 // #[cfg(feature = "before")]
445 attributes::outer_attrs(p);
447 patterns::pattern_top_r(p, TokenSet::EMPTY);
452 let blocklike = match expr_stmt(p, None) {
453 Some((_, blocklike)) => blocklike,
454 None => BlockLike::NotBlock,
457 // test match_arms_commas
465 if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
466 p.error("expected `,`");
468 m.complete(p, MATCH_ARM);
475 // _ if let foo = bar => (),
478 fn match_guard(p: &mut Parser) -> CompletedMarker {
479 assert!(p.at(T![if]));
483 m.complete(p, MATCH_GUARD)
488 // fn b() { let _ = 1; }
491 pub(crate) fn block_expr(p: &mut Parser) {
493 p.error("expected a block");
498 m.complete(p, BLOCK_EXPR);
501 fn stmt_list(p: &mut Parser) -> CompletedMarker {
502 assert!(p.at(T!['{']));
505 expr_block_contents(p);
507 m.complete(p, STMT_LIST)
515 fn return_expr(p: &mut Parser) -> CompletedMarker {
516 assert!(p.at(T![return]));
519 if p.at_ts(EXPR_FIRST) {
522 m.complete(p, RETURN_EXPR)
529 fn yield_expr(p: &mut Parser) -> CompletedMarker {
530 assert!(p.at(T![yield]));
533 if p.at_ts(EXPR_FIRST) {
536 m.complete(p, YIELD_EXPR)
539 // test continue_expr
546 fn continue_expr(p: &mut Parser) -> CompletedMarker {
547 assert!(p.at(T![continue]));
549 p.bump(T![continue]);
550 if p.at(LIFETIME_IDENT) {
553 m.complete(p, CONTINUE_EXPR)
565 fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
566 assert!(p.at(T![break]));
569 if p.at(LIFETIME_IDENT) {
572 // test break_ambiguity
579 if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
582 m.complete(p, BREAK_EXPR)
585 // test try_block_expr
589 fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
590 assert!(p.at(T![try]));
591 let m = m.unwrap_or_else(|| p.start());
592 // Special-case `try!` as macro.
593 // This is a hack until we do proper edition support
594 if p.nth_at(1, T![!]) {
595 // test try_macro_fallback
596 // fn foo() { try!(Ok(())); }
597 let path = p.start();
598 let path_segment = p.start();
599 let name_ref = p.start();
601 name_ref.complete(p, NAME_REF);
602 path_segment.complete(p, PATH_SEGMENT);
603 path.complete(p, PATH);
604 let _block_like = items::macro_call_after_excl(p);
605 return m.complete(p, MACRO_CALL);
612 p.error("expected a block");
614 m.complete(p, BLOCK_EXPR)
620 // let y = (box 1i32, box 2i32);
621 // let z = Foo(box 1i32, box 2i32);
623 fn box_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
624 assert!(p.at(T![box]));
625 let m = m.unwrap_or_else(|| p.start());
627 if p.at_ts(EXPR_FIRST) {
630 m.complete(p, BOX_EXPR)