1 //! FIXME: write short doc here
18 pub(crate) const LITERAL_FIRST: TokenSet = token_set![
31 pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
32 if !p.at_ts(LITERAL_FIRST) {
37 Some(m.complete(p, LITERAL))
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![
64 const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW];
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));
70 if paths::is_path_start(p) {
71 return Some(path_expr(p, r));
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),
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![:] => {
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)),
97 // test_err misplaced_label_err
101 p.error("expected a loop");
102 m.complete(p, ERROR);
107 T![async] if la == T!['{'] || (la == T![move] && p.nth(2) == T!['{']) => {
111 block_expr(p, Some(m))
113 T![match] => match_expr(p),
114 T![unsafe] if la == T!['{'] => {
117 block_expr(p, Some(m))
120 // test for_range_from
128 T![return] => return_expr(p),
129 T![continue] => continue_expr(p),
130 T![break] => break_expr(p, r),
132 p.err_recover("expected expression", EXPR_RECOVERY_SET);
136 let blocklike = match done.kind() {
137 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => {
140 _ => BlockLike::NotBlock,
142 Some((done, blocklike))
151 fn tuple_expr(p: &mut Parser) -> CompletedMarker {
152 assert!(p.at(T!['(']));
156 let mut saw_comma = false;
157 let mut saw_expr = false;
158 while !p.at(EOF) && !p.at(T![')']) {
160 if !p.at_ts(EXPR_FIRST) {
161 p.error("expected expression");
171 m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
181 fn array_expr(p: &mut Parser) -> CompletedMarker {
182 assert!(p.at(T!['[']));
186 return m.complete(p, ARRAY_EXPR);
189 // test first_array_member_attributes
190 // pub const A: &[i64] = &[
195 attributes::outer_attributes(p);
201 return m.complete(p, ARRAY_EXPR);
203 while !p.at(EOF) && !p.at(T![']']) {
209 // test subsequent_array_member_attributes
210 // pub const A: &[i64] = &[
215 attributes::outer_attributes(p);
216 if !p.at_ts(EXPR_FIRST) {
217 p.error("expected expression");
223 m.complete(p, ARRAY_EXPR)
236 fn lambda_expr(p: &mut Parser) -> CompletedMarker {
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![|])
246 params::param_list_opt_types(p);
247 if opt_fn_ret_type(p) {
249 p.error("expected `{`");
253 if p.at_ts(EXPR_FIRST) {
256 p.error("expected expression");
258 m.complete(p, LAMBDA_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) && 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 cond(p: &mut Parser) {
353 patterns::pattern_list(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_attributes(p);
396 while !p.at(EOF) && !p.at(T!['}']) {
398 error_block(p, "expected match arm");
402 // test match_arms_commas
410 if match_arm(p).is_block() {
412 } else if !p.at(T!['}']) {
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) -> BlockLike {
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_attributes(p);
447 patterns::pattern_list_r(p, TokenSet::empty());
452 let blocklike = expr_stmt(p).1;
453 m.complete(p, MATCH_ARM);
463 fn match_guard(p: &mut Parser) -> CompletedMarker {
464 assert!(p.at(T![if]));
468 m.complete(p, MATCH_GUARD)
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());
481 m.complete(p, BLOCK_EXPR)
489 fn return_expr(p: &mut Parser) -> CompletedMarker {
490 assert!(p.at(T![return]));
493 if p.at_ts(EXPR_FIRST) {
496 m.complete(p, RETURN_EXPR)
499 // test continue_expr
506 fn continue_expr(p: &mut Parser) -> CompletedMarker {
507 assert!(p.at(T![continue]));
509 p.bump(T![continue]);
511 m.complete(p, CONTINUE_EXPR)
523 fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
524 assert!(p.at(T![break]));
528 // test break_ambiguity
535 if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
538 m.complete(p, BREAK_EXPR)
541 // test try_block_expr
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());
550 m.complete(p, TRY_EXPR)
556 // let y = (box 1i32, box 2i32);
557 // let z = Foo(box 1i32, box 2i32);
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());
563 if p.at_ts(EXPR_FIRST) {
566 m.complete(p, BOX_EXPR)
569 /// Expression from `$var` macro expansion, wrapped in dollars
570 fn meta_var_expr(p: &mut Parser) -> CompletedMarker {
571 assert!(p.at(L_DOLLAR));
574 let (completed, _is_block) =
575 expr_bp(p, Restrictions { forbid_structs: false, prefer_stmt: false }, 1);
577 match (completed, p.current()) {
578 (Some(it), R_DOLLAR) => {
584 while !p.at(R_DOLLAR) {