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![move] if la == T![|] => closure_expr(p),
76 T![async] if la == T![|] || (la == T![move] && p.nth(2) == T![|]) => closure_expr(p),
79 T![loop] => loop_expr(p, None),
80 T![box] => box_expr(p, None),
81 T![for] => for_expr(p, None),
82 T![while] => while_expr(p, None),
83 T![try] => try_block_expr(p, None),
84 LIFETIME_IDENT if la == T![:] => {
88 T![loop] => loop_expr(p, Some(m)),
89 T![for] => for_expr(p, Some(m)),
90 T![while] => while_expr(p, Some(m)),
92 // fn f() { 'label: {}; }
95 m.complete(p, BLOCK_EXPR)
98 // test_err misplaced_label_err
102 p.error("expected a loop");
103 m.complete(p, ERROR);
108 T![async] if la == T!['{'] || (la == T![move] && p.nth(2) == T!['{']) => {
113 m.complete(p, BLOCK_EXPR)
115 T![match] => match_expr(p),
117 // fn f() { unsafe { } }
118 T![unsafe] if la == T!['{'] => {
122 m.complete(p, BLOCK_EXPR)
125 // fn f() { const { } }
126 T![const] if la == T!['{'] => {
130 m.complete(p, BLOCK_EXPR)
133 // test for_range_from
141 m.complete(p, BLOCK_EXPR)
143 T![return] => return_expr(p),
144 T![yield] => yield_expr(p),
145 T![continue] => continue_expr(p),
146 T![break] => break_expr(p, r),
148 p.err_recover("expected expression", EXPR_RECOVERY_SET);
152 let blocklike = match done.kind() {
153 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => BlockLike::Block,
154 _ => BlockLike::NotBlock,
156 Some((done, blocklike))
165 fn tuple_expr(p: &mut Parser) -> CompletedMarker {
166 assert!(p.at(T!['(']));
170 let mut saw_comma = false;
171 let mut saw_expr = false;
172 while !p.at(EOF) && !p.at(T![')']) {
176 // const A: (i64, i64) = (1, #[cfg(test)] 2);
187 m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
197 fn array_expr(p: &mut Parser) -> CompletedMarker {
198 assert!(p.at(T!['[']));
201 let mut n_exprs = 0u32;
202 let mut has_semi = false;
205 while !p.at(EOF) && !p.at(T![']']) {
209 // const A: &[i64] = &[1, #[cfg(test)] 2];
214 if n_exprs == 1 && p.eat(T![;]) {
219 if has_semi || !p.at(T![']']) && !p.expect(T![,]) {
225 m.complete(p, ARRAY_EXPR)
238 fn closure_expr(p: &mut Parser) -> CompletedMarker {
241 || (p.at(T![move]) && p.nth(1) == T![|])
242 || (p.at(T![async]) && p.nth(1) == T![|])
243 || (p.at(T![async]) && p.nth(1) == T![move] && p.nth(2) == T![|])
248 params::param_list_closure(p);
250 // test lambda_ret_block
251 // fn main() { || -> i32 { 92 }(); }
253 } else if p.at_ts(EXPR_FIRST) {
256 p.error("expected expression");
258 m.complete(p, CLOSURE_EXPR)
264 // if true {} else {};
265 // if true {} else if false {} else {};
267 // if { true } { } else { };
269 fn if_expr(p: &mut Parser) -> CompletedMarker {
270 assert!(p.at(T![if]));
283 m.complete(p, IF_EXPR)
290 // 'c: for x in () {}
292 fn label(p: &mut Parser) {
293 assert!(p.at(LIFETIME_IDENT) && p.nth(1) == T![:]);
297 m.complete(p, LABEL);
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());
309 m.complete(p, LOOP_EXPR)
315 // while let Some(x) = it.next() {};
316 // while { true } {};
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());
324 m.complete(p, WHILE_EXPR)
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());
335 patterns::pattern(p);
339 m.complete(p, FOR_EXPR)
343 // fn foo() { if let Some(_) = None {} }
345 // if let Some(_) | Some(_) = None {}
346 // if let | Some(_) = None {}
347 // while let Some(_) | Some(_) = None {}
348 // while let | Some(_) = None {}
350 fn condition(p: &mut Parser) {
353 patterns::pattern_top(p);
357 m.complete(p, CONDITION);
364 // match { } { _ => () };
365 // match { S {} } {};
367 fn match_expr(p: &mut Parser) -> CompletedMarker {
368 assert!(p.at(T![match]));
375 p.error("expected `{`");
377 m.complete(p, MATCH_EXPR)
380 pub(crate) fn match_arm_list(p: &mut Parser) {
381 assert!(p.at(T!['{']));
385 // test match_arms_inner_attribute
388 // #![doc("Inner attribute")]
390 // #![doc("Stacked")]
394 attributes::inner_attrs(p);
396 while !p.at(EOF) && !p.at(T!['}']) {
398 error_block(p, "expected match arm");
404 m.complete(p, MATCH_ARM_LIST);
411 // _ if Test > Test{field: 0} => (),
413 // | X | Y if Z => (),
417 fn match_arm(p: &mut Parser) {
419 // test match_arms_outer_attributes
422 // #[cfg(feature = "some")]
424 // #[cfg(feature = "other")]
426 // #[cfg(feature = "many")]
427 // #[cfg(feature = "attributes")]
428 // #[cfg(feature = "before")]
432 attributes::outer_attrs(p);
434 patterns::pattern_top_r(p, TokenSet::EMPTY);
439 let blocklike = match expr_stmt(p, None) {
440 Some((_, blocklike)) => blocklike,
441 None => BlockLike::NotBlock,
444 // test match_arms_commas
452 if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
453 p.error("expected `,`");
455 m.complete(p, MATCH_ARM);
462 // _ if let foo = bar => (),
465 fn match_guard(p: &mut Parser) -> CompletedMarker {
466 assert!(p.at(T![if]));
470 patterns::pattern_top(p);
474 m.complete(p, MATCH_GUARD)
479 // fn b() { let _ = 1; }
482 pub(crate) fn block_expr(p: &mut Parser) {
484 p.error("expected a block");
489 m.complete(p, BLOCK_EXPR);
492 fn stmt_list(p: &mut Parser) -> CompletedMarker {
493 assert!(p.at(T!['{']));
496 expr_block_contents(p);
498 m.complete(p, STMT_LIST)
506 fn return_expr(p: &mut Parser) -> CompletedMarker {
507 assert!(p.at(T![return]));
510 if p.at_ts(EXPR_FIRST) {
513 m.complete(p, RETURN_EXPR)
520 fn yield_expr(p: &mut Parser) -> CompletedMarker {
521 assert!(p.at(T![yield]));
524 if p.at_ts(EXPR_FIRST) {
527 m.complete(p, YIELD_EXPR)
530 // test continue_expr
537 fn continue_expr(p: &mut Parser) -> CompletedMarker {
538 assert!(p.at(T![continue]));
540 p.bump(T![continue]);
541 if p.at(LIFETIME_IDENT) {
544 m.complete(p, CONTINUE_EXPR)
556 fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
557 assert!(p.at(T![break]));
560 if p.at(LIFETIME_IDENT) {
563 // test break_ambiguity
570 if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
573 m.complete(p, BREAK_EXPR)
576 // test try_block_expr
580 fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
581 assert!(p.at(T![try]));
582 let m = m.unwrap_or_else(|| p.start());
583 // Special-case `try!` as macro.
584 // This is a hack until we do proper edition support
585 if p.nth_at(1, T![!]) {
586 // test try_macro_fallback
587 // fn foo() { try!(Ok(())); }
588 let path = p.start();
589 let path_segment = p.start();
590 let name_ref = p.start();
592 name_ref.complete(p, NAME_REF);
593 path_segment.complete(p, PATH_SEGMENT);
594 path.complete(p, PATH);
595 let _block_like = items::macro_call_after_excl(p);
596 return m.complete(p, MACRO_CALL);
603 p.error("expected a block");
605 m.complete(p, BLOCK_EXPR)
611 // let y = (box 1i32, box 2i32);
612 // let z = Foo(box 1i32, box 2i32);
614 fn box_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
615 assert!(p.at(T![box]));
616 let m = m.unwrap_or_else(|| p.start());
618 if p.at_ts(EXPR_FIRST) {
621 m.complete(p, BOX_EXPR)