]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/parser/expr.rs
Auto merge of #96495 - Dylan-DPC:rollup-9lm4tpp, r=Dylan-DPC
[rust.git] / compiler / rustc_parse / src / parser / expr.rs
1 use super::diagnostics::SnapshotParser;
2 use super::pat::{CommaRecoveryMode, RecoverColon, RecoverComma, PARAM_EXPECTED};
3 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
4 use super::{
5     AttrWrapper, BlockMode, ClosureSpans, ForceCollect, Parser, PathStyle, Restrictions,
6     SemiColonMode, SeqSep, TokenExpectType, TokenType, TrailingToken,
7 };
8 use crate::maybe_recover_from_interpolated_ty_qpath;
9
10 use ast::token::DelimToken;
11 use rustc_ast::ptr::P;
12 use rustc_ast::token::{self, Token, TokenKind};
13 use rustc_ast::tokenstream::Spacing;
14 use rustc_ast::util::classify;
15 use rustc_ast::util::literal::LitError;
16 use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
17 use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, Lit, UnOp, DUMMY_NODE_ID};
18 use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
19 use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
20 use rustc_ast_pretty::pprust;
21 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult};
22 use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
23 use rustc_session::lint::BuiltinLintDiagnostics;
24 use rustc_span::source_map::{self, Span, Spanned};
25 use rustc_span::symbol::{kw, sym, Ident, Symbol};
26 use rustc_span::{BytePos, Pos};
27 use std::mem;
28
29 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
30 /// dropped into the token stream, which happens while parsing the result of
31 /// macro expansion). Placement of these is not as complex as I feared it would
32 /// be. The important thing is to make sure that lookahead doesn't balk at
33 /// `token::Interpolated` tokens.
34 macro_rules! maybe_whole_expr {
35     ($p:expr) => {
36         if let token::Interpolated(nt) = &$p.token.kind {
37             match &**nt {
38                 token::NtExpr(e) | token::NtLiteral(e) => {
39                     let e = e.clone();
40                     $p.bump();
41                     return Ok(e);
42                 }
43                 token::NtPath(path) => {
44                     let path = (**path).clone();
45                     $p.bump();
46                     return Ok($p.mk_expr(
47                         $p.prev_token.span,
48                         ExprKind::Path(None, path),
49                         AttrVec::new(),
50                     ));
51                 }
52                 token::NtBlock(block) => {
53                     let block = block.clone();
54                     $p.bump();
55                     return Ok($p.mk_expr(
56                         $p.prev_token.span,
57                         ExprKind::Block(block, None),
58                         AttrVec::new(),
59                     ));
60                 }
61                 _ => {}
62             };
63         }
64     };
65 }
66
67 #[derive(Debug)]
68 pub(super) enum LhsExpr {
69     NotYetParsed,
70     AttributesParsed(AttrWrapper),
71     AlreadyParsed(P<Expr>),
72 }
73
74 impl From<Option<AttrWrapper>> for LhsExpr {
75     /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)`
76     /// and `None` into `LhsExpr::NotYetParsed`.
77     ///
78     /// This conversion does not allocate.
79     fn from(o: Option<AttrWrapper>) -> Self {
80         if let Some(attrs) = o { LhsExpr::AttributesParsed(attrs) } else { LhsExpr::NotYetParsed }
81     }
82 }
83
84 impl From<P<Expr>> for LhsExpr {
85     /// Converts the `expr: P<Expr>` into `LhsExpr::AlreadyParsed(expr)`.
86     ///
87     /// This conversion does not allocate.
88     fn from(expr: P<Expr>) -> Self {
89         LhsExpr::AlreadyParsed(expr)
90     }
91 }
92
93 impl<'a> Parser<'a> {
94     /// Parses an expression.
95     #[inline]
96     pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
97         self.current_closure.take();
98
99         self.parse_expr_res(Restrictions::empty(), None)
100     }
101
102     /// Parses an expression, forcing tokens to be collected
103     pub fn parse_expr_force_collect(&mut self) -> PResult<'a, P<Expr>> {
104         self.collect_tokens_no_attrs(|this| this.parse_expr())
105     }
106
107     pub fn parse_anon_const_expr(&mut self) -> PResult<'a, AnonConst> {
108         self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value })
109     }
110
111     fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> {
112         match self.parse_expr() {
113             Ok(expr) => Ok(expr),
114             Err(mut err) => match self.token.ident() {
115                 Some((Ident { name: kw::Underscore, .. }, false))
116                     if self.look_ahead(1, |t| t == &token::Comma) =>
117                 {
118                     // Special-case handling of `foo(_, _, _)`
119                     err.emit();
120                     self.bump();
121                     Ok(self.mk_expr(self.prev_token.span, ExprKind::Err, AttrVec::new()))
122                 }
123                 _ => Err(err),
124             },
125         }
126     }
127
128     /// Parses a sequence of expressions delimited by parentheses.
129     fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> {
130         self.parse_paren_comma_seq(|p| p.parse_expr_catch_underscore()).map(|(r, _)| r)
131     }
132
133     /// Parses an expression, subject to the given restrictions.
134     #[inline]
135     pub(super) fn parse_expr_res(
136         &mut self,
137         r: Restrictions,
138         already_parsed_attrs: Option<AttrWrapper>,
139     ) -> PResult<'a, P<Expr>> {
140         self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
141     }
142
143     /// Parses an associative expression.
144     ///
145     /// This parses an expression accounting for associativity and precedence of the operators in
146     /// the expression.
147     #[inline]
148     fn parse_assoc_expr(
149         &mut self,
150         already_parsed_attrs: Option<AttrWrapper>,
151     ) -> PResult<'a, P<Expr>> {
152         self.parse_assoc_expr_with(0, already_parsed_attrs.into())
153     }
154
155     /// Parses an associative expression with operators of at least `min_prec` precedence.
156     pub(super) fn parse_assoc_expr_with(
157         &mut self,
158         min_prec: usize,
159         lhs: LhsExpr,
160     ) -> PResult<'a, P<Expr>> {
161         let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
162             expr
163         } else {
164             let attrs = match lhs {
165                 LhsExpr::AttributesParsed(attrs) => Some(attrs),
166                 _ => None,
167             };
168             if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind) {
169                 return self.parse_prefix_range_expr(attrs);
170             } else {
171                 self.parse_prefix_expr(attrs)?
172             }
173         };
174         let last_type_ascription_set = self.last_type_ascription.is_some();
175
176         if !self.should_continue_as_assoc_expr(&lhs) {
177             self.last_type_ascription = None;
178             return Ok(lhs);
179         }
180
181         self.expected_tokens.push(TokenType::Operator);
182         while let Some(op) = self.check_assoc_op() {
183             // Adjust the span for interpolated LHS to point to the `$lhs` token
184             // and not to what it refers to.
185             let lhs_span = match self.prev_token.kind {
186                 TokenKind::Interpolated(..) => self.prev_token.span,
187                 _ => lhs.span,
188             };
189
190             let cur_op_span = self.token.span;
191             let restrictions = if op.node.is_assign_like() {
192                 self.restrictions & Restrictions::NO_STRUCT_LITERAL
193             } else {
194                 self.restrictions
195             };
196             let prec = op.node.precedence();
197             if prec < min_prec {
198                 break;
199             }
200             // Check for deprecated `...` syntax
201             if self.token == token::DotDotDot && op.node == AssocOp::DotDotEq {
202                 self.err_dotdotdot_syntax(self.token.span);
203             }
204
205             if self.token == token::LArrow {
206                 self.err_larrow_operator(self.token.span);
207             }
208
209             self.bump();
210             if op.node.is_comparison() {
211                 if let Some(expr) = self.check_no_chained_comparison(&lhs, &op)? {
212                     return Ok(expr);
213                 }
214             }
215
216             // Look for JS' `===` and `!==` and recover
217             if (op.node == AssocOp::Equal || op.node == AssocOp::NotEqual)
218                 && self.token.kind == token::Eq
219                 && self.prev_token.span.hi() == self.token.span.lo()
220             {
221                 let sp = op.span.to(self.token.span);
222                 let sugg = match op.node {
223                     AssocOp::Equal => "==",
224                     AssocOp::NotEqual => "!=",
225                     _ => unreachable!(),
226                 };
227                 self.struct_span_err(sp, &format!("invalid comparison operator `{sugg}=`"))
228                     .span_suggestion_short(
229                         sp,
230                         &format!("`{s}=` is not a valid comparison operator, use `{s}`", s = sugg),
231                         sugg.to_string(),
232                         Applicability::MachineApplicable,
233                     )
234                     .emit();
235                 self.bump();
236             }
237
238             // Look for PHP's `<>` and recover
239             if op.node == AssocOp::Less
240                 && self.token.kind == token::Gt
241                 && self.prev_token.span.hi() == self.token.span.lo()
242             {
243                 let sp = op.span.to(self.token.span);
244                 self.struct_span_err(sp, "invalid comparison operator `<>`")
245                     .span_suggestion_short(
246                         sp,
247                         "`<>` is not a valid comparison operator, use `!=`",
248                         "!=".to_string(),
249                         Applicability::MachineApplicable,
250                     )
251                     .emit();
252                 self.bump();
253             }
254
255             // Look for C++'s `<=>` and recover
256             if op.node == AssocOp::LessEqual
257                 && self.token.kind == token::Gt
258                 && self.prev_token.span.hi() == self.token.span.lo()
259             {
260                 let sp = op.span.to(self.token.span);
261                 self.struct_span_err(sp, "invalid comparison operator `<=>`")
262                     .span_label(
263                         sp,
264                         "`<=>` is not a valid comparison operator, use `std::cmp::Ordering`",
265                     )
266                     .emit();
267                 self.bump();
268             }
269
270             if self.prev_token == token::BinOp(token::Plus)
271                 && self.token == token::BinOp(token::Plus)
272                 && self.prev_token.span.between(self.token.span).is_empty()
273             {
274                 let op_span = self.prev_token.span.to(self.token.span);
275                 // Eat the second `+`
276                 self.bump();
277                 lhs = self.recover_from_postfix_increment(lhs, op_span)?;
278                 continue;
279             }
280
281             let op = op.node;
282             // Special cases:
283             if op == AssocOp::As {
284                 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?;
285                 continue;
286             } else if op == AssocOp::Colon {
287                 lhs = self.parse_assoc_op_ascribe(lhs, lhs_span)?;
288                 continue;
289             } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
290                 // If we didn't have to handle `x..`/`x..=`, it would be pretty easy to
291                 // generalise it to the Fixity::None code.
292                 lhs = self.parse_range_expr(prec, lhs, op, cur_op_span)?;
293                 break;
294             }
295
296             let fixity = op.fixity();
297             let prec_adjustment = match fixity {
298                 Fixity::Right => 0,
299                 Fixity::Left => 1,
300                 // We currently have no non-associative operators that are not handled above by
301                 // the special cases. The code is here only for future convenience.
302                 Fixity::None => 1,
303             };
304             let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
305                 this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
306             })?;
307
308             let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
309             lhs = match op {
310                 AssocOp::Add
311                 | AssocOp::Subtract
312                 | AssocOp::Multiply
313                 | AssocOp::Divide
314                 | AssocOp::Modulus
315                 | AssocOp::LAnd
316                 | AssocOp::LOr
317                 | AssocOp::BitXor
318                 | AssocOp::BitAnd
319                 | AssocOp::BitOr
320                 | AssocOp::ShiftLeft
321                 | AssocOp::ShiftRight
322                 | AssocOp::Equal
323                 | AssocOp::Less
324                 | AssocOp::LessEqual
325                 | AssocOp::NotEqual
326                 | AssocOp::Greater
327                 | AssocOp::GreaterEqual => {
328                     let ast_op = op.to_ast_binop().unwrap();
329                     let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
330                     self.mk_expr(span, binary, AttrVec::new())
331                 }
332                 AssocOp::Assign => {
333                     self.mk_expr(span, ExprKind::Assign(lhs, rhs, cur_op_span), AttrVec::new())
334                 }
335                 AssocOp::AssignOp(k) => {
336                     let aop = match k {
337                         token::Plus => BinOpKind::Add,
338                         token::Minus => BinOpKind::Sub,
339                         token::Star => BinOpKind::Mul,
340                         token::Slash => BinOpKind::Div,
341                         token::Percent => BinOpKind::Rem,
342                         token::Caret => BinOpKind::BitXor,
343                         token::And => BinOpKind::BitAnd,
344                         token::Or => BinOpKind::BitOr,
345                         token::Shl => BinOpKind::Shl,
346                         token::Shr => BinOpKind::Shr,
347                     };
348                     let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs);
349                     self.mk_expr(span, aopexpr, AttrVec::new())
350                 }
351                 AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
352                     self.span_bug(span, "AssocOp should have been handled by special case")
353                 }
354             };
355
356             if let Fixity::None = fixity {
357                 break;
358             }
359         }
360         if last_type_ascription_set {
361             self.last_type_ascription = None;
362         }
363         Ok(lhs)
364     }
365
366     fn should_continue_as_assoc_expr(&mut self, lhs: &Expr) -> bool {
367         match (self.expr_is_complete(lhs), AssocOp::from_token(&self.token)) {
368             // Semi-statement forms are odd:
369             // See https://github.com/rust-lang/rust/issues/29071
370             (true, None) => false,
371             (false, _) => true, // Continue parsing the expression.
372             // An exhaustive check is done in the following block, but these are checked first
373             // because they *are* ambiguous but also reasonable looking incorrect syntax, so we
374             // want to keep their span info to improve diagnostics in these cases in a later stage.
375             (true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
376             (true, Some(AssocOp::Subtract)) | // `{ 42 } -5`
377             (true, Some(AssocOp::Add)) // `{ 42 } + 42
378             // If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
379             // `if x { a } else { b } && if y { c } else { d }`
380             if !self.look_ahead(1, |t| t.is_used_keyword()) => {
381                 // These cases are ambiguous and can't be identified in the parser alone.
382                 let sp = self.sess.source_map().start_point(self.token.span);
383                 self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
384                 false
385             }
386             (true, Some(AssocOp::LAnd)) |
387             (true, Some(AssocOp::LOr)) |
388             (true, Some(AssocOp::BitOr)) => {
389                 // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the
390                 // above due to #74233.
391                 // These cases are ambiguous and can't be identified in the parser alone.
392                 //
393                 // Bitwise AND is left out because guessing intent is hard. We can make
394                 // suggestions based on the assumption that double-refs are rarely intentional,
395                 // and closures are distinct enough that they don't get mixed up with their
396                 // return value.
397                 let sp = self.sess.source_map().start_point(self.token.span);
398                 self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
399                 false
400             }
401             (true, Some(ref op)) if !op.can_continue_expr_unambiguously() => false,
402             (true, Some(_)) => {
403                 self.error_found_expr_would_be_stmt(lhs);
404                 true
405             }
406         }
407     }
408
409     /// We've found an expression that would be parsed as a statement,
410     /// but the next token implies this should be parsed as an expression.
411     /// For example: `if let Some(x) = x { x } else { 0 } / 2`.
412     fn error_found_expr_would_be_stmt(&self, lhs: &Expr) {
413         let mut err = self.struct_span_err(
414             self.token.span,
415             &format!("expected expression, found `{}`", pprust::token_to_string(&self.token),),
416         );
417         err.span_label(self.token.span, "expected expression");
418         self.sess.expr_parentheses_needed(&mut err, lhs.span);
419         err.emit();
420     }
421
422     /// Possibly translate the current token to an associative operator.
423     /// The method does not advance the current token.
424     ///
425     /// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively.
426     fn check_assoc_op(&self) -> Option<Spanned<AssocOp>> {
427         let (op, span) = match (AssocOp::from_token(&self.token), self.token.ident()) {
428             // When parsing const expressions, stop parsing when encountering `>`.
429             (
430                 Some(
431                     AssocOp::ShiftRight
432                     | AssocOp::Greater
433                     | AssocOp::GreaterEqual
434                     | AssocOp::AssignOp(token::BinOpToken::Shr),
435                 ),
436                 _,
437             ) if self.restrictions.contains(Restrictions::CONST_EXPR) => {
438                 return None;
439             }
440             (Some(op), _) => (op, self.token.span),
441             (None, Some((Ident { name: sym::and, span }, false))) => {
442                 self.error_bad_logical_op("and", "&&", "conjunction");
443                 (AssocOp::LAnd, span)
444             }
445             (None, Some((Ident { name: sym::or, span }, false))) => {
446                 self.error_bad_logical_op("or", "||", "disjunction");
447                 (AssocOp::LOr, span)
448             }
449             _ => return None,
450         };
451         Some(source_map::respan(span, op))
452     }
453
454     /// Error on `and` and `or` suggesting `&&` and `||` respectively.
455     fn error_bad_logical_op(&self, bad: &str, good: &str, english: &str) {
456         self.struct_span_err(self.token.span, &format!("`{bad}` is not a logical operator"))
457             .span_suggestion_short(
458                 self.token.span,
459                 &format!("use `{good}` to perform logical {english}"),
460                 good.to_string(),
461                 Applicability::MachineApplicable,
462             )
463             .note("unlike in e.g., python and PHP, `&&` and `||` are used for logical operators")
464             .emit();
465     }
466
467     /// Checks if this expression is a successfully parsed statement.
468     fn expr_is_complete(&self, e: &Expr) -> bool {
469         self.restrictions.contains(Restrictions::STMT_EXPR)
470             && !classify::expr_requires_semi_to_be_stmt(e)
471     }
472
473     /// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
474     /// The other two variants are handled in `parse_prefix_range_expr` below.
475     fn parse_range_expr(
476         &mut self,
477         prec: usize,
478         lhs: P<Expr>,
479         op: AssocOp,
480         cur_op_span: Span,
481     ) -> PResult<'a, P<Expr>> {
482         let rhs = if self.is_at_start_of_range_notation_rhs() {
483             Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?)
484         } else {
485             None
486         };
487         let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span);
488         let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span);
489         let limits =
490             if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
491         let range = self.mk_range(Some(lhs), rhs, limits);
492         Ok(self.mk_expr(span, range, AttrVec::new()))
493     }
494
495     fn is_at_start_of_range_notation_rhs(&self) -> bool {
496         if self.token.can_begin_expr() {
497             // Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
498             if self.token == token::OpenDelim(token::Brace) {
499                 return !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
500             }
501             true
502         } else {
503             false
504         }
505     }
506
507     /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
508     fn parse_prefix_range_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
509         // Check for deprecated `...` syntax.
510         if self.token == token::DotDotDot {
511             self.err_dotdotdot_syntax(self.token.span);
512         }
513
514         debug_assert!(
515             [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind),
516             "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
517             self.token
518         );
519
520         let limits = match self.token.kind {
521             token::DotDot => RangeLimits::HalfOpen,
522             _ => RangeLimits::Closed,
523         };
524         let op = AssocOp::from_token(&self.token);
525         // FIXME: `parse_prefix_range_expr` is called when the current
526         // token is `DotDot`, `DotDotDot`, or `DotDotEq`. If we haven't already
527         // parsed attributes, then trying to parse them here will always fail.
528         // We should figure out how we want attributes on range expressions to work.
529         let attrs = self.parse_or_use_outer_attributes(attrs)?;
530         self.collect_tokens_for_expr(attrs, |this, attrs| {
531             let lo = this.token.span;
532             this.bump();
533             let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
534                 // RHS must be parsed with more associativity than the dots.
535                 this.parse_assoc_expr_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed)
536                     .map(|x| (lo.to(x.span), Some(x)))?
537             } else {
538                 (lo, None)
539             };
540             let range = this.mk_range(None, opt_end, limits);
541             Ok(this.mk_expr(span, range, attrs.into()))
542         })
543     }
544
545     /// Parses a prefix-unary-operator expr.
546     fn parse_prefix_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
547         let attrs = self.parse_or_use_outer_attributes(attrs)?;
548         let lo = self.token.span;
549
550         macro_rules! make_it {
551             ($this:ident, $attrs:expr, |this, _| $body:expr) => {
552                 $this.collect_tokens_for_expr($attrs, |$this, attrs| {
553                     let (hi, ex) = $body?;
554                     Ok($this.mk_expr(lo.to(hi), ex, attrs.into()))
555                 })
556             };
557         }
558
559         let this = self;
560
561         // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
562         match this.token.uninterpolate().kind {
563             token::Not => make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Not)), // `!expr`
564             token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)), // `~expr`
565             token::BinOp(token::Minus) => {
566                 make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg))
567             } // `-expr`
568             token::BinOp(token::Star) => {
569                 make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Deref))
570             } // `*expr`
571             token::BinOp(token::And) | token::AndAnd => {
572                 make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo))
573             }
574             token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => {
575                 let mut err = this.struct_span_err(lo, "leading `+` is not supported");
576                 err.span_label(lo, "unexpected `+`");
577
578                 // a block on the LHS might have been intended to be an expression instead
579                 if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
580                     this.sess.expr_parentheses_needed(&mut err, *sp);
581                 } else {
582                     err.span_suggestion_verbose(
583                         lo,
584                         "try removing the `+`",
585                         "".to_string(),
586                         Applicability::MachineApplicable,
587                     );
588                 }
589                 err.emit();
590
591                 this.bump();
592                 this.parse_prefix_expr(None)
593             } // `+expr`
594             // Recover from `++x`:
595             token::BinOp(token::Plus)
596                 if this.look_ahead(1, |t| *t == token::BinOp(token::Plus)) =>
597             {
598                 let prev_is_semi = this.prev_token == token::Semi;
599                 let pre_span = this.token.span.to(this.look_ahead(1, |t| t.span));
600                 // Eat both `+`s.
601                 this.bump();
602                 this.bump();
603
604                 let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
605                 this.recover_from_prefix_increment(operand_expr, pre_span, prev_is_semi)
606             }
607             token::Ident(..) if this.token.is_keyword(kw::Box) => {
608                 make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
609             }
610             token::Ident(..) if this.is_mistaken_not_ident_negation() => {
611                 make_it!(this, attrs, |this, _| this.recover_not_expr(lo))
612             }
613             _ => return this.parse_dot_or_call_expr(Some(attrs)),
614         }
615     }
616
617     fn parse_prefix_expr_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
618         self.bump();
619         let expr = self.parse_prefix_expr(None);
620         let (span, expr) = self.interpolated_or_expr_span(expr)?;
621         Ok((lo.to(span), expr))
622     }
623
624     fn parse_unary_expr(&mut self, lo: Span, op: UnOp) -> PResult<'a, (Span, ExprKind)> {
625         let (span, expr) = self.parse_prefix_expr_common(lo)?;
626         Ok((span, self.mk_unary(op, expr)))
627     }
628
629     // Recover on `!` suggesting for bitwise negation instead.
630     fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
631         self.struct_span_err(lo, "`~` cannot be used as a unary operator")
632             .span_suggestion_short(
633                 lo,
634                 "use `!` to perform bitwise not",
635                 "!".to_owned(),
636                 Applicability::MachineApplicable,
637             )
638             .emit();
639
640         self.parse_unary_expr(lo, UnOp::Not)
641     }
642
643     /// Parse `box expr`.
644     fn parse_box_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
645         let (span, expr) = self.parse_prefix_expr_common(lo)?;
646         self.sess.gated_spans.gate(sym::box_syntax, span);
647         Ok((span, ExprKind::Box(expr)))
648     }
649
650     fn is_mistaken_not_ident_negation(&self) -> bool {
651         let token_cannot_continue_expr = |t: &Token| match t.uninterpolate().kind {
652             // These tokens can start an expression after `!`, but
653             // can't continue an expression after an ident
654             token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
655             token::Literal(..) | token::Pound => true,
656             _ => t.is_whole_expr(),
657         };
658         self.token.is_ident_named(sym::not) && self.look_ahead(1, token_cannot_continue_expr)
659     }
660
661     /// Recover on `not expr` in favor of `!expr`.
662     fn recover_not_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
663         // Emit the error...
664         let not_token = self.look_ahead(1, |t| t.clone());
665         self.struct_span_err(
666             not_token.span,
667             &format!("unexpected {} after identifier", super::token_descr(&not_token)),
668         )
669         .span_suggestion_short(
670             // Span the `not` plus trailing whitespace to avoid
671             // trailing whitespace after the `!` in our suggestion
672             self.sess.source_map().span_until_non_whitespace(lo.to(not_token.span)),
673             "use `!` to perform logical negation",
674             "!".to_owned(),
675             Applicability::MachineApplicable,
676         )
677         .emit();
678
679         // ...and recover!
680         self.parse_unary_expr(lo, UnOp::Not)
681     }
682
683     /// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
684     fn interpolated_or_expr_span(
685         &self,
686         expr: PResult<'a, P<Expr>>,
687     ) -> PResult<'a, (Span, P<Expr>)> {
688         expr.map(|e| {
689             (
690                 match self.prev_token.kind {
691                     TokenKind::Interpolated(..) => self.prev_token.span,
692                     _ => e.span,
693                 },
694                 e,
695             )
696         })
697     }
698
699     fn parse_assoc_op_cast(
700         &mut self,
701         lhs: P<Expr>,
702         lhs_span: Span,
703         expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
704     ) -> PResult<'a, P<Expr>> {
705         let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
706             this.mk_expr(
707                 this.mk_expr_sp(&lhs, lhs_span, rhs.span),
708                 expr_kind(lhs, rhs),
709                 AttrVec::new(),
710             )
711         };
712
713         // Save the state of the parser before parsing type normally, in case there is a
714         // LessThan comparison after this cast.
715         let parser_snapshot_before_type = self.clone();
716         let cast_expr = match self.parse_as_cast_ty() {
717             Ok(rhs) => mk_expr(self, lhs, rhs),
718             Err(type_err) => {
719                 // Rewind to before attempting to parse the type with generics, to recover
720                 // from situations like `x as usize < y` in which we first tried to parse
721                 // `usize < y` as a type with generic arguments.
722                 let parser_snapshot_after_type = mem::replace(self, parser_snapshot_before_type);
723
724                 // Check for typo of `'a: loop { break 'a }` with a missing `'`.
725                 match (&lhs.kind, &self.token.kind) {
726                     (
727                         // `foo: `
728                         ExprKind::Path(None, ast::Path { segments, .. }),
729                         TokenKind::Ident(kw::For | kw::Loop | kw::While, false),
730                     ) if segments.len() == 1 => {
731                         let snapshot = self.create_snapshot_for_diagnostic();
732                         let label = Label {
733                             ident: Ident::from_str_and_span(
734                                 &format!("'{}", segments[0].ident),
735                                 segments[0].ident.span,
736                             ),
737                         };
738                         match self.parse_labeled_expr(label, AttrVec::new(), false) {
739                             Ok(expr) => {
740                                 type_err.cancel();
741                                 self.struct_span_err(label.ident.span, "malformed loop label")
742                                     .span_suggestion(
743                                         label.ident.span,
744                                         "use the correct loop label format",
745                                         label.ident.to_string(),
746                                         Applicability::MachineApplicable,
747                                     )
748                                     .emit();
749                                 return Ok(expr);
750                             }
751                             Err(err) => {
752                                 err.cancel();
753                                 self.restore_snapshot(snapshot);
754                             }
755                         }
756                     }
757                     _ => {}
758                 }
759
760                 match self.parse_path(PathStyle::Expr) {
761                     Ok(path) => {
762                         let (op_noun, op_verb) = match self.token.kind {
763                             token::Lt => ("comparison", "comparing"),
764                             token::BinOp(token::Shl) => ("shift", "shifting"),
765                             _ => {
766                                 // We can end up here even without `<` being the next token, for
767                                 // example because `parse_ty_no_plus` returns `Err` on keywords,
768                                 // but `parse_path` returns `Ok` on them due to error recovery.
769                                 // Return original error and parser state.
770                                 *self = parser_snapshot_after_type;
771                                 return Err(type_err);
772                             }
773                         };
774
775                         // Successfully parsed the type path leaving a `<` yet to parse.
776                         type_err.cancel();
777
778                         // Report non-fatal diagnostics, keep `x as usize` as an expression
779                         // in AST and continue parsing.
780                         let msg = format!(
781                             "`<` is interpreted as a start of generic arguments for `{}`, not a {}",
782                             pprust::path_to_string(&path),
783                             op_noun,
784                         );
785                         let span_after_type = parser_snapshot_after_type.token.span;
786                         let expr =
787                             mk_expr(self, lhs, self.mk_ty(path.span, TyKind::Path(None, path)));
788
789                         self.struct_span_err(self.token.span, &msg)
790                             .span_label(
791                                 self.look_ahead(1, |t| t.span).to(span_after_type),
792                                 "interpreted as generic arguments",
793                             )
794                             .span_label(self.token.span, format!("not interpreted as {op_noun}"))
795                             .multipart_suggestion(
796                                 &format!("try {op_verb} the cast value"),
797                                 vec![
798                                     (expr.span.shrink_to_lo(), "(".to_string()),
799                                     (expr.span.shrink_to_hi(), ")".to_string()),
800                                 ],
801                                 Applicability::MachineApplicable,
802                             )
803                             .emit();
804
805                         expr
806                     }
807                     Err(path_err) => {
808                         // Couldn't parse as a path, return original error and parser state.
809                         path_err.cancel();
810                         *self = parser_snapshot_after_type;
811                         return Err(type_err);
812                     }
813                 }
814             }
815         };
816
817         self.parse_and_disallow_postfix_after_cast(cast_expr)
818     }
819
820     /// Parses a postfix operators such as `.`, `?`, or index (`[]`) after a cast,
821     /// then emits an error and returns the newly parsed tree.
822     /// The resulting parse tree for `&x as T[0]` has a precedence of `((&x) as T)[0]`.
823     fn parse_and_disallow_postfix_after_cast(
824         &mut self,
825         cast_expr: P<Expr>,
826     ) -> PResult<'a, P<Expr>> {
827         let span = cast_expr.span;
828         let maybe_ascription_span = if let ExprKind::Type(ascripted_expr, _) = &cast_expr.kind {
829             Some(ascripted_expr.span.shrink_to_hi().with_hi(span.hi()))
830         } else {
831             None
832         };
833
834         // Save the memory location of expr before parsing any following postfix operators.
835         // This will be compared with the memory location of the output expression.
836         // If they different we can assume we parsed another expression because the existing expression is not reallocated.
837         let addr_before = &*cast_expr as *const _ as usize;
838         let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
839         let changed = addr_before != &*with_postfix as *const _ as usize;
840
841         // Check if an illegal postfix operator has been added after the cast.
842         // If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator.
843         if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) || changed {
844             let msg = format!(
845                 "casts cannot be followed by {}",
846                 match with_postfix.kind {
847                     ExprKind::Index(_, _) => "indexing",
848                     ExprKind::Try(_) => "`?`",
849                     ExprKind::Field(_, _) => "a field access",
850                     ExprKind::MethodCall(_, _, _) => "a method call",
851                     ExprKind::Call(_, _) => "a function call",
852                     ExprKind::Await(_) => "`.await`",
853                     ExprKind::Err => return Ok(with_postfix),
854                     _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
855                 }
856             );
857             let mut err = self.struct_span_err(span, &msg);
858
859             let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| {
860                 let suggestions = vec![
861                     (span.shrink_to_lo(), "(".to_string()),
862                     (span.shrink_to_hi(), ")".to_string()),
863                 ];
864                 err.multipart_suggestion(
865                     "try surrounding the expression in parentheses",
866                     suggestions,
867                     Applicability::MachineApplicable,
868                 );
869             };
870
871             // If type ascription is "likely an error", the user will already be getting a useful
872             // help message, and doesn't need a second.
873             if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) {
874                 self.maybe_annotate_with_ascription(&mut err, false);
875             } else if let Some(ascription_span) = maybe_ascription_span {
876                 let is_nightly = self.sess.unstable_features.is_nightly_build();
877                 if is_nightly {
878                     suggest_parens(&mut err);
879                 }
880                 err.span_suggestion(
881                     ascription_span,
882                     &format!(
883                         "{}remove the type ascription",
884                         if is_nightly { "alternatively, " } else { "" }
885                     ),
886                     String::new(),
887                     if is_nightly {
888                         Applicability::MaybeIncorrect
889                     } else {
890                         Applicability::MachineApplicable
891                     },
892                 );
893             } else {
894                 suggest_parens(&mut err);
895             }
896             err.emit();
897         };
898         Ok(with_postfix)
899     }
900
901     fn parse_assoc_op_ascribe(&mut self, lhs: P<Expr>, lhs_span: Span) -> PResult<'a, P<Expr>> {
902         let maybe_path = self.could_ascription_be_path(&lhs.kind);
903         self.last_type_ascription = Some((self.prev_token.span, maybe_path));
904         let lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
905         self.sess.gated_spans.gate(sym::type_ascription, lhs.span);
906         Ok(lhs)
907     }
908
909     /// Parse `& mut? <expr>` or `& raw [ const | mut ] <expr>`.
910     fn parse_borrow_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
911         self.expect_and()?;
912         let has_lifetime = self.token.is_lifetime() && self.look_ahead(1, |t| t != &token::Colon);
913         let lifetime = has_lifetime.then(|| self.expect_lifetime()); // For recovery, see below.
914         let (borrow_kind, mutbl) = self.parse_borrow_modifiers(lo);
915         let expr = self.parse_prefix_expr(None);
916         let (hi, expr) = self.interpolated_or_expr_span(expr)?;
917         let span = lo.to(hi);
918         if let Some(lt) = lifetime {
919             self.error_remove_borrow_lifetime(span, lt.ident.span);
920         }
921         Ok((span, ExprKind::AddrOf(borrow_kind, mutbl, expr)))
922     }
923
924     fn error_remove_borrow_lifetime(&self, span: Span, lt_span: Span) {
925         self.struct_span_err(span, "borrow expressions cannot be annotated with lifetimes")
926             .span_label(lt_span, "annotated with lifetime here")
927             .span_suggestion(
928                 lt_span,
929                 "remove the lifetime annotation",
930                 String::new(),
931                 Applicability::MachineApplicable,
932             )
933             .emit();
934     }
935
936     /// Parse `mut?` or `raw [ const | mut ]`.
937     fn parse_borrow_modifiers(&mut self, lo: Span) -> (ast::BorrowKind, ast::Mutability) {
938         if self.check_keyword(kw::Raw) && self.look_ahead(1, Token::is_mutability) {
939             // `raw [ const | mut ]`.
940             let found_raw = self.eat_keyword(kw::Raw);
941             assert!(found_raw);
942             let mutability = self.parse_const_or_mut().unwrap();
943             self.sess.gated_spans.gate(sym::raw_ref_op, lo.to(self.prev_token.span));
944             (ast::BorrowKind::Raw, mutability)
945         } else {
946             // `mut?`
947             (ast::BorrowKind::Ref, self.parse_mutability())
948         }
949     }
950
951     /// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
952     fn parse_dot_or_call_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
953         let attrs = self.parse_or_use_outer_attributes(attrs)?;
954         self.collect_tokens_for_expr(attrs, |this, attrs| {
955             let base = this.parse_bottom_expr();
956             let (span, base) = this.interpolated_or_expr_span(base)?;
957             this.parse_dot_or_call_expr_with(base, span, attrs)
958         })
959     }
960
961     pub(super) fn parse_dot_or_call_expr_with(
962         &mut self,
963         e0: P<Expr>,
964         lo: Span,
965         mut attrs: Vec<ast::Attribute>,
966     ) -> PResult<'a, P<Expr>> {
967         // Stitch the list of outer attributes onto the return value.
968         // A little bit ugly, but the best way given the current code
969         // structure
970         self.parse_dot_or_call_expr_with_(e0, lo).map(|expr| {
971             expr.map(|mut expr| {
972                 attrs.extend::<Vec<_>>(expr.attrs.into());
973                 expr.attrs = attrs.into();
974                 expr
975             })
976         })
977     }
978
979     fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
980         loop {
981             if self.eat(&token::Question) {
982                 // `expr?`
983                 e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e), AttrVec::new());
984                 continue;
985             }
986             if self.eat(&token::Dot) {
987                 // expr.f
988                 e = self.parse_dot_suffix_expr(lo, e)?;
989                 continue;
990             }
991             if self.expr_is_complete(&e) {
992                 return Ok(e);
993             }
994             e = match self.token.kind {
995                 token::OpenDelim(token::Paren) => self.parse_fn_call_expr(lo, e),
996                 token::OpenDelim(token::Bracket) => self.parse_index_expr(lo, e)?,
997                 _ => return Ok(e),
998             }
999         }
1000     }
1001
1002     fn look_ahead_type_ascription_as_field(&mut self) -> bool {
1003         self.look_ahead(1, |t| t.is_ident())
1004             && self.look_ahead(2, |t| t == &token::Colon)
1005             && self.look_ahead(3, |t| t.can_begin_expr())
1006     }
1007
1008     fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
1009         match self.token.uninterpolate().kind {
1010             token::Ident(..) => self.parse_dot_suffix(base, lo),
1011             token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
1012                 Ok(self.parse_tuple_field_access_expr(lo, base, symbol, suffix, None))
1013             }
1014             token::Literal(token::Lit { kind: token::Float, symbol, suffix }) => {
1015                 Ok(self.parse_tuple_field_access_expr_float(lo, base, symbol, suffix))
1016             }
1017             _ => {
1018                 self.error_unexpected_after_dot();
1019                 Ok(base)
1020             }
1021         }
1022     }
1023
1024     fn error_unexpected_after_dot(&self) {
1025         // FIXME Could factor this out into non_fatal_unexpected or something.
1026         let actual = pprust::token_to_string(&self.token);
1027         self.struct_span_err(self.token.span, &format!("unexpected token: `{actual}`")).emit();
1028     }
1029
1030     // We need an identifier or integer, but the next token is a float.
1031     // Break the float into components to extract the identifier or integer.
1032     // FIXME: With current `TokenCursor` it's hard to break tokens into more than 2
1033     // parts unless those parts are processed immediately. `TokenCursor` should either
1034     // support pushing "future tokens" (would be also helpful to `break_and_eat`), or
1035     // we should break everything including floats into more basic proc-macro style
1036     // tokens in the lexer (probably preferable).
1037     fn parse_tuple_field_access_expr_float(
1038         &mut self,
1039         lo: Span,
1040         base: P<Expr>,
1041         float: Symbol,
1042         suffix: Option<Symbol>,
1043     ) -> P<Expr> {
1044         #[derive(Debug)]
1045         enum FloatComponent {
1046             IdentLike(String),
1047             Punct(char),
1048         }
1049         use FloatComponent::*;
1050
1051         let float_str = float.as_str();
1052         let mut components = Vec::new();
1053         let mut ident_like = String::new();
1054         for c in float_str.chars() {
1055             if c == '_' || c.is_ascii_alphanumeric() {
1056                 ident_like.push(c);
1057             } else if matches!(c, '.' | '+' | '-') {
1058                 if !ident_like.is_empty() {
1059                     components.push(IdentLike(mem::take(&mut ident_like)));
1060                 }
1061                 components.push(Punct(c));
1062             } else {
1063                 panic!("unexpected character in a float token: {:?}", c)
1064             }
1065         }
1066         if !ident_like.is_empty() {
1067             components.push(IdentLike(ident_like));
1068         }
1069
1070         // With proc macros the span can refer to anything, the source may be too short,
1071         // or too long, or non-ASCII. It only makes sense to break our span into components
1072         // if its underlying text is identical to our float literal.
1073         let span = self.token.span;
1074         let can_take_span_apart =
1075             || self.span_to_snippet(span).as_deref() == Ok(float_str).as_deref();
1076
1077         match &*components {
1078             // 1e2
1079             [IdentLike(i)] => {
1080                 self.parse_tuple_field_access_expr(lo, base, Symbol::intern(&i), suffix, None)
1081             }
1082             // 1.
1083             [IdentLike(i), Punct('.')] => {
1084                 let (ident_span, dot_span) = if can_take_span_apart() {
1085                     let (span, ident_len) = (span.data(), BytePos::from_usize(i.len()));
1086                     let ident_span = span.with_hi(span.lo + ident_len);
1087                     let dot_span = span.with_lo(span.lo + ident_len);
1088                     (ident_span, dot_span)
1089                 } else {
1090                     (span, span)
1091                 };
1092                 assert!(suffix.is_none());
1093                 let symbol = Symbol::intern(&i);
1094                 self.token = Token::new(token::Ident(symbol, false), ident_span);
1095                 let next_token = (Token::new(token::Dot, dot_span), self.token_spacing);
1096                 self.parse_tuple_field_access_expr(lo, base, symbol, None, Some(next_token))
1097             }
1098             // 1.2 | 1.2e3
1099             [IdentLike(i1), Punct('.'), IdentLike(i2)] => {
1100                 let (ident1_span, dot_span, ident2_span) = if can_take_span_apart() {
1101                     let (span, ident1_len) = (span.data(), BytePos::from_usize(i1.len()));
1102                     let ident1_span = span.with_hi(span.lo + ident1_len);
1103                     let dot_span = span
1104                         .with_lo(span.lo + ident1_len)
1105                         .with_hi(span.lo + ident1_len + BytePos(1));
1106                     let ident2_span = self.token.span.with_lo(span.lo + ident1_len + BytePos(1));
1107                     (ident1_span, dot_span, ident2_span)
1108                 } else {
1109                     (span, span, span)
1110                 };
1111                 let symbol1 = Symbol::intern(&i1);
1112                 self.token = Token::new(token::Ident(symbol1, false), ident1_span);
1113                 // This needs to be `Spacing::Alone` to prevent regressions.
1114                 // See issue #76399 and PR #76285 for more details
1115                 let next_token1 = (Token::new(token::Dot, dot_span), Spacing::Alone);
1116                 let base1 =
1117                     self.parse_tuple_field_access_expr(lo, base, symbol1, None, Some(next_token1));
1118                 let symbol2 = Symbol::intern(&i2);
1119                 let next_token2 = Token::new(token::Ident(symbol2, false), ident2_span);
1120                 self.bump_with((next_token2, self.token_spacing)); // `.`
1121                 self.parse_tuple_field_access_expr(lo, base1, symbol2, suffix, None)
1122             }
1123             // 1e+ | 1e- (recovered)
1124             [IdentLike(_), Punct('+' | '-')] |
1125             // 1e+2 | 1e-2
1126             [IdentLike(_), Punct('+' | '-'), IdentLike(_)] |
1127             // 1.2e+ | 1.2e-
1128             [IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-')] |
1129             // 1.2e+3 | 1.2e-3
1130             [IdentLike(_), Punct('.'), IdentLike(_), Punct('+' | '-'), IdentLike(_)] => {
1131                 // See the FIXME about `TokenCursor` above.
1132                 self.error_unexpected_after_dot();
1133                 base
1134             }
1135             _ => panic!("unexpected components in a float token: {:?}", components),
1136         }
1137     }
1138
1139     fn parse_tuple_field_access_expr(
1140         &mut self,
1141         lo: Span,
1142         base: P<Expr>,
1143         field: Symbol,
1144         suffix: Option<Symbol>,
1145         next_token: Option<(Token, Spacing)>,
1146     ) -> P<Expr> {
1147         match next_token {
1148             Some(next_token) => self.bump_with(next_token),
1149             None => self.bump(),
1150         }
1151         let span = self.prev_token.span;
1152         let field = ExprKind::Field(base, Ident::new(field, span));
1153         self.expect_no_suffix(span, "a tuple index", suffix);
1154         self.mk_expr(lo.to(span), field, AttrVec::new())
1155     }
1156
1157     /// Parse a function call expression, `expr(...)`.
1158     fn parse_fn_call_expr(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> {
1159         let snapshot = if self.token.kind == token::OpenDelim(token::Paren)
1160             && self.look_ahead_type_ascription_as_field()
1161         {
1162             Some((self.create_snapshot_for_diagnostic(), fun.kind.clone()))
1163         } else {
1164             None
1165         };
1166         let open_paren = self.token.span;
1167
1168         let mut seq = self.parse_paren_expr_seq().map(|args| {
1169             self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args), AttrVec::new())
1170         });
1171         if let Some(expr) =
1172             self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot)
1173         {
1174             return expr;
1175         }
1176         self.recover_seq_parse_error(token::Paren, lo, seq)
1177     }
1178
1179     /// If we encounter a parser state that looks like the user has written a `struct` literal with
1180     /// parentheses instead of braces, recover the parser state and provide suggestions.
1181     #[instrument(skip(self, seq, snapshot), level = "trace")]
1182     fn maybe_recover_struct_lit_bad_delims(
1183         &mut self,
1184         lo: Span,
1185         open_paren: Span,
1186         seq: &mut PResult<'a, P<Expr>>,
1187         snapshot: Option<(SnapshotParser<'a>, ExprKind)>,
1188     ) -> Option<P<Expr>> {
1189         match (seq.as_mut(), snapshot) {
1190             (Err(err), Some((mut snapshot, ExprKind::Path(None, path)))) => {
1191                 let name = pprust::path_to_string(&path);
1192                 snapshot.bump(); // `(`
1193                 match snapshot.parse_struct_fields(path, false, token::Paren) {
1194                     Ok((fields, ..)) if snapshot.eat(&token::CloseDelim(token::Paren)) => {
1195                         // We are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
1196                         // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
1197                         self.restore_snapshot(snapshot);
1198                         let close_paren = self.prev_token.span;
1199                         let span = lo.to(self.prev_token.span);
1200                         if !fields.is_empty() {
1201                             let replacement_err = self.struct_span_err(
1202                                 span,
1203                                 "invalid `struct` delimiters or `fn` call arguments",
1204                             );
1205                             mem::replace(err, replacement_err).cancel();
1206
1207                             err.multipart_suggestion(
1208                                 &format!("if `{name}` is a struct, use braces as delimiters"),
1209                                 vec![
1210                                     (open_paren, " { ".to_string()),
1211                                     (close_paren, " }".to_string()),
1212                                 ],
1213                                 Applicability::MaybeIncorrect,
1214                             );
1215                             err.multipart_suggestion(
1216                                 &format!("if `{name}` is a function, use the arguments directly"),
1217                                 fields
1218                                     .into_iter()
1219                                     .map(|field| (field.span.until(field.expr.span), String::new()))
1220                                     .collect(),
1221                                 Applicability::MaybeIncorrect,
1222                             );
1223                             err.emit();
1224                         } else {
1225                             err.emit();
1226                         }
1227                         return Some(self.mk_expr_err(span));
1228                     }
1229                     Ok(_) => {}
1230                     Err(mut err) => {
1231                         err.emit();
1232                     }
1233                 }
1234             }
1235             _ => {}
1236         }
1237         None
1238     }
1239
1240     /// Parse an indexing expression `expr[...]`.
1241     fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
1242         self.bump(); // `[`
1243         let index = self.parse_expr()?;
1244         self.expect(&token::CloseDelim(token::Bracket))?;
1245         Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new()))
1246     }
1247
1248     /// Assuming we have just parsed `.`, continue parsing into an expression.
1249     fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
1250         if self.token.uninterpolated_span().rust_2018() && self.eat_keyword(kw::Await) {
1251             return Ok(self.mk_await_expr(self_arg, lo));
1252         }
1253
1254         let fn_span_lo = self.token.span;
1255         let mut segment = self.parse_path_segment(PathStyle::Expr, None)?;
1256         self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(token::Paren)]);
1257         self.check_turbofish_missing_angle_brackets(&mut segment);
1258
1259         if self.check(&token::OpenDelim(token::Paren)) {
1260             // Method call `expr.f()`
1261             let mut args = self.parse_paren_expr_seq()?;
1262             args.insert(0, self_arg);
1263
1264             let fn_span = fn_span_lo.to(self.prev_token.span);
1265             let span = lo.to(self.prev_token.span);
1266             Ok(self.mk_expr(span, ExprKind::MethodCall(segment, args, fn_span), AttrVec::new()))
1267         } else {
1268             // Field access `expr.f`
1269             if let Some(args) = segment.args {
1270                 self.struct_span_err(
1271                     args.span(),
1272                     "field expressions cannot have generic arguments",
1273                 )
1274                 .emit();
1275             }
1276
1277             let span = lo.to(self.prev_token.span);
1278             Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident), AttrVec::new()))
1279         }
1280     }
1281
1282     /// At the bottom (top?) of the precedence hierarchy,
1283     /// Parses things like parenthesized exprs, macros, `return`, etc.
1284     ///
1285     /// N.B., this does not parse outer attributes, and is private because it only works
1286     /// correctly if called from `parse_dot_or_call_expr()`.
1287     fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
1288         maybe_recover_from_interpolated_ty_qpath!(self, true);
1289         maybe_whole_expr!(self);
1290
1291         // Outer attributes are already parsed and will be
1292         // added to the return value after the fact.
1293         //
1294         // Therefore, prevent sub-parser from parsing
1295         // attributes by giving them an empty "already-parsed" list.
1296         let attrs = AttrVec::new();
1297
1298         // Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
1299         let lo = self.token.span;
1300         if let token::Literal(_) = self.token.kind {
1301             // This match arm is a special-case of the `_` match arm below and
1302             // could be removed without changing functionality, but it's faster
1303             // to have it here, especially for programs with large constants.
1304             self.parse_lit_expr(attrs)
1305         } else if self.check(&token::OpenDelim(token::Paren)) {
1306             self.parse_tuple_parens_expr(attrs)
1307         } else if self.check(&token::OpenDelim(token::Brace)) {
1308             self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs)
1309         } else if self.check(&token::BinOp(token::Or)) || self.check(&token::OrOr) {
1310             self.parse_closure_expr(attrs).map_err(|mut err| {
1311                 // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
1312                 // then suggest parens around the lhs.
1313                 if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
1314                     self.sess.expr_parentheses_needed(&mut err, *sp);
1315                 }
1316                 err
1317             })
1318         } else if self.check(&token::OpenDelim(token::Bracket)) {
1319             self.parse_array_or_repeat_expr(attrs, token::Bracket)
1320         } else if self.check_path() {
1321             self.parse_path_start_expr(attrs)
1322         } else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
1323             self.parse_closure_expr(attrs)
1324         } else if self.eat_keyword(kw::If) {
1325             self.parse_if_expr(attrs)
1326         } else if self.check_keyword(kw::For) {
1327             if self.choose_generics_over_qpath(1) {
1328                 // NOTE(Centril, eddyb): DO NOT REMOVE! Beyond providing parser recovery,
1329                 // this is an insurance policy in case we allow qpaths in (tuple-)struct patterns.
1330                 // When `for <Foo as Bar>::Proj in $expr $block` is wanted,
1331                 // you can disambiguate in favor of a pattern with `(...)`.
1332                 self.recover_quantified_closure_expr(attrs)
1333             } else {
1334                 assert!(self.eat_keyword(kw::For));
1335                 self.parse_for_expr(None, self.prev_token.span, attrs)
1336             }
1337         } else if self.eat_keyword(kw::While) {
1338             self.parse_while_expr(None, self.prev_token.span, attrs)
1339         } else if let Some(label) = self.eat_label() {
1340             self.parse_labeled_expr(label, attrs, true)
1341         } else if self.eat_keyword(kw::Loop) {
1342             let sp = self.prev_token.span;
1343             self.parse_loop_expr(None, self.prev_token.span, attrs).map_err(|mut err| {
1344                 err.span_label(sp, "while parsing this `loop` expression");
1345                 err
1346             })
1347         } else if self.eat_keyword(kw::Continue) {
1348             let kind = ExprKind::Continue(self.eat_label());
1349             Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
1350         } else if self.eat_keyword(kw::Match) {
1351             let match_sp = self.prev_token.span;
1352             self.parse_match_expr(attrs).map_err(|mut err| {
1353                 err.span_label(match_sp, "while parsing this `match` expression");
1354                 err
1355             })
1356         } else if self.eat_keyword(kw::Unsafe) {
1357             let sp = self.prev_token.span;
1358             self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs)
1359                 .map_err(|mut err| {
1360                     err.span_label(sp, "while parsing this `unsafe` expression");
1361                     err
1362                 })
1363         } else if self.check_inline_const(0) {
1364             self.parse_const_block(lo.to(self.token.span), false)
1365         } else if self.is_do_catch_block() {
1366             self.recover_do_catch(attrs)
1367         } else if self.is_try_block() {
1368             self.expect_keyword(kw::Try)?;
1369             self.parse_try_block(lo, attrs)
1370         } else if self.eat_keyword(kw::Return) {
1371             self.parse_return_expr(attrs)
1372         } else if self.eat_keyword(kw::Break) {
1373             self.parse_break_expr(attrs)
1374         } else if self.eat_keyword(kw::Yield) {
1375             self.parse_yield_expr(attrs)
1376         } else if self.eat_keyword(kw::Let) {
1377             self.parse_let_expr(attrs)
1378         } else if self.eat_keyword(kw::Underscore) {
1379             Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
1380         } else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
1381             // Don't complain about bare semicolons after unclosed braces
1382             // recovery in order to keep the error count down. Fixing the
1383             // delimiters will possibly also fix the bare semicolon found in
1384             // expression context. For example, silence the following error:
1385             //
1386             //     error: expected expression, found `;`
1387             //      --> file.rs:2:13
1388             //       |
1389             //     2 |     foo(bar(;
1390             //       |             ^ expected expression
1391             self.bump();
1392             Ok(self.mk_expr_err(self.token.span))
1393         } else if self.token.uninterpolated_span().rust_2018() {
1394             // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly.
1395             if self.check_keyword(kw::Async) {
1396                 if self.is_async_block() {
1397                     // Check for `async {` and `async move {`.
1398                     self.parse_async_block(attrs)
1399                 } else {
1400                     self.parse_closure_expr(attrs)
1401                 }
1402             } else if self.eat_keyword(kw::Await) {
1403                 self.recover_incorrect_await_syntax(lo, self.prev_token.span, attrs)
1404             } else {
1405                 self.parse_lit_expr(attrs)
1406             }
1407         } else {
1408             self.parse_lit_expr(attrs)
1409         }
1410     }
1411
1412     fn parse_lit_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1413         let lo = self.token.span;
1414         match self.parse_opt_lit() {
1415             Some(literal) => {
1416                 let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs);
1417                 self.maybe_recover_from_bad_qpath(expr, true)
1418             }
1419             None => self.try_macro_suggestion(),
1420         }
1421     }
1422
1423     fn parse_tuple_parens_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1424         let lo = self.token.span;
1425         self.expect(&token::OpenDelim(token::Paren))?;
1426         let (es, trailing_comma) = match self.parse_seq_to_end(
1427             &token::CloseDelim(token::Paren),
1428             SeqSep::trailing_allowed(token::Comma),
1429             |p| p.parse_expr_catch_underscore(),
1430         ) {
1431             Ok(x) => x,
1432             Err(err) => return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err))),
1433         };
1434         let kind = if es.len() == 1 && !trailing_comma {
1435             // `(e)` is parenthesized `e`.
1436             ExprKind::Paren(es.into_iter().next().unwrap())
1437         } else {
1438             // `(e,)` is a tuple with only one field, `e`.
1439             ExprKind::Tup(es)
1440         };
1441         let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
1442         self.maybe_recover_from_bad_qpath(expr, true)
1443     }
1444
1445     fn parse_array_or_repeat_expr(
1446         &mut self,
1447         attrs: AttrVec,
1448         close_delim: token::DelimToken,
1449     ) -> PResult<'a, P<Expr>> {
1450         let lo = self.token.span;
1451         self.bump(); // `[` or other open delim
1452
1453         let close = &token::CloseDelim(close_delim);
1454         let kind = if self.eat(close) {
1455             // Empty vector
1456             ExprKind::Array(Vec::new())
1457         } else {
1458             // Non-empty vector
1459             let first_expr = self.parse_expr()?;
1460             if self.eat(&token::Semi) {
1461                 // Repeating array syntax: `[ 0; 512 ]`
1462                 let count = self.parse_anon_const_expr()?;
1463                 self.expect(close)?;
1464                 ExprKind::Repeat(first_expr, count)
1465             } else if self.eat(&token::Comma) {
1466                 // Vector with two or more elements.
1467                 let sep = SeqSep::trailing_allowed(token::Comma);
1468                 let (remaining_exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?;
1469                 let mut exprs = vec![first_expr];
1470                 exprs.extend(remaining_exprs);
1471                 ExprKind::Array(exprs)
1472             } else {
1473                 // Vector with one element
1474                 self.expect(close)?;
1475                 ExprKind::Array(vec![first_expr])
1476             }
1477         };
1478         let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
1479         self.maybe_recover_from_bad_qpath(expr, true)
1480     }
1481
1482     fn parse_path_start_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1483         let (qself, path) = if self.eat_lt() {
1484             let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
1485             (Some(qself), path)
1486         } else {
1487             (None, self.parse_path(PathStyle::Expr)?)
1488         };
1489         let lo = path.span;
1490
1491         // `!`, as an operator, is prefix, so we know this isn't that.
1492         let (hi, kind) = if self.eat(&token::Not) {
1493             // MACRO INVOCATION expression
1494             if qself.is_some() {
1495                 self.struct_span_err(path.span, "macros cannot use qualified paths").emit();
1496             }
1497             let mac = MacCall {
1498                 path,
1499                 args: self.parse_mac_args()?,
1500                 prior_type_ascription: self.last_type_ascription,
1501             };
1502             (self.prev_token.span, ExprKind::MacCall(mac))
1503         } else if self.check(&token::OpenDelim(token::Brace)) {
1504             if let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path, &attrs) {
1505                 if qself.is_some() {
1506                     self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
1507                 }
1508                 return expr;
1509             } else {
1510                 (path.span, ExprKind::Path(qself, path))
1511             }
1512         } else {
1513             (path.span, ExprKind::Path(qself, path))
1514         };
1515
1516         let expr = self.mk_expr(lo.to(hi), kind, attrs);
1517         self.maybe_recover_from_bad_qpath(expr, true)
1518     }
1519
1520     /// Parse `'label: $expr`. The label is already parsed.
1521     fn parse_labeled_expr(
1522         &mut self,
1523         label: Label,
1524         attrs: AttrVec,
1525         mut consume_colon: bool,
1526     ) -> PResult<'a, P<Expr>> {
1527         let lo = label.ident.span;
1528         let label = Some(label);
1529         let ate_colon = self.eat(&token::Colon);
1530         let expr = if self.eat_keyword(kw::While) {
1531             self.parse_while_expr(label, lo, attrs)
1532         } else if self.eat_keyword(kw::For) {
1533             self.parse_for_expr(label, lo, attrs)
1534         } else if self.eat_keyword(kw::Loop) {
1535             self.parse_loop_expr(label, lo, attrs)
1536         } else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
1537             self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
1538         } else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
1539             // We're probably inside of a `Path<'a>` that needs a turbofish
1540             let msg = "expected `while`, `for`, `loop` or `{` after a label";
1541             self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
1542             consume_colon = false;
1543             Ok(self.mk_expr_err(lo))
1544         } else {
1545             let msg = "expected `while`, `for`, `loop` or `{` after a label";
1546             self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
1547             // Continue as an expression in an effort to recover on `'label: non_block_expr`.
1548             self.parse_expr()
1549         }?;
1550
1551         if !ate_colon && consume_colon {
1552             self.error_labeled_expr_must_be_followed_by_colon(lo, expr.span);
1553         }
1554
1555         Ok(expr)
1556     }
1557
1558     fn error_labeled_expr_must_be_followed_by_colon(&self, lo: Span, span: Span) {
1559         self.struct_span_err(span, "labeled expression must be followed by `:`")
1560             .span_label(lo, "the label")
1561             .span_suggestion_short(
1562                 lo.shrink_to_hi(),
1563                 "add `:` after the label",
1564                 ": ".to_string(),
1565                 Applicability::MachineApplicable,
1566             )
1567             .note("labels are used before loops and blocks, allowing e.g., `break 'label` to them")
1568             .emit();
1569     }
1570
1571     /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
1572     fn recover_do_catch(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1573         let lo = self.token.span;
1574
1575         self.bump(); // `do`
1576         self.bump(); // `catch`
1577
1578         let span_dc = lo.to(self.prev_token.span);
1579         self.struct_span_err(span_dc, "found removed `do catch` syntax")
1580             .span_suggestion(
1581                 span_dc,
1582                 "replace with the new syntax",
1583                 "try".to_string(),
1584                 Applicability::MachineApplicable,
1585             )
1586             .note("following RFC #2388, the new non-placeholder syntax is `try`")
1587             .emit();
1588
1589         self.parse_try_block(lo, attrs)
1590     }
1591
1592     /// Parse an expression if the token can begin one.
1593     fn parse_expr_opt(&mut self) -> PResult<'a, Option<P<Expr>>> {
1594         Ok(if self.token.can_begin_expr() { Some(self.parse_expr()?) } else { None })
1595     }
1596
1597     /// Parse `"return" expr?`.
1598     fn parse_return_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1599         let lo = self.prev_token.span;
1600         let kind = ExprKind::Ret(self.parse_expr_opt()?);
1601         let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
1602         self.maybe_recover_from_bad_qpath(expr, true)
1603     }
1604
1605     /// Parse `"break" (('label (:? expr)?) | expr?)` with `"break"` token already eaten.
1606     /// If the label is followed immediately by a `:` token, the label and `:` are
1607     /// parsed as part of the expression (i.e. a labeled loop). The language team has
1608     /// decided in #87026 to require parentheses as a visual aid to avoid confusion if
1609     /// the break expression of an unlabeled break is a labeled loop (as in
1610     /// `break 'lbl: loop {}`); a labeled break with an unlabeled loop as its value
1611     /// expression only gets a warning for compatibility reasons; and a labeled break
1612     /// with a labeled loop does not even get a warning because there is no ambiguity.
1613     fn parse_break_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1614         let lo = self.prev_token.span;
1615         let mut label = self.eat_label();
1616         let kind = if label.is_some() && self.token == token::Colon {
1617             // The value expression can be a labeled loop, see issue #86948, e.g.:
1618             // `loop { break 'label: loop { break 'label 42; }; }`
1619             let lexpr = self.parse_labeled_expr(label.take().unwrap(), AttrVec::new(), true)?;
1620             self.struct_span_err(
1621                 lexpr.span,
1622                 "parentheses are required around this expression to avoid confusion with a labeled break expression",
1623             )
1624             .multipart_suggestion(
1625                 "wrap the expression in parentheses",
1626                 vec![
1627                     (lexpr.span.shrink_to_lo(), "(".to_string()),
1628                     (lexpr.span.shrink_to_hi(), ")".to_string()),
1629                 ],
1630                 Applicability::MachineApplicable,
1631             )
1632             .emit();
1633             Some(lexpr)
1634         } else if self.token != token::OpenDelim(token::Brace)
1635             || !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
1636         {
1637             let expr = self.parse_expr_opt()?;
1638             if let Some(ref expr) = expr {
1639                 if label.is_some()
1640                     && matches!(
1641                         expr.kind,
1642                         ExprKind::While(_, _, None)
1643                             | ExprKind::ForLoop(_, _, _, None)
1644                             | ExprKind::Loop(_, None)
1645                             | ExprKind::Block(_, None)
1646                     )
1647                 {
1648                     self.sess.buffer_lint_with_diagnostic(
1649                         BREAK_WITH_LABEL_AND_LOOP,
1650                         lo.to(expr.span),
1651                         ast::CRATE_NODE_ID,
1652                         "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression",
1653                         BuiltinLintDiagnostics::BreakWithLabelAndLoop(expr.span),
1654                     );
1655                 }
1656             }
1657             expr
1658         } else {
1659             None
1660         };
1661         let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Break(label, kind), attrs);
1662         self.maybe_recover_from_bad_qpath(expr, true)
1663     }
1664
1665     /// Parse `"yield" expr?`.
1666     fn parse_yield_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1667         let lo = self.prev_token.span;
1668         let kind = ExprKind::Yield(self.parse_expr_opt()?);
1669         let span = lo.to(self.prev_token.span);
1670         self.sess.gated_spans.gate(sym::generators, span);
1671         let expr = self.mk_expr(span, kind, attrs);
1672         self.maybe_recover_from_bad_qpath(expr, true)
1673     }
1674
1675     /// Returns a string literal if the next token is a string literal.
1676     /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
1677     /// and returns `None` if the next token is not literal at all.
1678     pub fn parse_str_lit(&mut self) -> Result<ast::StrLit, Option<Lit>> {
1679         match self.parse_opt_lit() {
1680             Some(lit) => match lit.kind {
1681                 ast::LitKind::Str(symbol_unescaped, style) => Ok(ast::StrLit {
1682                     style,
1683                     symbol: lit.token.symbol,
1684                     suffix: lit.token.suffix,
1685                     span: lit.span,
1686                     symbol_unescaped,
1687                 }),
1688                 _ => Err(Some(lit)),
1689             },
1690             None => Err(None),
1691         }
1692     }
1693
1694     pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
1695         self.parse_opt_lit().ok_or_else(|| {
1696             if let token::Interpolated(inner) = &self.token.kind {
1697                 let expr = match inner.as_ref() {
1698                     token::NtExpr(expr) => Some(expr),
1699                     token::NtLiteral(expr) => Some(expr),
1700                     _ => None,
1701                 };
1702                 if let Some(expr) = expr {
1703                     if matches!(expr.kind, ExprKind::Err) {
1704                         let mut err = self
1705                             .diagnostic()
1706                             .struct_span_err(self.token.span, "invalid interpolated expression");
1707                         err.downgrade_to_delayed_bug();
1708                         return err;
1709                     }
1710                 }
1711             }
1712             let msg = format!("unexpected token: {}", super::token_descr(&self.token));
1713             self.struct_span_err(self.token.span, &msg)
1714         })
1715     }
1716
1717     /// Matches `lit = true | false | token_lit`.
1718     /// Returns `None` if the next token is not a literal.
1719     pub(super) fn parse_opt_lit(&mut self) -> Option<Lit> {
1720         let mut recovered = None;
1721         if self.token == token::Dot {
1722             // Attempt to recover `.4` as `0.4`. We don't currently have any syntax where
1723             // dot would follow an optional literal, so we do this unconditionally.
1724             recovered = self.look_ahead(1, |next_token| {
1725                 if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) =
1726                     next_token.kind
1727                 {
1728                     if self.token.span.hi() == next_token.span.lo() {
1729                         let s = String::from("0.") + symbol.as_str();
1730                         let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix);
1731                         return Some(Token::new(kind, self.token.span.to(next_token.span)));
1732                     }
1733                 }
1734                 None
1735             });
1736             if let Some(token) = &recovered {
1737                 self.bump();
1738                 self.error_float_lits_must_have_int_part(&token);
1739             }
1740         }
1741
1742         let token = recovered.as_ref().unwrap_or(&self.token);
1743         match Lit::from_token(token) {
1744             Ok(lit) => {
1745                 self.bump();
1746                 Some(lit)
1747             }
1748             Err(LitError::NotLiteral) => None,
1749             Err(err) => {
1750                 let span = token.span;
1751                 let token::Literal(lit) = token.kind else {
1752                     unreachable!();
1753                 };
1754                 self.bump();
1755                 self.report_lit_error(err, lit, span);
1756                 // Pack possible quotes and prefixes from the original literal into
1757                 // the error literal's symbol so they can be pretty-printed faithfully.
1758                 let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
1759                 let symbol = Symbol::intern(&suffixless_lit.to_string());
1760                 let lit = token::Lit::new(token::Err, symbol, lit.suffix);
1761                 Some(Lit::from_lit_token(lit, span).unwrap_or_else(|_| unreachable!()))
1762             }
1763         }
1764     }
1765
1766     fn error_float_lits_must_have_int_part(&self, token: &Token) {
1767         self.struct_span_err(token.span, "float literals must have an integer part")
1768             .span_suggestion(
1769                 token.span,
1770                 "must have an integer part",
1771                 pprust::token_to_string(token).into(),
1772                 Applicability::MachineApplicable,
1773             )
1774             .emit();
1775     }
1776
1777     fn report_lit_error(&self, err: LitError, lit: token::Lit, span: Span) {
1778         // Checks if `s` looks like i32 or u1234 etc.
1779         fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
1780             s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
1781         }
1782
1783         // Try to lowercase the prefix if it's a valid base prefix.
1784         fn fix_base_capitalisation(s: &str) -> Option<String> {
1785             if let Some(stripped) = s.strip_prefix('B') {
1786                 Some(format!("0b{stripped}"))
1787             } else if let Some(stripped) = s.strip_prefix('O') {
1788                 Some(format!("0o{stripped}"))
1789             } else if let Some(stripped) = s.strip_prefix('X') {
1790                 Some(format!("0x{stripped}"))
1791             } else {
1792                 None
1793             }
1794         }
1795
1796         let token::Lit { kind, suffix, .. } = lit;
1797         match err {
1798             // `NotLiteral` is not an error by itself, so we don't report
1799             // it and give the parser opportunity to try something else.
1800             LitError::NotLiteral => {}
1801             // `LexerError` *is* an error, but it was already reported
1802             // by lexer, so here we don't report it the second time.
1803             LitError::LexerError => {}
1804             LitError::InvalidSuffix => {
1805                 self.expect_no_suffix(
1806                     span,
1807                     &format!("{} {} literal", kind.article(), kind.descr()),
1808                     suffix,
1809                 );
1810             }
1811             LitError::InvalidIntSuffix => {
1812                 let suf = suffix.expect("suffix error with no suffix");
1813                 let suf = suf.as_str();
1814                 if looks_like_width_suffix(&['i', 'u'], &suf) {
1815                     // If it looks like a width, try to be helpful.
1816                     let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
1817                     self.struct_span_err(span, &msg)
1818                         .help("valid widths are 8, 16, 32, 64 and 128")
1819                         .emit();
1820                 } else if let Some(fixed) = fix_base_capitalisation(suf) {
1821                     let msg = "invalid base prefix for number literal";
1822
1823                     self.struct_span_err(span, msg)
1824                         .note("base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase")
1825                         .span_suggestion(
1826                             span,
1827                             "try making the prefix lowercase",
1828                             fixed,
1829                             Applicability::MaybeIncorrect,
1830                         )
1831                         .emit();
1832                 } else {
1833                     let msg = format!("invalid suffix `{suf}` for number literal");
1834                     self.struct_span_err(span, &msg)
1835                         .span_label(span, format!("invalid suffix `{suf}`"))
1836                         .help("the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)")
1837                         .emit();
1838                 }
1839             }
1840             LitError::InvalidFloatSuffix => {
1841                 let suf = suffix.expect("suffix error with no suffix");
1842                 let suf = suf.as_str();
1843                 if looks_like_width_suffix(&['f'], suf) {
1844                     // If it looks like a width, try to be helpful.
1845                     let msg = format!("invalid width `{}` for float literal", &suf[1..]);
1846                     self.struct_span_err(span, &msg).help("valid widths are 32 and 64").emit();
1847                 } else {
1848                     let msg = format!("invalid suffix `{suf}` for float literal");
1849                     self.struct_span_err(span, &msg)
1850                         .span_label(span, format!("invalid suffix `{suf}`"))
1851                         .help("valid suffixes are `f32` and `f64`")
1852                         .emit();
1853                 }
1854             }
1855             LitError::NonDecimalFloat(base) => {
1856                 let descr = match base {
1857                     16 => "hexadecimal",
1858                     8 => "octal",
1859                     2 => "binary",
1860                     _ => unreachable!(),
1861                 };
1862                 self.struct_span_err(span, &format!("{descr} float literal is not supported"))
1863                     .span_label(span, "not supported")
1864                     .emit();
1865             }
1866             LitError::IntTooLarge => {
1867                 self.struct_span_err(span, "integer literal is too large").emit();
1868             }
1869         }
1870     }
1871
1872     pub(super) fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<Symbol>) {
1873         if let Some(suf) = suffix {
1874             let mut err = if kind == "a tuple index"
1875                 && [sym::i32, sym::u32, sym::isize, sym::usize].contains(&suf)
1876             {
1877                 // #59553: warn instead of reject out of hand to allow the fix to percolate
1878                 // through the ecosystem when people fix their macros
1879                 let mut err = self
1880                     .sess
1881                     .span_diagnostic
1882                     .struct_span_warn(sp, &format!("suffixes on {kind} are invalid"));
1883                 err.note(&format!(
1884                     "`{}` is *temporarily* accepted on tuple index fields as it was \
1885                         incorrectly accepted on stable for a few releases",
1886                     suf,
1887                 ));
1888                 err.help(
1889                     "on proc macros, you'll want to use `syn::Index::from` or \
1890                         `proc_macro::Literal::*_unsuffixed` for code that will desugar \
1891                         to tuple field access",
1892                 );
1893                 err.note(
1894                     "see issue #60210 <https://github.com/rust-lang/rust/issues/60210> \
1895                      for more information",
1896                 );
1897                 err
1898             } else {
1899                 self.struct_span_err(sp, &format!("suffixes on {kind} are invalid"))
1900                     .forget_guarantee()
1901             };
1902             err.span_label(sp, format!("invalid suffix `{suf}`"));
1903             err.emit();
1904         }
1905     }
1906
1907     /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
1908     /// Keep this in sync with `Token::can_begin_literal_maybe_minus`.
1909     pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
1910         maybe_whole_expr!(self);
1911
1912         let lo = self.token.span;
1913         let minus_present = self.eat(&token::BinOp(token::Minus));
1914         let lit = self.parse_lit()?;
1915         let expr = self.mk_expr(lit.span, ExprKind::Lit(lit), AttrVec::new());
1916
1917         if minus_present {
1918             Ok(self.mk_expr(
1919                 lo.to(self.prev_token.span),
1920                 self.mk_unary(UnOp::Neg, expr),
1921                 AttrVec::new(),
1922             ))
1923         } else {
1924             Ok(expr)
1925         }
1926     }
1927
1928     fn is_array_like_block(&mut self) -> bool {
1929         self.look_ahead(1, |t| matches!(t.kind, TokenKind::Ident(..) | TokenKind::Literal(_)))
1930             && self.look_ahead(2, |t| t == &token::Comma)
1931             && self.look_ahead(3, |t| t.can_begin_expr())
1932     }
1933
1934     /// Emits a suggestion if it looks like the user meant an array but
1935     /// accidentally used braces, causing the code to be interpreted as a block
1936     /// expression.
1937     fn maybe_suggest_brackets_instead_of_braces(
1938         &mut self,
1939         lo: Span,
1940         attrs: AttrVec,
1941     ) -> Option<P<Expr>> {
1942         let mut snapshot = self.create_snapshot_for_diagnostic();
1943         match snapshot.parse_array_or_repeat_expr(attrs, token::Brace) {
1944             Ok(arr) => {
1945                 let hi = snapshot.prev_token.span;
1946                 self.struct_span_err(arr.span, "this is a block expression, not an array")
1947                     .multipart_suggestion(
1948                         "to make an array, use square brackets instead of curly braces",
1949                         vec![(lo, "[".to_owned()), (hi, "]".to_owned())],
1950                         Applicability::MaybeIncorrect,
1951                     )
1952                     .emit();
1953
1954                 self.restore_snapshot(snapshot);
1955                 Some(self.mk_expr_err(arr.span))
1956             }
1957             Err(e) => {
1958                 e.cancel();
1959                 None
1960             }
1961         }
1962     }
1963
1964     /// Parses a block or unsafe block.
1965     pub(super) fn parse_block_expr(
1966         &mut self,
1967         opt_label: Option<Label>,
1968         lo: Span,
1969         blk_mode: BlockCheckMode,
1970         mut attrs: AttrVec,
1971     ) -> PResult<'a, P<Expr>> {
1972         if self.is_array_like_block() {
1973             if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo, attrs.clone()) {
1974                 return Ok(arr);
1975             }
1976         }
1977
1978         if let Some(label) = opt_label {
1979             self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
1980         }
1981
1982         if self.token.is_whole_block() {
1983             self.struct_span_err(self.token.span, "cannot use a `block` macro fragment here")
1984                 .span_label(lo.to(self.token.span), "the `block` fragment is within this context")
1985                 .emit();
1986         }
1987
1988         let (inner_attrs, blk) = self.parse_block_common(lo, blk_mode)?;
1989         attrs.extend(inner_attrs);
1990         Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
1991     }
1992
1993     /// Recover on an explicitly quantified closure expression, e.g., `for<'a> |x: &'a u8| *x + 1`.
1994     fn recover_quantified_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
1995         let lo = self.token.span;
1996         let _ = self.parse_late_bound_lifetime_defs()?;
1997         let span_for = lo.to(self.prev_token.span);
1998         let closure = self.parse_closure_expr(attrs)?;
1999
2000         self.struct_span_err(span_for, "cannot introduce explicit parameters for a closure")
2001             .span_label(closure.span, "the parameters are attached to this closure")
2002             .span_suggestion(
2003                 span_for,
2004                 "remove the parameters",
2005                 String::new(),
2006                 Applicability::MachineApplicable,
2007             )
2008             .emit();
2009
2010         Ok(self.mk_expr_err(lo.to(closure.span)))
2011     }
2012
2013     /// Parses a closure expression (e.g., `move |args| expr`).
2014     fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
2015         let lo = self.token.span;
2016
2017         let movability =
2018             if self.eat_keyword(kw::Static) { Movability::Static } else { Movability::Movable };
2019
2020         let asyncness = if self.token.uninterpolated_span().rust_2018() {
2021             self.parse_asyncness()
2022         } else {
2023             Async::No
2024         };
2025
2026         let capture_clause = self.parse_capture_clause()?;
2027         let decl = self.parse_fn_block_decl()?;
2028         let decl_hi = self.prev_token.span;
2029         let mut body = match decl.output {
2030             FnRetTy::Default(_) => {
2031                 let restrictions = self.restrictions - Restrictions::STMT_EXPR;
2032                 self.parse_expr_res(restrictions, None)?
2033             }
2034             _ => {
2035                 // If an explicit return type is given, require a block to appear (RFC 968).
2036                 let body_lo = self.token.span;
2037                 self.parse_block_expr(None, body_lo, BlockCheckMode::Default, AttrVec::new())?
2038             }
2039         };
2040
2041         if let Async::Yes { span, .. } = asyncness {
2042             // Feature-gate `async ||` closures.
2043             self.sess.gated_spans.gate(sym::async_closure, span);
2044         }
2045
2046         if self.token.kind == TokenKind::Semi
2047             && matches!(self.token_cursor.frame.delim_sp, Some((DelimToken::Paren, _)))
2048         {
2049             // It is likely that the closure body is a block but where the
2050             // braces have been removed. We will recover and eat the next
2051             // statements later in the parsing process.
2052             body = self.mk_expr_err(body.span);
2053         }
2054
2055         let body_span = body.span;
2056
2057         let closure = self.mk_expr(
2058             lo.to(body.span),
2059             ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)),
2060             attrs,
2061         );
2062
2063         // Disable recovery for closure body
2064         let spans =
2065             ClosureSpans { whole_closure: closure.span, closing_pipe: decl_hi, body: body_span };
2066         self.current_closure = Some(spans);
2067
2068         Ok(closure)
2069     }
2070
2071     /// Parses an optional `move` prefix to a closure-like construct.
2072     fn parse_capture_clause(&mut self) -> PResult<'a, CaptureBy> {
2073         if self.eat_keyword(kw::Move) {
2074             // Check for `move async` and recover
2075             if self.check_keyword(kw::Async) {
2076                 let move_async_span = self.token.span.with_lo(self.prev_token.span.data().lo);
2077                 Err(self.incorrect_move_async_order_found(move_async_span))
2078             } else {
2079                 Ok(CaptureBy::Value)
2080             }
2081         } else {
2082             Ok(CaptureBy::Ref)
2083         }
2084     }
2085
2086     /// Parses the `|arg, arg|` header of a closure.
2087     fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
2088         let inputs = if self.eat(&token::OrOr) {
2089             Vec::new()
2090         } else {
2091             self.expect(&token::BinOp(token::Or))?;
2092             let args = self
2093                 .parse_seq_to_before_tokens(
2094                     &[&token::BinOp(token::Or), &token::OrOr],
2095                     SeqSep::trailing_allowed(token::Comma),
2096                     TokenExpectType::NoExpect,
2097                     |p| p.parse_fn_block_param(),
2098                 )?
2099                 .0;
2100             self.expect_or()?;
2101             args
2102         };
2103         let output =
2104             self.parse_ret_ty(AllowPlus::Yes, RecoverQPath::Yes, RecoverReturnSign::Yes)?;
2105
2106         Ok(P(FnDecl { inputs, output }))
2107     }
2108
2109     /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
2110     fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
2111         let lo = self.token.span;
2112         let attrs = self.parse_outer_attributes()?;
2113         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
2114             let pat = this.parse_pat_no_top_alt(PARAM_EXPECTED)?;
2115             let ty = if this.eat(&token::Colon) {
2116                 this.parse_ty()?
2117             } else {
2118                 this.mk_ty(this.prev_token.span, TyKind::Infer)
2119             };
2120
2121             Ok((
2122                 Param {
2123                     attrs: attrs.into(),
2124                     ty,
2125                     pat,
2126                     span: lo.to(this.token.span),
2127                     id: DUMMY_NODE_ID,
2128                     is_placeholder: false,
2129                 },
2130                 TrailingToken::MaybeComma,
2131             ))
2132         })
2133     }
2134
2135     /// Parses an `if` expression (`if` token already eaten).
2136     fn parse_if_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
2137         let lo = self.prev_token.span;
2138         let cond = self.parse_cond_expr()?;
2139
2140         let missing_then_block_binop_span = || {
2141             match cond.kind {
2142                 ExprKind::Binary(Spanned { span: binop_span, .. }, _, ref right)
2143                     if let ExprKind::Block(..) = right.kind => Some(binop_span),
2144                 _ => None
2145             }
2146         };
2147
2148         // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
2149         // verify that the last statement is either an implicit return (no `;`) or an explicit
2150         // return. This won't catch blocks with an explicit `return`, but that would be caught by
2151         // the dead code lint.
2152         let thn = if self.token.is_keyword(kw::Else) || !cond.returns() {
2153             if let Some(binop_span) = missing_then_block_binop_span() {
2154                 self.error_missing_if_then_block(lo, None, Some(binop_span)).emit();
2155                 self.mk_block_err(cond.span)
2156             } else {
2157                 self.error_missing_if_cond(lo, cond.span)
2158             }
2159         } else {
2160             let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
2161             let not_block = self.token != token::OpenDelim(token::Brace);
2162             let block = self.parse_block().map_err(|err| {
2163                 if not_block {
2164                     self.error_missing_if_then_block(lo, Some(err), missing_then_block_binop_span())
2165                 } else {
2166                     err
2167                 }
2168             })?;
2169             self.error_on_if_block_attrs(lo, false, block.span, &attrs);
2170             block
2171         };
2172         let els = if self.eat_keyword(kw::Else) { Some(self.parse_else_expr()?) } else { None };
2173         Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els), attrs))
2174     }
2175
2176     fn error_missing_if_then_block(
2177         &self,
2178         if_span: Span,
2179         err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>>,
2180         binop_span: Option<Span>,
2181     ) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
2182         let msg = "this `if` expression has a condition, but no block";
2183
2184         let mut err = if let Some(mut err) = err {
2185             err.span_label(if_span, msg);
2186             err
2187         } else {
2188             self.struct_span_err(if_span, msg)
2189         };
2190
2191         if let Some(binop_span) = binop_span {
2192             err.span_help(binop_span, "maybe you forgot the right operand of the condition?");
2193         }
2194
2195         err
2196     }
2197
2198     fn error_missing_if_cond(&self, lo: Span, span: Span) -> P<ast::Block> {
2199         let sp = self.sess.source_map().next_point(lo);
2200         self.struct_span_err(sp, "missing condition for `if` expression")
2201             .span_label(sp, "expected if condition here")
2202             .emit();
2203         self.mk_block_err(span)
2204     }
2205
2206     /// Parses the condition of a `if` or `while` expression.
2207     fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
2208         let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
2209
2210         if let ExprKind::Let(..) = cond.kind {
2211             // Remove the last feature gating of a `let` expression since it's stable.
2212             self.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
2213         }
2214
2215         Ok(cond)
2216     }
2217
2218     /// Parses a `let $pat = $expr` pseudo-expression.
2219     /// The `let` token has already been eaten.
2220     fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
2221         let lo = self.prev_token.span;
2222         let pat = self.parse_pat_allow_top_alt(
2223             None,
2224             RecoverComma::Yes,
2225             RecoverColon::Yes,
2226             CommaRecoveryMode::LikelyTuple,
2227         )?;
2228         self.expect(&token::Eq)?;
2229         let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| {
2230             this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
2231         })?;
2232         let span = lo.to(expr.span);
2233         self.sess.gated_spans.gate(sym::let_chains, span);
2234         Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span), attrs))
2235     }
2236
2237     /// Parses an `else { ... }` expression (`else` token already eaten).
2238     fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
2239         let ctx_span = self.prev_token.span; // `else`
2240         let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
2241         let expr = if self.eat_keyword(kw::If) {
2242             self.parse_if_expr(AttrVec::new())?
2243         } else {
2244             let blk = self.parse_block()?;
2245             self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new())
2246         };
2247         self.error_on_if_block_attrs(ctx_span, true, expr.span, &attrs);
2248         Ok(expr)
2249     }
2250
2251     fn error_on_if_block_attrs(
2252         &self,
2253         ctx_span: Span,
2254         is_ctx_else: bool,
2255         branch_span: Span,
2256         attrs: &[ast::Attribute],
2257     ) {
2258         let (span, last) = match attrs {
2259             [] => return,
2260             [x0 @ xn] | [x0, .., xn] => (x0.span.to(xn.span), xn.span),
2261         };
2262         let ctx = if is_ctx_else { "else" } else { "if" };
2263         self.struct_span_err(last, "outer attributes are not allowed on `if` and `else` branches")
2264             .span_label(branch_span, "the attributes are attached to this branch")
2265             .span_label(ctx_span, format!("the branch belongs to this `{ctx}`"))
2266             .span_suggestion(
2267                 span,
2268                 "remove the attributes",
2269                 String::new(),
2270                 Applicability::MachineApplicable,
2271             )
2272             .emit();
2273     }
2274
2275     /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
2276     fn parse_for_expr(
2277         &mut self,
2278         opt_label: Option<Label>,
2279         lo: Span,
2280         mut attrs: AttrVec,
2281     ) -> PResult<'a, P<Expr>> {
2282         // Record whether we are about to parse `for (`.
2283         // This is used below for recovery in case of `for ( $stuff ) $block`
2284         // in which case we will suggest `for $stuff $block`.
2285         let begin_paren = match self.token.kind {
2286             token::OpenDelim(token::Paren) => Some(self.token.span),
2287             _ => None,
2288         };
2289
2290         let pat = self.parse_pat_allow_top_alt(
2291             None,
2292             RecoverComma::Yes,
2293             RecoverColon::Yes,
2294             CommaRecoveryMode::LikelyTuple,
2295         )?;
2296         if !self.eat_keyword(kw::In) {
2297             self.error_missing_in_for_loop();
2298         }
2299         self.check_for_for_in_in_typo(self.prev_token.span);
2300         let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
2301
2302         let pat = self.recover_parens_around_for_head(pat, begin_paren);
2303
2304         let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
2305         attrs.extend(iattrs);
2306
2307         let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label);
2308         Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
2309     }
2310
2311     fn error_missing_in_for_loop(&mut self) {
2312         let (span, msg, sugg) = if self.token.is_ident_named(sym::of) {
2313             // Possibly using JS syntax (#75311).
2314             let span = self.token.span;
2315             self.bump();
2316             (span, "try using `in` here instead", "in")
2317         } else {
2318             (self.prev_token.span.between(self.token.span), "try adding `in` here", " in ")
2319         };
2320         self.struct_span_err(span, "missing `in` in `for` loop")
2321             .span_suggestion_short(
2322                 span,
2323                 msg,
2324                 sugg.into(),
2325                 // Has been misleading, at least in the past (closed Issue #48492).
2326                 Applicability::MaybeIncorrect,
2327             )
2328             .emit();
2329     }
2330
2331     /// Parses a `while` or `while let` expression (`while` token already eaten).
2332     fn parse_while_expr(
2333         &mut self,
2334         opt_label: Option<Label>,
2335         lo: Span,
2336         mut attrs: AttrVec,
2337     ) -> PResult<'a, P<Expr>> {
2338         let cond = self.parse_cond_expr().map_err(|mut err| {
2339             err.span_label(lo, "while parsing the condition of this `while` expression");
2340             err
2341         })?;
2342         let (iattrs, body) = self.parse_inner_attrs_and_block().map_err(|mut err| {
2343             err.span_label(lo, "while parsing the body of this `while` expression");
2344             err.span_label(cond.span, "this `while` condition successfully parsed");
2345             err
2346         })?;
2347         attrs.extend(iattrs);
2348         Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::While(cond, body, opt_label), attrs))
2349     }
2350
2351     /// Parses `loop { ... }` (`loop` token already eaten).
2352     fn parse_loop_expr(
2353         &mut self,
2354         opt_label: Option<Label>,
2355         lo: Span,
2356         mut attrs: AttrVec,
2357     ) -> PResult<'a, P<Expr>> {
2358         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
2359         attrs.extend(iattrs);
2360         Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::Loop(body, opt_label), attrs))
2361     }
2362
2363     crate fn eat_label(&mut self) -> Option<Label> {
2364         self.token.lifetime().map(|ident| {
2365             self.bump();
2366             Label { ident }
2367         })
2368     }
2369
2370     /// Parses a `match ... { ... }` expression (`match` token already eaten).
2371     fn parse_match_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
2372         let match_span = self.prev_token.span;
2373         let lo = self.prev_token.span;
2374         let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
2375         if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) {
2376             if self.token == token::Semi {
2377                 e.span_suggestion_short(
2378                     match_span,
2379                     "try removing this `match`",
2380                     String::new(),
2381                     Applicability::MaybeIncorrect, // speculative
2382                 );
2383             }
2384             if self.maybe_recover_unexpected_block_label() {
2385                 e.cancel();
2386                 self.bump();
2387             } else {
2388                 return Err(e);
2389             }
2390         }
2391         attrs.extend(self.parse_inner_attributes()?);
2392
2393         let mut arms: Vec<Arm> = Vec::new();
2394         while self.token != token::CloseDelim(token::Brace) {
2395             match self.parse_arm() {
2396                 Ok(arm) => arms.push(arm),
2397                 Err(mut e) => {
2398                     // Recover by skipping to the end of the block.
2399                     e.emit();
2400                     self.recover_stmt();
2401                     let span = lo.to(self.token.span);
2402                     if self.token == token::CloseDelim(token::Brace) {
2403                         self.bump();
2404                     }
2405                     return Ok(self.mk_expr(span, ExprKind::Match(scrutinee, arms), attrs));
2406                 }
2407             }
2408         }
2409         let hi = self.token.span;
2410         self.bump();
2411         Ok(self.mk_expr(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
2412     }
2413
2414     /// Attempt to recover from match arm body with statements and no surrounding braces.
2415     fn parse_arm_body_missing_braces(
2416         &mut self,
2417         first_expr: &P<Expr>,
2418         arrow_span: Span,
2419     ) -> Option<P<Expr>> {
2420         if self.token.kind != token::Semi {
2421             return None;
2422         }
2423         let start_snapshot = self.create_snapshot_for_diagnostic();
2424         let semi_sp = self.token.span;
2425         self.bump(); // `;`
2426         let mut stmts =
2427             vec![self.mk_stmt(first_expr.span, ast::StmtKind::Expr(first_expr.clone()))];
2428         let err = |this: &mut Parser<'_>, stmts: Vec<ast::Stmt>| {
2429             let span = stmts[0].span.to(stmts[stmts.len() - 1].span);
2430             let mut err = this.struct_span_err(span, "`match` arm body without braces");
2431             let (these, s, are) =
2432                 if stmts.len() > 1 { ("these", "s", "are") } else { ("this", "", "is") };
2433             err.span_label(
2434                 span,
2435                 &format!(
2436                     "{these} statement{s} {are} not surrounded by a body",
2437                     these = these,
2438                     s = s,
2439                     are = are
2440                 ),
2441             );
2442             err.span_label(arrow_span, "while parsing the `match` arm starting here");
2443             if stmts.len() > 1 {
2444                 err.multipart_suggestion(
2445                     &format!("surround the statement{s} with a body"),
2446                     vec![
2447                         (span.shrink_to_lo(), "{ ".to_string()),
2448                         (span.shrink_to_hi(), " }".to_string()),
2449                     ],
2450                     Applicability::MachineApplicable,
2451                 );
2452             } else {
2453                 err.span_suggestion(
2454                     semi_sp,
2455                     "use a comma to end a `match` arm expression",
2456                     ",".to_string(),
2457                     Applicability::MachineApplicable,
2458                 );
2459             }
2460             err.emit();
2461             this.mk_expr_err(span)
2462         };
2463         // We might have either a `,` -> `;` typo, or a block without braces. We need
2464         // a more subtle parsing strategy.
2465         loop {
2466             if self.token.kind == token::CloseDelim(token::Brace) {
2467                 // We have reached the closing brace of the `match` expression.
2468                 return Some(err(self, stmts));
2469             }
2470             if self.token.kind == token::Comma {
2471                 self.restore_snapshot(start_snapshot);
2472                 return None;
2473             }
2474             let pre_pat_snapshot = self.create_snapshot_for_diagnostic();
2475             match self.parse_pat_no_top_alt(None) {
2476                 Ok(_pat) => {
2477                     if self.token.kind == token::FatArrow {
2478                         // Reached arm end.
2479                         self.restore_snapshot(pre_pat_snapshot);
2480                         return Some(err(self, stmts));
2481                     }
2482                 }
2483                 Err(err) => {
2484                     err.cancel();
2485                 }
2486             }
2487
2488             self.restore_snapshot(pre_pat_snapshot);
2489             match self.parse_stmt_without_recovery(true, ForceCollect::No) {
2490                 // Consume statements for as long as possible.
2491                 Ok(Some(stmt)) => {
2492                     stmts.push(stmt);
2493                 }
2494                 Ok(None) => {
2495                     self.restore_snapshot(start_snapshot);
2496                     break;
2497                 }
2498                 // We couldn't parse either yet another statement missing it's
2499                 // enclosing block nor the next arm's pattern or closing brace.
2500                 Err(stmt_err) => {
2501                     stmt_err.cancel();
2502                     self.restore_snapshot(start_snapshot);
2503                     break;
2504                 }
2505             }
2506         }
2507         None
2508     }
2509
2510     pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
2511         fn check_let_expr(expr: &Expr) -> (bool, bool) {
2512             match expr.kind {
2513                 ExprKind::Binary(_, ref lhs, ref rhs) => {
2514                     let lhs_rslt = check_let_expr(lhs);
2515                     let rhs_rslt = check_let_expr(rhs);
2516                     (lhs_rslt.0 || rhs_rslt.0, false)
2517                 }
2518                 ExprKind::Let(..) => (true, true),
2519                 _ => (false, true),
2520             }
2521         }
2522         let attrs = self.parse_outer_attributes()?;
2523         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
2524             let lo = this.token.span;
2525             let pat = this.parse_pat_allow_top_alt(
2526                 None,
2527                 RecoverComma::Yes,
2528                 RecoverColon::Yes,
2529                 CommaRecoveryMode::EitherTupleOrPipe,
2530             )?;
2531             let guard = if this.eat_keyword(kw::If) {
2532                 let if_span = this.prev_token.span;
2533                 let cond = this.parse_expr()?;
2534                 let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond);
2535                 if has_let_expr {
2536                     if does_not_have_bin_op {
2537                         // Remove the last feature gating of a `let` expression since it's stable.
2538                         this.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
2539                     }
2540                     let span = if_span.to(cond.span);
2541                     this.sess.gated_spans.gate(sym::if_let_guard, span);
2542                 }
2543                 Some(cond)
2544             } else {
2545                 None
2546             };
2547             let arrow_span = this.token.span;
2548             if let Err(mut err) = this.expect(&token::FatArrow) {
2549                 // We might have a `=>` -> `=` or `->` typo (issue #89396).
2550                 if TokenKind::FatArrow
2551                     .similar_tokens()
2552                     .map_or(false, |similar_tokens| similar_tokens.contains(&this.token.kind))
2553                 {
2554                     err.span_suggestion(
2555                         this.token.span,
2556                         "try using a fat arrow here",
2557                         "=>".to_string(),
2558                         Applicability::MaybeIncorrect,
2559                     );
2560                     err.emit();
2561                     this.bump();
2562                 } else {
2563                     return Err(err);
2564                 }
2565             }
2566             let arm_start_span = this.token.span;
2567
2568             let expr = this.parse_expr_res(Restrictions::STMT_EXPR, None).map_err(|mut err| {
2569                 err.span_label(arrow_span, "while parsing the `match` arm starting here");
2570                 err
2571             })?;
2572
2573             let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
2574                 && this.token != token::CloseDelim(token::Brace);
2575
2576             let hi = this.prev_token.span;
2577
2578             if require_comma {
2579                 let sm = this.sess.source_map();
2580                 if let Some(body) = this.parse_arm_body_missing_braces(&expr, arrow_span) {
2581                     let span = body.span;
2582                     return Ok((
2583                         ast::Arm {
2584                             attrs: attrs.into(),
2585                             pat,
2586                             guard,
2587                             body,
2588                             span,
2589                             id: DUMMY_NODE_ID,
2590                             is_placeholder: false,
2591                         },
2592                         TrailingToken::None,
2593                     ));
2594                 }
2595                 this.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]).map_err(
2596                     |mut err| {
2597                         match (sm.span_to_lines(expr.span), sm.span_to_lines(arm_start_span)) {
2598                             (Ok(ref expr_lines), Ok(ref arm_start_lines))
2599                                 if arm_start_lines.lines[0].end_col
2600                                     == expr_lines.lines[0].end_col
2601                                     && expr_lines.lines.len() == 2
2602                                     && this.token == token::FatArrow =>
2603                             {
2604                                 // We check whether there's any trailing code in the parse span,
2605                                 // if there isn't, we very likely have the following:
2606                                 //
2607                                 // X |     &Y => "y"
2608                                 //   |        --    - missing comma
2609                                 //   |        |
2610                                 //   |        arrow_span
2611                                 // X |     &X => "x"
2612                                 //   |      - ^^ self.token.span
2613                                 //   |      |
2614                                 //   |      parsed until here as `"y" & X`
2615                                 err.span_suggestion_short(
2616                                     arm_start_span.shrink_to_hi(),
2617                                     "missing a comma here to end this `match` arm",
2618                                     ",".to_owned(),
2619                                     Applicability::MachineApplicable,
2620                                 );
2621                             }
2622                             _ => {
2623                                 err.span_label(
2624                                     arrow_span,
2625                                     "while parsing the `match` arm starting here",
2626                                 );
2627                             }
2628                         }
2629                         err
2630                     },
2631                 )?;
2632             } else {
2633                 this.eat(&token::Comma);
2634             }
2635
2636             Ok((
2637                 ast::Arm {
2638                     attrs: attrs.into(),
2639                     pat,
2640                     guard,
2641                     body: expr,
2642                     span: lo.to(hi),
2643                     id: DUMMY_NODE_ID,
2644                     is_placeholder: false,
2645                 },
2646                 TrailingToken::None,
2647             ))
2648         })
2649     }
2650
2651     /// Parses a `try {...}` expression (`try` token already eaten).
2652     fn parse_try_block(&mut self, span_lo: Span, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
2653         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
2654         attrs.extend(iattrs);
2655         if self.eat_keyword(kw::Catch) {
2656             let mut error = self.struct_span_err(
2657                 self.prev_token.span,
2658                 "keyword `catch` cannot follow a `try` block",
2659             );
2660             error.help("try using `match` on the result of the `try` block instead");
2661             error.emit();
2662             Err(error)
2663         } else {
2664             let span = span_lo.to(body.span);
2665             self.sess.gated_spans.gate(sym::try_blocks, span);
2666             Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
2667         }
2668     }
2669
2670     fn is_do_catch_block(&self) -> bool {
2671         self.token.is_keyword(kw::Do)
2672             && self.is_keyword_ahead(1, &[kw::Catch])
2673             && self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))
2674             && !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
2675     }
2676
2677     fn is_try_block(&self) -> bool {
2678         self.token.is_keyword(kw::Try)
2679             && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
2680             && self.token.uninterpolated_span().rust_2018()
2681     }
2682
2683     /// Parses an `async move? {...}` expression.
2684     fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
2685         let lo = self.token.span;
2686         self.expect_keyword(kw::Async)?;
2687         let capture_clause = self.parse_capture_clause()?;
2688         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
2689         attrs.extend(iattrs);
2690         let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);
2691         Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
2692     }
2693
2694     fn is_async_block(&self) -> bool {
2695         self.token.is_keyword(kw::Async)
2696             && ((
2697                 // `async move {`
2698                 self.is_keyword_ahead(1, &[kw::Move])
2699                     && self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))
2700             ) || (
2701                 // `async {`
2702                 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
2703             ))
2704     }
2705
2706     fn is_certainly_not_a_block(&self) -> bool {
2707         self.look_ahead(1, |t| t.is_ident())
2708             && (
2709                 // `{ ident, ` cannot start a block.
2710                 self.look_ahead(2, |t| t == &token::Comma)
2711                     || self.look_ahead(2, |t| t == &token::Colon)
2712                         && (
2713                             // `{ ident: token, ` cannot start a block.
2714                             self.look_ahead(4, |t| t == &token::Comma) ||
2715                 // `{ ident: ` cannot start a block unless it's a type ascription `ident: Type`.
2716                 self.look_ahead(3, |t| !t.can_begin_type())
2717                         )
2718             )
2719     }
2720
2721     fn maybe_parse_struct_expr(
2722         &mut self,
2723         qself: Option<&ast::QSelf>,
2724         path: &ast::Path,
2725         attrs: &AttrVec,
2726     ) -> Option<PResult<'a, P<Expr>>> {
2727         let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
2728         if struct_allowed || self.is_certainly_not_a_block() {
2729             if let Err(err) = self.expect(&token::OpenDelim(token::Brace)) {
2730                 return Some(Err(err));
2731             }
2732             let expr = self.parse_struct_expr(qself.cloned(), path.clone(), attrs.clone(), true);
2733             if let (Ok(expr), false) = (&expr, struct_allowed) {
2734                 // This is a struct literal, but we don't can't accept them here.
2735                 self.error_struct_lit_not_allowed_here(path.span, expr.span);
2736             }
2737             return Some(expr);
2738         }
2739         None
2740     }
2741
2742     fn error_struct_lit_not_allowed_here(&self, lo: Span, sp: Span) {
2743         self.struct_span_err(sp, "struct literals are not allowed here")
2744             .multipart_suggestion(
2745                 "surround the struct literal with parentheses",
2746                 vec![(lo.shrink_to_lo(), "(".to_string()), (sp.shrink_to_hi(), ")".to_string())],
2747                 Applicability::MachineApplicable,
2748             )
2749             .emit();
2750     }
2751
2752     pub(super) fn parse_struct_fields(
2753         &mut self,
2754         pth: ast::Path,
2755         recover: bool,
2756         close_delim: token::DelimToken,
2757     ) -> PResult<'a, (Vec<ExprField>, ast::StructRest, bool)> {
2758         let mut fields = Vec::new();
2759         let mut base = ast::StructRest::None;
2760         let mut recover_async = false;
2761
2762         let mut async_block_err = |e: &mut Diagnostic, span: Span| {
2763             recover_async = true;
2764             e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later");
2765             e.help_use_latest_edition();
2766         };
2767
2768         while self.token != token::CloseDelim(close_delim) {
2769             if self.eat(&token::DotDot) {
2770                 let exp_span = self.prev_token.span;
2771                 // We permit `.. }` on the left-hand side of a destructuring assignment.
2772                 if self.check(&token::CloseDelim(close_delim)) {
2773                     base = ast::StructRest::Rest(self.prev_token.span.shrink_to_hi());
2774                     break;
2775                 }
2776                 match self.parse_expr() {
2777                     Ok(e) => base = ast::StructRest::Base(e),
2778                     Err(mut e) if recover => {
2779                         e.emit();
2780                         self.recover_stmt();
2781                     }
2782                     Err(e) => return Err(e),
2783                 }
2784                 self.recover_struct_comma_after_dotdot(exp_span);
2785                 break;
2786             }
2787
2788             let recovery_field = self.find_struct_error_after_field_looking_code();
2789             let parsed_field = match self.parse_expr_field() {
2790                 Ok(f) => Some(f),
2791                 Err(mut e) => {
2792                     if pth == kw::Async {
2793                         async_block_err(&mut e, pth.span);
2794                     } else {
2795                         e.span_label(pth.span, "while parsing this struct");
2796                     }
2797                     e.emit();
2798
2799                     // If the next token is a comma, then try to parse
2800                     // what comes next as additional fields, rather than
2801                     // bailing out until next `}`.
2802                     if self.token != token::Comma {
2803                         self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
2804                         if self.token != token::Comma {
2805                             break;
2806                         }
2807                     }
2808                     None
2809                 }
2810             };
2811
2812             match self.expect_one_of(&[token::Comma], &[token::CloseDelim(close_delim)]) {
2813                 Ok(_) => {
2814                     if let Some(f) = parsed_field.or(recovery_field) {
2815                         // Only include the field if there's no parse error for the field name.
2816                         fields.push(f);
2817                     }
2818                 }
2819                 Err(mut e) => {
2820                     if pth == kw::Async {
2821                         async_block_err(&mut e, pth.span);
2822                     } else {
2823                         e.span_label(pth.span, "while parsing this struct");
2824                         if let Some(f) = recovery_field {
2825                             fields.push(f);
2826                             e.span_suggestion(
2827                                 self.prev_token.span.shrink_to_hi(),
2828                                 "try adding a comma",
2829                                 ",".into(),
2830                                 Applicability::MachineApplicable,
2831                             );
2832                         }
2833                     }
2834                     if !recover {
2835                         return Err(e);
2836                     }
2837                     e.emit();
2838                     self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
2839                     self.eat(&token::Comma);
2840                 }
2841             }
2842         }
2843         Ok((fields, base, recover_async))
2844     }
2845
2846     /// Precondition: already parsed the '{'.
2847     pub(super) fn parse_struct_expr(
2848         &mut self,
2849         qself: Option<ast::QSelf>,
2850         pth: ast::Path,
2851         attrs: AttrVec,
2852         recover: bool,
2853     ) -> PResult<'a, P<Expr>> {
2854         let lo = pth.span;
2855         let (fields, base, recover_async) =
2856             self.parse_struct_fields(pth.clone(), recover, token::Brace)?;
2857         let span = lo.to(self.token.span);
2858         self.expect(&token::CloseDelim(token::Brace))?;
2859         let expr = if recover_async {
2860             ExprKind::Err
2861         } else {
2862             ExprKind::Struct(P(ast::StructExpr { qself, path: pth, fields, rest: base }))
2863         };
2864         Ok(self.mk_expr(span, expr, attrs))
2865     }
2866
2867     /// Use in case of error after field-looking code: `S { foo: () with a }`.
2868     fn find_struct_error_after_field_looking_code(&self) -> Option<ExprField> {
2869         match self.token.ident() {
2870             Some((ident, is_raw))
2871                 if (is_raw || !ident.is_reserved())
2872                     && self.look_ahead(1, |t| *t == token::Colon) =>
2873             {
2874                 Some(ast::ExprField {
2875                     ident,
2876                     span: self.token.span,
2877                     expr: self.mk_expr_err(self.token.span),
2878                     is_shorthand: false,
2879                     attrs: AttrVec::new(),
2880                     id: DUMMY_NODE_ID,
2881                     is_placeholder: false,
2882                 })
2883             }
2884             _ => None,
2885         }
2886     }
2887
2888     fn recover_struct_comma_after_dotdot(&mut self, span: Span) {
2889         if self.token != token::Comma {
2890             return;
2891         }
2892         self.struct_span_err(
2893             span.to(self.prev_token.span),
2894             "cannot use a comma after the base struct",
2895         )
2896         .span_suggestion_short(
2897             self.token.span,
2898             "remove this comma",
2899             String::new(),
2900             Applicability::MachineApplicable,
2901         )
2902         .note("the base struct must always be the last field")
2903         .emit();
2904         self.recover_stmt();
2905     }
2906
2907     /// Parses `ident (COLON expr)?`.
2908     fn parse_expr_field(&mut self) -> PResult<'a, ExprField> {
2909         let attrs = self.parse_outer_attributes()?;
2910         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
2911             let lo = this.token.span;
2912
2913             // Check if a colon exists one ahead. This means we're parsing a fieldname.
2914             let is_shorthand = !this.look_ahead(1, |t| t == &token::Colon || t == &token::Eq);
2915             let (ident, expr) = if is_shorthand {
2916                 // Mimic `x: x` for the `x` field shorthand.
2917                 let ident = this.parse_ident_common(false)?;
2918                 let path = ast::Path::from_ident(ident);
2919                 (ident, this.mk_expr(ident.span, ExprKind::Path(None, path), AttrVec::new()))
2920             } else {
2921                 let ident = this.parse_field_name()?;
2922                 this.error_on_eq_field_init(ident);
2923                 this.bump(); // `:`
2924                 (ident, this.parse_expr()?)
2925             };
2926
2927             Ok((
2928                 ast::ExprField {
2929                     ident,
2930                     span: lo.to(expr.span),
2931                     expr,
2932                     is_shorthand,
2933                     attrs: attrs.into(),
2934                     id: DUMMY_NODE_ID,
2935                     is_placeholder: false,
2936                 },
2937                 TrailingToken::MaybeComma,
2938             ))
2939         })
2940     }
2941
2942     /// Check for `=`. This means the source incorrectly attempts to
2943     /// initialize a field with an eq rather than a colon.
2944     fn error_on_eq_field_init(&self, field_name: Ident) {
2945         if self.token != token::Eq {
2946             return;
2947         }
2948
2949         self.struct_span_err(self.token.span, "expected `:`, found `=`")
2950             .span_suggestion(
2951                 field_name.span.shrink_to_hi().to(self.token.span),
2952                 "replace equals symbol with a colon",
2953                 ":".to_string(),
2954                 Applicability::MachineApplicable,
2955             )
2956             .emit();
2957     }
2958
2959     fn err_dotdotdot_syntax(&self, span: Span) {
2960         self.struct_span_err(span, "unexpected token: `...`")
2961             .span_suggestion(
2962                 span,
2963                 "use `..` for an exclusive range",
2964                 "..".to_owned(),
2965                 Applicability::MaybeIncorrect,
2966             )
2967             .span_suggestion(
2968                 span,
2969                 "or `..=` for an inclusive range",
2970                 "..=".to_owned(),
2971                 Applicability::MaybeIncorrect,
2972             )
2973             .emit();
2974     }
2975
2976     fn err_larrow_operator(&self, span: Span) {
2977         self.struct_span_err(span, "unexpected token: `<-`")
2978             .span_suggestion(
2979                 span,
2980                 "if you meant to write a comparison against a negative value, add a \
2981              space in between `<` and `-`",
2982                 "< -".to_string(),
2983                 Applicability::MaybeIncorrect,
2984             )
2985             .emit();
2986     }
2987
2988     fn mk_assign_op(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
2989         ExprKind::AssignOp(binop, lhs, rhs)
2990     }
2991
2992     fn mk_range(
2993         &mut self,
2994         start: Option<P<Expr>>,
2995         end: Option<P<Expr>>,
2996         limits: RangeLimits,
2997     ) -> ExprKind {
2998         if end.is_none() && limits == RangeLimits::Closed {
2999             self.inclusive_range_with_incorrect_end(self.prev_token.span);
3000             ExprKind::Err
3001         } else {
3002             ExprKind::Range(start, end, limits)
3003         }
3004     }
3005
3006     fn mk_unary(&self, unop: UnOp, expr: P<Expr>) -> ExprKind {
3007         ExprKind::Unary(unop, expr)
3008     }
3009
3010     fn mk_binary(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
3011         ExprKind::Binary(binop, lhs, rhs)
3012     }
3013
3014     fn mk_index(&self, expr: P<Expr>, idx: P<Expr>) -> ExprKind {
3015         ExprKind::Index(expr, idx)
3016     }
3017
3018     fn mk_call(&self, f: P<Expr>, args: Vec<P<Expr>>) -> ExprKind {
3019         ExprKind::Call(f, args)
3020     }
3021
3022     fn mk_await_expr(&mut self, self_arg: P<Expr>, lo: Span) -> P<Expr> {
3023         let span = lo.to(self.prev_token.span);
3024         let await_expr = self.mk_expr(span, ExprKind::Await(self_arg), AttrVec::new());
3025         self.recover_from_await_method_call();
3026         await_expr
3027     }
3028
3029     crate fn mk_expr(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
3030         P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
3031     }
3032
3033     pub(super) fn mk_expr_err(&self, span: Span) -> P<Expr> {
3034         self.mk_expr(span, ExprKind::Err, AttrVec::new())
3035     }
3036
3037     /// Create expression span ensuring the span of the parent node
3038     /// is larger than the span of lhs and rhs, including the attributes.
3039     fn mk_expr_sp(&self, lhs: &P<Expr>, lhs_span: Span, rhs_span: Span) -> Span {
3040         lhs.attrs
3041             .iter()
3042             .find(|a| a.style == AttrStyle::Outer)
3043             .map_or(lhs_span, |a| a.span)
3044             .to(rhs_span)
3045     }
3046
3047     fn collect_tokens_for_expr(
3048         &mut self,
3049         attrs: AttrWrapper,
3050         f: impl FnOnce(&mut Self, Vec<ast::Attribute>) -> PResult<'a, P<Expr>>,
3051     ) -> PResult<'a, P<Expr>> {
3052         self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
3053             let res = f(this, attrs)?;
3054             let trailing = if this.restrictions.contains(Restrictions::STMT_EXPR)
3055                 && this.token.kind == token::Semi
3056             {
3057                 TrailingToken::Semi
3058             } else {
3059                 // FIXME - pass this through from the place where we know
3060                 // we need a comma, rather than assuming that `#[attr] expr,`
3061                 // always captures a trailing comma
3062                 TrailingToken::MaybeComma
3063             };
3064             Ok((res, trailing))
3065         })
3066     }
3067 }