]> git.lizzy.rs Git - rust.git/blob - src/librustc_parse/parser/expr.rs
Add test for issue 63116
[rust.git] / src / librustc_parse / parser / expr.rs
1 use super::{Parser, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode};
2 use super::{SemiColonMode, SeqSep, TokenExpectType};
3 use super::pat::{GateOr, PARAM_EXPECTED};
4 use super::diagnostics::Error;
5 use crate::maybe_recover_from_interpolated_ty_qpath;
6
7 use syntax::ast::{
8     self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode,
9     Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind,
10     FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field, Lit,
11 };
12 use syntax::token::{self, Token, TokenKind};
13 use syntax::print::pprust;
14 use syntax::ptr::P;
15 use syntax::source_map::{self, Span};
16 use syntax::util::classify;
17 use syntax::util::literal::LitError;
18 use syntax::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
19 use syntax_pos::symbol::{kw, sym};
20 use syntax_pos::Symbol;
21 use errors::{PResult, Applicability};
22 use std::mem;
23 use rustc_data_structures::thin_vec::ThinVec;
24
25 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
26 /// dropped into the token stream, which happens while parsing the result of
27 /// macro expansion). Placement of these is not as complex as I feared it would
28 /// be. The important thing is to make sure that lookahead doesn't balk at
29 /// `token::Interpolated` tokens.
30 macro_rules! maybe_whole_expr {
31     ($p:expr) => {
32         if let token::Interpolated(nt) = &$p.token.kind {
33             match &**nt {
34                 token::NtExpr(e) | token::NtLiteral(e) => {
35                     let e = e.clone();
36                     $p.bump();
37                     return Ok(e);
38                 }
39                 token::NtPath(path) => {
40                     let path = path.clone();
41                     $p.bump();
42                     return Ok($p.mk_expr(
43                         $p.token.span, ExprKind::Path(None, path), ThinVec::new()
44                     ));
45                 }
46                 token::NtBlock(block) => {
47                     let block = block.clone();
48                     $p.bump();
49                     return Ok($p.mk_expr(
50                         $p.token.span, ExprKind::Block(block, None), ThinVec::new()
51                     ));
52                 }
53                 // N.B., `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
54                 _ => {},
55             };
56         }
57     }
58 }
59
60 #[derive(Debug)]
61 pub(super) enum LhsExpr {
62     NotYetParsed,
63     AttributesParsed(ThinVec<Attribute>),
64     AlreadyParsed(P<Expr>),
65 }
66
67 impl From<Option<ThinVec<Attribute>>> for LhsExpr {
68     /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)`
69     /// and `None` into `LhsExpr::NotYetParsed`.
70     ///
71     /// This conversion does not allocate.
72     fn from(o: Option<ThinVec<Attribute>>) -> Self {
73         if let Some(attrs) = o {
74             LhsExpr::AttributesParsed(attrs)
75         } else {
76             LhsExpr::NotYetParsed
77         }
78     }
79 }
80
81 impl From<P<Expr>> for LhsExpr {
82     /// Converts the `expr: P<Expr>` into `LhsExpr::AlreadyParsed(expr)`.
83     ///
84     /// This conversion does not allocate.
85     fn from(expr: P<Expr>) -> Self {
86         LhsExpr::AlreadyParsed(expr)
87     }
88 }
89
90 impl<'a> Parser<'a> {
91     /// Parses an expression.
92     #[inline]
93     pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
94         self.parse_expr_res(Restrictions::empty(), None)
95     }
96
97     fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> {
98         self.parse_paren_comma_seq(|p| {
99             match p.parse_expr() {
100                 Ok(expr) => Ok(expr),
101                 Err(mut err) => match p.token.kind {
102                     token::Ident(name, false)
103                     if name == kw::Underscore && p.look_ahead(1, |t| {
104                         t == &token::Comma
105                     }) => {
106                         // Special-case handling of `foo(_, _, _)`
107                         err.emit();
108                         let sp = p.token.span;
109                         p.bump();
110                         Ok(p.mk_expr(sp, ExprKind::Err, ThinVec::new()))
111                     }
112                     _ => Err(err),
113                 },
114             }
115         }).map(|(r, _)| r)
116     }
117
118     /// Parses an expression, subject to the given restrictions.
119     #[inline]
120     pub(super) fn parse_expr_res(
121         &mut self,
122         r: Restrictions,
123         already_parsed_attrs: Option<ThinVec<Attribute>>
124     ) -> PResult<'a, P<Expr>> {
125         self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
126     }
127
128     /// Parses an associative expression.
129     ///
130     /// This parses an expression accounting for associativity and precedence of the operators in
131     /// the expression.
132     #[inline]
133     fn parse_assoc_expr(
134         &mut self,
135         already_parsed_attrs: Option<ThinVec<Attribute>>,
136     ) -> PResult<'a, P<Expr>> {
137         self.parse_assoc_expr_with(0, already_parsed_attrs.into())
138     }
139
140     /// Parses an associative expression with operators of at least `min_prec` precedence.
141     pub(super) fn parse_assoc_expr_with(
142         &mut self,
143         min_prec: usize,
144         lhs: LhsExpr,
145     ) -> PResult<'a, P<Expr>> {
146         let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
147             expr
148         } else {
149             let attrs = match lhs {
150                 LhsExpr::AttributesParsed(attrs) => Some(attrs),
151                 _ => None,
152             };
153             if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind) {
154                 return self.parse_prefix_range_expr(attrs);
155             } else {
156                 self.parse_prefix_expr(attrs)?
157             }
158         };
159         let last_type_ascription_set = self.last_type_ascription.is_some();
160
161         match (self.expr_is_complete(&lhs), AssocOp::from_token(&self.token)) {
162             (true, None) => {
163                 self.last_type_ascription = None;
164                 // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
165                 return Ok(lhs);
166             }
167             (false, _) => {} // continue parsing the expression
168             // An exhaustive check is done in the following block, but these are checked first
169             // because they *are* ambiguous but also reasonable looking incorrect syntax, so we
170             // want to keep their span info to improve diagnostics in these cases in a later stage.
171             (true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
172             (true, Some(AssocOp::Subtract)) | // `{ 42 } -5`
173             (true, Some(AssocOp::LAnd)) | // `{ 42 } &&x` (#61475)
174             (true, Some(AssocOp::Add)) // `{ 42 } + 42
175             // If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
176             // `if x { a } else { b } && if y { c } else { d }`
177             if !self.look_ahead(1, |t| t.is_reserved_ident()) => {
178                 self.last_type_ascription = None;
179                 // These cases are ambiguous and can't be identified in the parser alone
180                 let sp = self.sess.source_map().start_point(self.token.span);
181                 self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
182                 return Ok(lhs);
183             }
184             (true, Some(ref op)) if !op.can_continue_expr_unambiguously() => {
185                 self.last_type_ascription = None;
186                 return Ok(lhs);
187             }
188             (true, Some(_)) => {
189                 // We've found an expression that would be parsed as a statement, but the next
190                 // token implies this should be parsed as an expression.
191                 // For example: `if let Some(x) = x { x } else { 0 } / 2`
192                 let mut err = self.struct_span_err(self.token.span, &format!(
193                     "expected expression, found `{}`",
194                     pprust::token_to_string(&self.token),
195                 ));
196                 err.span_label(self.token.span, "expected expression");
197                 self.sess.expr_parentheses_needed(
198                     &mut err,
199                     lhs.span,
200                     Some(pprust::expr_to_string(&lhs),
201                 ));
202                 err.emit();
203             }
204         }
205         self.expected_tokens.push(TokenType::Operator);
206         while let Some(op) = AssocOp::from_token(&self.token) {
207
208             // Adjust the span for interpolated LHS to point to the `$lhs` token and not to what
209             // it refers to. Interpolated identifiers are unwrapped early and never show up here
210             // as `PrevTokenKind::Interpolated` so if LHS is a single identifier we always process
211             // it as "interpolated", it doesn't change the answer for non-interpolated idents.
212             let lhs_span = match (self.prev_token_kind, &lhs.kind) {
213                 (PrevTokenKind::Interpolated, _) => self.prev_span,
214                 (PrevTokenKind::Ident, &ExprKind::Path(None, ref path))
215                     if path.segments.len() == 1 => self.prev_span,
216                 _ => lhs.span,
217             };
218
219             let cur_op_span = self.token.span;
220             let restrictions = if op.is_assign_like() {
221                 self.restrictions & Restrictions::NO_STRUCT_LITERAL
222             } else {
223                 self.restrictions
224             };
225             let prec = op.precedence();
226             if prec < min_prec {
227                 break;
228             }
229             // Check for deprecated `...` syntax
230             if self.token == token::DotDotDot && op == AssocOp::DotDotEq {
231                 self.err_dotdotdot_syntax(self.token.span);
232             }
233
234             if self.token == token::LArrow {
235                 self.err_larrow_operator(self.token.span);
236             }
237
238             self.bump();
239             if op.is_comparison() {
240                 if let Some(expr) = self.check_no_chained_comparison(&lhs, &op)? {
241                     return Ok(expr);
242                 }
243             }
244             // Special cases:
245             if op == AssocOp::As {
246                 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?;
247                 continue
248             } else if op == AssocOp::Colon {
249                 let maybe_path = self.could_ascription_be_path(&lhs.kind);
250                 self.last_type_ascription = Some((self.prev_span, maybe_path));
251
252                 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
253                 self.sess.gated_spans.gate(sym::type_ascription, lhs.span);
254                 continue
255             } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
256                 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
257                 // generalise it to the Fixity::None code.
258                 //
259                 // We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
260                 // two variants are handled with `parse_prefix_range_expr` call above.
261                 let rhs = if self.is_at_start_of_range_notation_rhs() {
262                     Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?)
263                 } else {
264                     None
265                 };
266                 let (lhs_span, rhs_span) = (lhs.span, if let Some(ref x) = rhs {
267                     x.span
268                 } else {
269                     cur_op_span
270                 });
271                 let limits = if op == AssocOp::DotDot {
272                     RangeLimits::HalfOpen
273                 } else {
274                     RangeLimits::Closed
275                 };
276
277                 let r = self.mk_range(Some(lhs), rhs, limits)?;
278                 lhs = self.mk_expr(lhs_span.to(rhs_span), r, ThinVec::new());
279                 break
280             }
281
282             let fixity = op.fixity();
283             let prec_adjustment = match fixity {
284                 Fixity::Right => 0,
285                 Fixity::Left => 1,
286                 // We currently have no non-associative operators that are not handled above by
287                 // the special cases. The code is here only for future convenience.
288                 Fixity::None => 1,
289             };
290             let rhs = self.with_res(
291                 restrictions - Restrictions::STMT_EXPR,
292                 |this| this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
293             )?;
294
295             // Make sure that the span of the parent node is larger than the span of lhs and rhs,
296             // including the attributes.
297             let lhs_span = lhs
298                 .attrs
299                 .iter()
300                 .filter(|a| a.style == AttrStyle::Outer)
301                 .next()
302                 .map_or(lhs_span, |a| a.span);
303             let span = lhs_span.to(rhs.span);
304             lhs = match op {
305                 AssocOp::Add | AssocOp::Subtract | AssocOp::Multiply | AssocOp::Divide |
306                 AssocOp::Modulus | AssocOp::LAnd | AssocOp::LOr | AssocOp::BitXor |
307                 AssocOp::BitAnd | AssocOp::BitOr | AssocOp::ShiftLeft | AssocOp::ShiftRight |
308                 AssocOp::Equal | AssocOp::Less | AssocOp::LessEqual | AssocOp::NotEqual |
309                 AssocOp::Greater | AssocOp::GreaterEqual => {
310                     let ast_op = op.to_ast_binop().unwrap();
311                     let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
312                     self.mk_expr(span, binary, ThinVec::new())
313                 }
314                 AssocOp::Assign => self.mk_expr(span, ExprKind::Assign(lhs, rhs), ThinVec::new()),
315                 AssocOp::AssignOp(k) => {
316                     let aop = match k {
317                         token::Plus =>    BinOpKind::Add,
318                         token::Minus =>   BinOpKind::Sub,
319                         token::Star =>    BinOpKind::Mul,
320                         token::Slash =>   BinOpKind::Div,
321                         token::Percent => BinOpKind::Rem,
322                         token::Caret =>   BinOpKind::BitXor,
323                         token::And =>     BinOpKind::BitAnd,
324                         token::Or =>      BinOpKind::BitOr,
325                         token::Shl =>     BinOpKind::Shl,
326                         token::Shr =>     BinOpKind::Shr,
327                     };
328                     let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs);
329                     self.mk_expr(span, aopexpr, ThinVec::new())
330                 }
331                 AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
332                     self.bug("AssocOp should have been handled by special case")
333                 }
334             };
335
336             if let Fixity::None = fixity { break }
337         }
338         if last_type_ascription_set {
339             self.last_type_ascription = None;
340         }
341         Ok(lhs)
342     }
343
344     /// Checks if this expression is a successfully parsed statement.
345     fn expr_is_complete(&self, e: &Expr) -> bool {
346         self.restrictions.contains(Restrictions::STMT_EXPR) &&
347             !classify::expr_requires_semi_to_be_stmt(e)
348     }
349
350     fn is_at_start_of_range_notation_rhs(&self) -> bool {
351         if self.token.can_begin_expr() {
352             // Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
353             if self.token == token::OpenDelim(token::Brace) {
354                 return !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
355             }
356             true
357         } else {
358             false
359         }
360     }
361
362     /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
363     fn parse_prefix_range_expr(
364         &mut self,
365         already_parsed_attrs: Option<ThinVec<Attribute>>
366     ) -> PResult<'a, P<Expr>> {
367         // Check for deprecated `...` syntax.
368         if self.token == token::DotDotDot {
369             self.err_dotdotdot_syntax(self.token.span);
370         }
371
372         debug_assert!([token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind),
373                       "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
374                       self.token);
375         let tok = self.token.clone();
376         let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
377         let lo = self.token.span;
378         let mut hi = self.token.span;
379         self.bump();
380         let opt_end = if self.is_at_start_of_range_notation_rhs() {
381             // RHS must be parsed with more associativity than the dots.
382             let next_prec = AssocOp::from_token(&tok).unwrap().precedence() + 1;
383             Some(self.parse_assoc_expr_with(next_prec, LhsExpr::NotYetParsed)
384                 .map(|x| {
385                     hi = x.span;
386                     x
387                 })?)
388         } else {
389             None
390         };
391         let limits = if tok == token::DotDot {
392             RangeLimits::HalfOpen
393         } else {
394             RangeLimits::Closed
395         };
396
397         let r = self.mk_range(None, opt_end, limits)?;
398         Ok(self.mk_expr(lo.to(hi), r, attrs))
399     }
400
401     /// Parses a prefix-unary-operator expr.
402     fn parse_prefix_expr(
403         &mut self,
404         already_parsed_attrs: Option<ThinVec<Attribute>>
405     ) -> PResult<'a, P<Expr>> {
406         let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
407         let lo = self.token.span;
408         // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
409         let (hi, ex) = match self.token.kind {
410             token::Not => {
411                 self.bump();
412                 let e = self.parse_prefix_expr(None);
413                 let (span, e) = self.interpolated_or_expr_span(e)?;
414                 (lo.to(span), self.mk_unary(UnOp::Not, e))
415             }
416             // Suggest `!` for bitwise negation when encountering a `~`
417             token::Tilde => {
418                 self.bump();
419                 let e = self.parse_prefix_expr(None);
420                 let (span, e) = self.interpolated_or_expr_span(e)?;
421                 let span_of_tilde = lo;
422                 self.struct_span_err(span_of_tilde, "`~` cannot be used as a unary operator")
423                     .span_suggestion_short(
424                         span_of_tilde,
425                         "use `!` to perform bitwise not",
426                         "!".to_owned(),
427                         Applicability::MachineApplicable
428                     )
429                     .emit();
430                 (lo.to(span), self.mk_unary(UnOp::Not, e))
431             }
432             token::BinOp(token::Minus) => {
433                 self.bump();
434                 let e = self.parse_prefix_expr(None);
435                 let (span, e) = self.interpolated_or_expr_span(e)?;
436                 (lo.to(span), self.mk_unary(UnOp::Neg, e))
437             }
438             token::BinOp(token::Star) => {
439                 self.bump();
440                 let e = self.parse_prefix_expr(None);
441                 let (span, e) = self.interpolated_or_expr_span(e)?;
442                 (lo.to(span), self.mk_unary(UnOp::Deref, e))
443             }
444             token::BinOp(token::And) | token::AndAnd => {
445                 self.expect_and()?;
446                 let m = self.parse_mutability();
447                 let e = self.parse_prefix_expr(None);
448                 let (span, e) = self.interpolated_or_expr_span(e)?;
449                 (lo.to(span), ExprKind::AddrOf(m, e))
450             }
451             token::Ident(..) if self.token.is_keyword(kw::Box) => {
452                 self.bump();
453                 let e = self.parse_prefix_expr(None);
454                 let (span, e) = self.interpolated_or_expr_span(e)?;
455                 let span = lo.to(span);
456                 self.sess.gated_spans.gate(sym::box_syntax, span);
457                 (span, ExprKind::Box(e))
458             }
459             token::Ident(..) if self.token.is_ident_named(sym::not) => {
460                 // `not` is just an ordinary identifier in Rust-the-language,
461                 // but as `rustc`-the-compiler, we can issue clever diagnostics
462                 // for confused users who really want to say `!`
463                 let token_cannot_continue_expr = |t: &Token| match t.kind {
464                     // These tokens can start an expression after `!`, but
465                     // can't continue an expression after an ident
466                     token::Ident(name, is_raw) => token::ident_can_begin_expr(name, t.span, is_raw),
467                     token::Literal(..) | token::Pound => true,
468                     _ => t.is_whole_expr(),
469                 };
470                 let cannot_continue_expr = self.look_ahead(1, token_cannot_continue_expr);
471                 if cannot_continue_expr {
472                     self.bump();
473                     // Emit the error ...
474                     self.struct_span_err(
475                         self.token.span,
476                         &format!("unexpected {} after identifier",self.this_token_descr())
477                     )
478                     .span_suggestion_short(
479                         // Span the `not` plus trailing whitespace to avoid
480                         // trailing whitespace after the `!` in our suggestion
481                         self.sess.source_map()
482                             .span_until_non_whitespace(lo.to(self.token.span)),
483                         "use `!` to perform logical negation",
484                         "!".to_owned(),
485                         Applicability::MachineApplicable
486                     )
487                     .emit();
488                     // â€”and recover! (just as if we were in the block
489                     // for the `token::Not` arm)
490                     let e = self.parse_prefix_expr(None);
491                     let (span, e) = self.interpolated_or_expr_span(e)?;
492                     (lo.to(span), self.mk_unary(UnOp::Not, e))
493                 } else {
494                     return self.parse_dot_or_call_expr(Some(attrs));
495                 }
496             }
497             _ => { return self.parse_dot_or_call_expr(Some(attrs)); }
498         };
499         return Ok(self.mk_expr(lo.to(hi), ex, attrs));
500     }
501
502     /// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
503     fn interpolated_or_expr_span(
504         &self,
505         expr: PResult<'a, P<Expr>>,
506     ) -> PResult<'a, (Span, P<Expr>)> {
507         expr.map(|e| {
508             if self.prev_token_kind == PrevTokenKind::Interpolated {
509                 (self.prev_span, e)
510             } else {
511                 (e.span, e)
512             }
513         })
514     }
515
516     fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span,
517                            expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind)
518                            -> PResult<'a, P<Expr>> {
519         let mk_expr = |this: &mut Self, rhs: P<Ty>| {
520             this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs), ThinVec::new())
521         };
522
523         // Save the state of the parser before parsing type normally, in case there is a
524         // LessThan comparison after this cast.
525         let parser_snapshot_before_type = self.clone();
526         match self.parse_ty_no_plus() {
527             Ok(rhs) => {
528                 Ok(mk_expr(self, rhs))
529             }
530             Err(mut type_err) => {
531                 // Rewind to before attempting to parse the type with generics, to recover
532                 // from situations like `x as usize < y` in which we first tried to parse
533                 // `usize < y` as a type with generic arguments.
534                 let parser_snapshot_after_type = self.clone();
535                 mem::replace(self, parser_snapshot_before_type);
536
537                 match self.parse_path(PathStyle::Expr) {
538                     Ok(path) => {
539                         let (op_noun, op_verb) = match self.token.kind {
540                             token::Lt => ("comparison", "comparing"),
541                             token::BinOp(token::Shl) => ("shift", "shifting"),
542                             _ => {
543                                 // We can end up here even without `<` being the next token, for
544                                 // example because `parse_ty_no_plus` returns `Err` on keywords,
545                                 // but `parse_path` returns `Ok` on them due to error recovery.
546                                 // Return original error and parser state.
547                                 mem::replace(self, parser_snapshot_after_type);
548                                 return Err(type_err);
549                             }
550                         };
551
552                         // Successfully parsed the type path leaving a `<` yet to parse.
553                         type_err.cancel();
554
555                         // Report non-fatal diagnostics, keep `x as usize` as an expression
556                         // in AST and continue parsing.
557                         let msg = format!(
558                             "`<` is interpreted as a start of generic arguments for `{}`, not a {}",
559                             pprust::path_to_string(&path),
560                             op_noun,
561                         );
562                         let span_after_type = parser_snapshot_after_type.token.span;
563                         let expr = mk_expr(self, P(Ty {
564                             span: path.span,
565                             kind: TyKind::Path(None, path),
566                             id: DUMMY_NODE_ID,
567                         }));
568
569                         let expr_str = self.span_to_snippet(expr.span)
570                             .unwrap_or_else(|_| pprust::expr_to_string(&expr));
571
572                         self.struct_span_err(self.token.span, &msg)
573                             .span_label(
574                                 self.look_ahead(1, |t| t.span).to(span_after_type),
575                                 "interpreted as generic arguments"
576                             )
577                             .span_label(self.token.span, format!("not interpreted as {}", op_noun))
578                             .span_suggestion(
579                                 expr.span,
580                                 &format!("try {} the cast value", op_verb),
581                                 format!("({})", expr_str),
582                                 Applicability::MachineApplicable,
583                             )
584                             .emit();
585
586                         Ok(expr)
587                     }
588                     Err(mut path_err) => {
589                         // Couldn't parse as a path, return original error and parser state.
590                         path_err.cancel();
591                         mem::replace(self, parser_snapshot_after_type);
592                         Err(type_err)
593                     }
594                 }
595             }
596         }
597     }
598
599     /// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
600     fn parse_dot_or_call_expr(
601         &mut self,
602         already_parsed_attrs: Option<ThinVec<Attribute>>,
603     ) -> PResult<'a, P<Expr>> {
604         let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
605
606         let b = self.parse_bottom_expr();
607         let (span, b) = self.interpolated_or_expr_span(b)?;
608         self.parse_dot_or_call_expr_with(b, span, attrs)
609     }
610
611     pub(super) fn parse_dot_or_call_expr_with(
612         &mut self,
613         e0: P<Expr>,
614         lo: Span,
615         mut attrs: ThinVec<Attribute>,
616     ) -> PResult<'a, P<Expr>> {
617         // Stitch the list of outer attributes onto the return value.
618         // A little bit ugly, but the best way given the current code
619         // structure
620         self.parse_dot_or_call_expr_with_(e0, lo).map(|expr|
621             expr.map(|mut expr| {
622                 attrs.extend::<Vec<_>>(expr.attrs.into());
623                 expr.attrs = attrs;
624                 match expr.kind {
625                     ExprKind::If(..) if !expr.attrs.is_empty() => {
626                         // Just point to the first attribute in there...
627                         let span = expr.attrs[0].span;
628                         self.span_err(span, "attributes are not yet allowed on `if` expressions");
629                     }
630                     _ => {}
631                 }
632                 expr
633             })
634         )
635     }
636
637     fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
638         let mut e = e0;
639         let mut hi;
640         loop {
641             // expr?
642             while self.eat(&token::Question) {
643                 let hi = self.prev_span;
644                 e = self.mk_expr(lo.to(hi), ExprKind::Try(e), ThinVec::new());
645             }
646
647             // expr.f
648             if self.eat(&token::Dot) {
649                 match self.token.kind {
650                     token::Ident(..) => {
651                         e = self.parse_dot_suffix(e, lo)?;
652                     }
653                     token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
654                         let span = self.token.span;
655                         self.bump();
656                         let field = ExprKind::Field(e, Ident::new(symbol, span));
657                         e = self.mk_expr(lo.to(span), field, ThinVec::new());
658
659                         self.expect_no_suffix(span, "a tuple index", suffix);
660                     }
661                     token::Literal(token::Lit { kind: token::Float, symbol, .. }) => {
662                       self.bump();
663                       let fstr = symbol.as_str();
664                       let msg = format!("unexpected token: `{}`", symbol);
665                       let mut err = self.diagnostic().struct_span_err(self.prev_span, &msg);
666                       err.span_label(self.prev_span, "unexpected token");
667                       if fstr.chars().all(|x| "0123456789.".contains(x)) {
668                           let float = match fstr.parse::<f64>().ok() {
669                               Some(f) => f,
670                               None => continue,
671                           };
672                           let sugg = pprust::to_string(|s| {
673                               s.popen();
674                               s.print_expr(&e);
675                               s.s.word( ".");
676                               s.print_usize(float.trunc() as usize);
677                               s.pclose();
678                               s.s.word(".");
679                               s.s.word(fstr.splitn(2, ".").last().unwrap().to_string())
680                           });
681                           err.span_suggestion(
682                               lo.to(self.prev_span),
683                               "try parenthesizing the first index",
684                               sugg,
685                               Applicability::MachineApplicable
686                           );
687                       }
688                       return Err(err);
689
690                     }
691                     _ => {
692                         // FIXME Could factor this out into non_fatal_unexpected or something.
693                         let actual = self.this_token_to_string();
694                         self.span_err(self.token.span, &format!("unexpected token: `{}`", actual));
695                     }
696                 }
697                 continue;
698             }
699             if self.expr_is_complete(&e) { break; }
700             match self.token.kind {
701                 // expr(...)
702                 token::OpenDelim(token::Paren) => {
703                     let seq = self.parse_paren_expr_seq().map(|es| {
704                         let nd = self.mk_call(e, es);
705                         let hi = self.prev_span;
706                         self.mk_expr(lo.to(hi), nd, ThinVec::new())
707                     });
708                     e = self.recover_seq_parse_error(token::Paren, lo, seq);
709                 }
710
711                 // expr[...]
712                 // Could be either an index expression or a slicing expression.
713                 token::OpenDelim(token::Bracket) => {
714                     self.bump();
715                     let ix = self.parse_expr()?;
716                     hi = self.token.span;
717                     self.expect(&token::CloseDelim(token::Bracket))?;
718                     let index = self.mk_index(e, ix);
719                     e = self.mk_expr(lo.to(hi), index, ThinVec::new())
720                 }
721                 _ => return Ok(e)
722             }
723         }
724         return Ok(e);
725     }
726
727     /// Assuming we have just parsed `.`, continue parsing into an expression.
728     fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
729         if self.token.span.rust_2018() && self.eat_keyword(kw::Await) {
730             return self.mk_await_expr(self_arg, lo);
731         }
732
733         let segment = self.parse_path_segment(PathStyle::Expr)?;
734         self.check_trailing_angle_brackets(&segment, token::OpenDelim(token::Paren));
735
736         Ok(match self.token.kind {
737             token::OpenDelim(token::Paren) => {
738                 // Method call `expr.f()`
739                 let mut args = self.parse_paren_expr_seq()?;
740                 args.insert(0, self_arg);
741
742                 let span = lo.to(self.prev_span);
743                 self.mk_expr(span, ExprKind::MethodCall(segment, args), ThinVec::new())
744             }
745             _ => {
746                 // Field access `expr.f`
747                 if let Some(args) = segment.args {
748                     self.span_err(args.span(),
749                                   "field expressions may not have generic arguments");
750                 }
751
752                 let span = lo.to(self.prev_span);
753                 self.mk_expr(span, ExprKind::Field(self_arg, segment.ident), ThinVec::new())
754             }
755         })
756     }
757
758     /// At the bottom (top?) of the precedence hierarchy,
759     /// Parses things like parenthesized exprs, macros, `return`, etc.
760     ///
761     /// N.B., this does not parse outer attributes, and is private because it only works
762     /// correctly if called from `parse_dot_or_call_expr()`.
763     fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
764         maybe_recover_from_interpolated_ty_qpath!(self, true);
765         maybe_whole_expr!(self);
766
767         // Outer attributes are already parsed and will be
768         // added to the return value after the fact.
769         //
770         // Therefore, prevent sub-parser from parsing
771         // attributes by giving them a empty "already-parsed" list.
772         let mut attrs = ThinVec::new();
773
774         let lo = self.token.span;
775         let mut hi = self.token.span;
776
777         let ex: ExprKind;
778
779         macro_rules! parse_lit {
780             () => {
781                 match self.parse_lit() {
782                     Ok(literal) => {
783                         hi = self.prev_span;
784                         ex = ExprKind::Lit(literal);
785                     }
786                     Err(mut err) => {
787                         err.cancel();
788                         return Err(self.expected_expression_found());
789                     }
790                 }
791             }
792         }
793
794         // Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
795         match self.token.kind {
796             // This match arm is a special-case of the `_` match arm below and
797             // could be removed without changing functionality, but it's faster
798             // to have it here, especially for programs with large constants.
799             token::Literal(_) => {
800                 parse_lit!()
801             }
802             token::OpenDelim(token::Paren) => {
803                 self.bump();
804
805                 attrs.extend(self.parse_inner_attributes()?);
806
807                 // `(e)` is parenthesized `e`.
808                 // `(e,)` is a tuple with only one field, `e`.
809                 let mut es = vec![];
810                 let mut trailing_comma = false;
811                 let mut recovered = false;
812                 while self.token != token::CloseDelim(token::Paren) {
813                     es.push(match self.parse_expr() {
814                         Ok(es) => es,
815                         Err(mut err) => {
816                             // Recover from parse error in tuple list.
817                             match self.token.kind {
818                                 token::Ident(name, false)
819                                 if name == kw::Underscore && self.look_ahead(1, |t| {
820                                     t == &token::Comma
821                                 }) => {
822                                     // Special-case handling of `Foo<(_, _, _)>`
823                                     err.emit();
824                                     let sp = self.token.span;
825                                     self.bump();
826                                     self.mk_expr(sp, ExprKind::Err, ThinVec::new())
827                                 }
828                                 _ => return Ok(
829                                     self.recover_seq_parse_error(token::Paren, lo, Err(err)),
830                                 ),
831                             }
832                         }
833                     });
834                     recovered = self.expect_one_of(
835                         &[],
836                         &[token::Comma, token::CloseDelim(token::Paren)],
837                     )?;
838                     if self.eat(&token::Comma) {
839                         trailing_comma = true;
840                     } else {
841                         trailing_comma = false;
842                         break;
843                     }
844                 }
845                 if !recovered {
846                     self.bump();
847                 }
848
849                 hi = self.prev_span;
850                 ex = if es.len() == 1 && !trailing_comma {
851                     ExprKind::Paren(es.into_iter().nth(0).unwrap())
852                 } else {
853                     ExprKind::Tup(es)
854                 };
855             }
856             token::OpenDelim(token::Brace) => {
857                 return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs);
858             }
859             token::BinOp(token::Or) | token::OrOr => {
860                 return self.parse_closure_expr(attrs);
861             }
862             token::OpenDelim(token::Bracket) => {
863                 self.bump();
864
865                 attrs.extend(self.parse_inner_attributes()?);
866
867                 if self.eat(&token::CloseDelim(token::Bracket)) {
868                     // Empty vector
869                     ex = ExprKind::Array(Vec::new());
870                 } else {
871                     // Non-empty vector
872                     let first_expr = self.parse_expr()?;
873                     if self.eat(&token::Semi) {
874                         // Repeating array syntax: `[ 0; 512 ]`
875                         let count = AnonConst {
876                             id: DUMMY_NODE_ID,
877                             value: self.parse_expr()?,
878                         };
879                         self.expect(&token::CloseDelim(token::Bracket))?;
880                         ex = ExprKind::Repeat(first_expr, count);
881                     } else if self.eat(&token::Comma) {
882                         // Vector with two or more elements
883                         let remaining_exprs = self.parse_seq_to_end(
884                             &token::CloseDelim(token::Bracket),
885                             SeqSep::trailing_allowed(token::Comma),
886                             |p| Ok(p.parse_expr()?)
887                         )?;
888                         let mut exprs = vec![first_expr];
889                         exprs.extend(remaining_exprs);
890                         ex = ExprKind::Array(exprs);
891                     } else {
892                         // Vector with one element
893                         self.expect(&token::CloseDelim(token::Bracket))?;
894                         ex = ExprKind::Array(vec![first_expr]);
895                     }
896                 }
897                 hi = self.prev_span;
898             }
899             _ => {
900                 if self.eat_lt() {
901                     let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
902                     hi = path.span;
903                     return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
904                 }
905                 if self.token.is_path_start() {
906                     let path = self.parse_path(PathStyle::Expr)?;
907
908                     // `!`, as an operator, is prefix, so we know this isn't that.
909                     if self.eat(&token::Not) {
910                         // MACRO INVOCATION expression
911                         let (delim, tts) = self.expect_delimited_token_tree()?;
912                         hi = self.prev_span;
913                         ex = ExprKind::Mac(Mac {
914                             path,
915                             tts,
916                             delim,
917                             span: lo.to(hi),
918                             prior_type_ascription: self.last_type_ascription,
919                         });
920                     } else if self.check(&token::OpenDelim(token::Brace)) {
921                         if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
922                             return expr;
923                         } else {
924                             hi = path.span;
925                             ex = ExprKind::Path(None, path);
926                         }
927                     } else {
928                         hi = path.span;
929                         ex = ExprKind::Path(None, path);
930                     }
931
932                     let expr = self.mk_expr(lo.to(hi), ex, attrs);
933                     return self.maybe_recover_from_bad_qpath(expr, true);
934                 }
935                 if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
936                     return self.parse_closure_expr(attrs);
937                 }
938                 if self.eat_keyword(kw::If) {
939                     return self.parse_if_expr(attrs);
940                 }
941                 if self.eat_keyword(kw::For) {
942                     let lo = self.prev_span;
943                     return self.parse_for_expr(None, lo, attrs);
944                 }
945                 if self.eat_keyword(kw::While) {
946                     let lo = self.prev_span;
947                     return self.parse_while_expr(None, lo, attrs);
948                 }
949                 if let Some(label) = self.eat_label() {
950                     let lo = label.ident.span;
951                     self.expect(&token::Colon)?;
952                     if self.eat_keyword(kw::While) {
953                         return self.parse_while_expr(Some(label), lo, attrs)
954                     }
955                     if self.eat_keyword(kw::For) {
956                         return self.parse_for_expr(Some(label), lo, attrs)
957                     }
958                     if self.eat_keyword(kw::Loop) {
959                         return self.parse_loop_expr(Some(label), lo, attrs)
960                     }
961                     if self.token == token::OpenDelim(token::Brace) {
962                         return self.parse_block_expr(Some(label),
963                                                      lo,
964                                                      BlockCheckMode::Default,
965                                                      attrs);
966                     }
967                     let msg = "expected `while`, `for`, `loop` or `{` after a label";
968                     let mut err = self.fatal(msg);
969                     err.span_label(self.token.span, msg);
970                     return Err(err);
971                 }
972                 if self.eat_keyword(kw::Loop) {
973                     let lo = self.prev_span;
974                     return self.parse_loop_expr(None, lo, attrs);
975                 }
976                 if self.eat_keyword(kw::Continue) {
977                     let label = self.eat_label();
978                     let ex = ExprKind::Continue(label);
979                     let hi = self.prev_span;
980                     return Ok(self.mk_expr(lo.to(hi), ex, attrs));
981                 }
982                 if self.eat_keyword(kw::Match) {
983                     let match_sp = self.prev_span;
984                     return self.parse_match_expr(attrs).map_err(|mut err| {
985                         err.span_label(match_sp, "while parsing this match expression");
986                         err
987                     });
988                 }
989                 if self.eat_keyword(kw::Unsafe) {
990                     return self.parse_block_expr(
991                         None,
992                         lo,
993                         BlockCheckMode::Unsafe(ast::UserProvided),
994                         attrs);
995                 }
996                 if self.is_do_catch_block() {
997                     let mut db = self.fatal("found removed `do catch` syntax");
998                     db.help("following RFC #2388, the new non-placeholder syntax is `try`");
999                     return Err(db);
1000                 }
1001                 if self.is_try_block() {
1002                     let lo = self.token.span;
1003                     assert!(self.eat_keyword(kw::Try));
1004                     return self.parse_try_block(lo, attrs);
1005                 }
1006
1007                 // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly.
1008                 let is_span_rust_2018 = self.token.span.rust_2018();
1009                 if is_span_rust_2018 && self.check_keyword(kw::Async) {
1010                     return if self.is_async_block() { // Check for `async {` and `async move {`.
1011                         self.parse_async_block(attrs)
1012                     } else {
1013                         self.parse_closure_expr(attrs)
1014                     };
1015                 }
1016                 if self.eat_keyword(kw::Return) {
1017                     if self.token.can_begin_expr() {
1018                         let e = self.parse_expr()?;
1019                         hi = e.span;
1020                         ex = ExprKind::Ret(Some(e));
1021                     } else {
1022                         ex = ExprKind::Ret(None);
1023                     }
1024                 } else if self.eat_keyword(kw::Break) {
1025                     let label = self.eat_label();
1026                     let e = if self.token.can_begin_expr()
1027                                && !(self.token == token::OpenDelim(token::Brace)
1028                                     && self.restrictions.contains(
1029                                            Restrictions::NO_STRUCT_LITERAL)) {
1030                         Some(self.parse_expr()?)
1031                     } else {
1032                         None
1033                     };
1034                     ex = ExprKind::Break(label, e);
1035                     hi = self.prev_span;
1036                 } else if self.eat_keyword(kw::Yield) {
1037                     if self.token.can_begin_expr() {
1038                         let e = self.parse_expr()?;
1039                         hi = e.span;
1040                         ex = ExprKind::Yield(Some(e));
1041                     } else {
1042                         ex = ExprKind::Yield(None);
1043                     }
1044
1045                     let span = lo.to(hi);
1046                     self.sess.gated_spans.gate(sym::generators, span);
1047                 } else if self.eat_keyword(kw::Let) {
1048                     return self.parse_let_expr(attrs);
1049                 } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
1050                     let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?;
1051                     hi = await_hi;
1052                     ex = e_kind;
1053                 } else {
1054                     if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
1055                         // Don't complain about bare semicolons after unclosed braces
1056                         // recovery in order to keep the error count down. Fixing the
1057                         // delimiters will possibly also fix the bare semicolon found in
1058                         // expression context. For example, silence the following error:
1059                         //
1060                         //     error: expected expression, found `;`
1061                         //      --> file.rs:2:13
1062                         //       |
1063                         //     2 |     foo(bar(;
1064                         //       |             ^ expected expression
1065                         self.bump();
1066                         return Ok(self.mk_expr(self.token.span, ExprKind::Err, ThinVec::new()));
1067                     }
1068                     parse_lit!()
1069                 }
1070             }
1071         }
1072
1073         let expr = self.mk_expr(lo.to(hi), ex, attrs);
1074         self.maybe_recover_from_bad_qpath(expr, true)
1075     }
1076
1077     /// Matches `lit = true | false | token_lit`.
1078     pub(super) fn parse_lit(&mut self) -> PResult<'a, Lit> {
1079         let mut recovered = None;
1080         if self.token == token::Dot {
1081             // Attempt to recover `.4` as `0.4`.
1082             recovered = self.look_ahead(1, |next_token| {
1083                 if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
1084                         = next_token.kind {
1085                     if self.token.span.hi() == next_token.span.lo() {
1086                         let s = String::from("0.") + &symbol.as_str();
1087                         let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix);
1088                         return Some(Token::new(kind, self.token.span.to(next_token.span)));
1089                     }
1090                 }
1091                 None
1092             });
1093             if let Some(token) = &recovered {
1094                 self.bump();
1095                 self.struct_span_err(token.span, "float literals must have an integer part")
1096                     .span_suggestion(
1097                         token.span,
1098                         "must have an integer part",
1099                         pprust::token_to_string(token),
1100                         Applicability::MachineApplicable,
1101                     )
1102                     .emit();
1103             }
1104         }
1105
1106         let token = recovered.as_ref().unwrap_or(&self.token);
1107         match Lit::from_token(token) {
1108             Ok(lit) => {
1109                 self.bump();
1110                 Ok(lit)
1111             }
1112             Err(LitError::NotLiteral) => {
1113                 let msg = format!("unexpected token: {}", self.this_token_descr());
1114                 Err(self.span_fatal(token.span, &msg))
1115             }
1116             Err(err) => {
1117                 let span = token.span;
1118                 let lit = match token.kind {
1119                     token::Literal(lit) => lit,
1120                     _ => unreachable!(),
1121                 };
1122                 self.bump();
1123                 self.error_literal_from_token(err, lit, span);
1124                 // Pack possible quotes and prefixes from the original literal into
1125                 // the error literal's symbol so they can be pretty-printed faithfully.
1126                 let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
1127                 let symbol = Symbol::intern(&suffixless_lit.to_string());
1128                 let lit = token::Lit::new(token::Err, symbol, lit.suffix);
1129                 Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
1130             }
1131         }
1132     }
1133
1134     fn error_literal_from_token(&self, err: LitError, lit: token::Lit, span: Span) {
1135         // Checks if `s` looks like i32 or u1234 etc.
1136         fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
1137             s.len() > 1
1138             && s.starts_with(first_chars)
1139             && s[1..].chars().all(|c| c.is_ascii_digit())
1140         }
1141
1142         let token::Lit { kind, suffix, .. } = lit;
1143         match err {
1144             // `NotLiteral` is not an error by itself, so we don't report
1145             // it and give the parser opportunity to try something else.
1146             LitError::NotLiteral => {}
1147             // `LexerError` *is* an error, but it was already reported
1148             // by lexer, so here we don't report it the second time.
1149             LitError::LexerError => {}
1150             LitError::InvalidSuffix => {
1151                 self.expect_no_suffix(
1152                     span,
1153                     &format!("{} {} literal", kind.article(), kind.descr()),
1154                     suffix,
1155                 );
1156             }
1157             LitError::InvalidIntSuffix => {
1158                 let suf = suffix.expect("suffix error with no suffix").as_str();
1159                 if looks_like_width_suffix(&['i', 'u'], &suf) {
1160                     // If it looks like a width, try to be helpful.
1161                     let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
1162                     self.struct_span_err(span, &msg)
1163                         .help("valid widths are 8, 16, 32, 64 and 128")
1164                         .emit();
1165                 } else {
1166                     let msg = format!("invalid suffix `{}` for integer literal", suf);
1167                     self.struct_span_err(span, &msg)
1168                         .span_label(span, format!("invalid suffix `{}`", suf))
1169                         .help("the suffix must be one of the integral types (`u32`, `isize`, etc)")
1170                         .emit();
1171                 }
1172             }
1173             LitError::InvalidFloatSuffix => {
1174                 let suf = suffix.expect("suffix error with no suffix").as_str();
1175                 if looks_like_width_suffix(&['f'], &suf) {
1176                     // If it looks like a width, try to be helpful.
1177                     let msg = format!("invalid width `{}` for float literal", &suf[1..]);
1178                     self.struct_span_err(span, &msg)
1179                         .help("valid widths are 32 and 64")
1180                         .emit();
1181                 } else {
1182                     let msg = format!("invalid suffix `{}` for float literal", suf);
1183                     self.struct_span_err(span, &msg)
1184                         .span_label(span, format!("invalid suffix `{}`", suf))
1185                         .help("valid suffixes are `f32` and `f64`")
1186                         .emit();
1187                 }
1188             }
1189             LitError::NonDecimalFloat(base) => {
1190                 let descr = match base {
1191                     16 => "hexadecimal",
1192                     8 => "octal",
1193                     2 => "binary",
1194                     _ => unreachable!(),
1195                 };
1196                 self.struct_span_err(span, &format!("{} float literal is not supported", descr))
1197                     .span_label(span, "not supported")
1198                     .emit();
1199             }
1200             LitError::IntTooLarge => {
1201                 self.struct_span_err(span, "integer literal is too large")
1202                     .emit();
1203             }
1204         }
1205     }
1206
1207     pub(super) fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<Symbol>) {
1208         if let Some(suf) = suffix {
1209             let mut err = if kind == "a tuple index"
1210                 && [sym::i32, sym::u32, sym::isize, sym::usize].contains(&suf)
1211             {
1212                 // #59553: warn instead of reject out of hand to allow the fix to percolate
1213                 // through the ecosystem when people fix their macros
1214                 let mut err = self.sess.span_diagnostic.struct_span_warn(
1215                     sp,
1216                     &format!("suffixes on {} are invalid", kind),
1217                 );
1218                 err.note(&format!(
1219                     "`{}` is *temporarily* accepted on tuple index fields as it was \
1220                         incorrectly accepted on stable for a few releases",
1221                     suf,
1222                 ));
1223                 err.help(
1224                     "on proc macros, you'll want to use `syn::Index::from` or \
1225                         `proc_macro::Literal::*_unsuffixed` for code that will desugar \
1226                         to tuple field access",
1227                 );
1228                 err.note(
1229                     "for more context, see https://github.com/rust-lang/rust/issues/60210",
1230                 );
1231                 err
1232             } else {
1233                 self.struct_span_err(sp, &format!("suffixes on {} are invalid", kind))
1234             };
1235             err.span_label(sp, format!("invalid suffix `{}`", suf));
1236             err.emit();
1237         }
1238     }
1239
1240     /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
1241     pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
1242         maybe_whole_expr!(self);
1243
1244         let minus_lo = self.token.span;
1245         let minus_present = self.eat(&token::BinOp(token::Minus));
1246         let lo = self.token.span;
1247         let literal = self.parse_lit()?;
1248         let hi = self.prev_span;
1249         let expr = self.mk_expr(lo.to(hi), ExprKind::Lit(literal), ThinVec::new());
1250
1251         if minus_present {
1252             let minus_hi = self.prev_span;
1253             let unary = self.mk_unary(UnOp::Neg, expr);
1254             Ok(self.mk_expr(minus_lo.to(minus_hi), unary, ThinVec::new()))
1255         } else {
1256             Ok(expr)
1257         }
1258     }
1259
1260     /// Parses a block or unsafe block.
1261     pub(super) fn parse_block_expr(
1262         &mut self,
1263         opt_label: Option<Label>,
1264         lo: Span,
1265         blk_mode: BlockCheckMode,
1266         outer_attrs: ThinVec<Attribute>,
1267     ) -> PResult<'a, P<Expr>> {
1268         if let Some(label) = opt_label {
1269             self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
1270         }
1271
1272         self.expect(&token::OpenDelim(token::Brace))?;
1273
1274         let mut attrs = outer_attrs;
1275         attrs.extend(self.parse_inner_attributes()?);
1276
1277         let blk = self.parse_block_tail(lo, blk_mode)?;
1278         Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
1279     }
1280
1281     /// Parses a closure expression (e.g., `move |args| expr`).
1282     fn parse_closure_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
1283         let lo = self.token.span;
1284
1285         let movability = if self.eat_keyword(kw::Static) {
1286             Movability::Static
1287         } else {
1288             Movability::Movable
1289         };
1290
1291         let asyncness = if self.token.span.rust_2018() {
1292             self.parse_asyncness()
1293         } else {
1294             IsAsync::NotAsync
1295         };
1296         if asyncness.is_async() {
1297             // Feature-gate `async ||` closures.
1298             self.sess.gated_spans.gate(sym::async_closure, self.prev_span);
1299         }
1300
1301         let capture_clause = self.parse_capture_clause();
1302         let decl = self.parse_fn_block_decl()?;
1303         let decl_hi = self.prev_span;
1304         let body = match decl.output {
1305             FunctionRetTy::Default(_) => {
1306                 let restrictions = self.restrictions - Restrictions::STMT_EXPR;
1307                 self.parse_expr_res(restrictions, None)?
1308             },
1309             _ => {
1310                 // If an explicit return type is given, require a block to appear (RFC 968).
1311                 let body_lo = self.token.span;
1312                 self.parse_block_expr(None, body_lo, BlockCheckMode::Default, ThinVec::new())?
1313             }
1314         };
1315
1316         Ok(self.mk_expr(
1317             lo.to(body.span),
1318             ExprKind::Closure(capture_clause, asyncness, movability, decl, body, lo.to(decl_hi)),
1319             attrs))
1320     }
1321
1322     /// Parses an optional `move` prefix to a closure lke construct.
1323     fn parse_capture_clause(&mut self) -> CaptureBy {
1324         if self.eat_keyword(kw::Move) {
1325             CaptureBy::Value
1326         } else {
1327             CaptureBy::Ref
1328         }
1329     }
1330
1331     /// Parses the `|arg, arg|` header of a closure.
1332     fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
1333         let inputs_captures = {
1334             if self.eat(&token::OrOr) {
1335                 Vec::new()
1336             } else {
1337                 self.expect(&token::BinOp(token::Or))?;
1338                 let args = self.parse_seq_to_before_tokens(
1339                     &[&token::BinOp(token::Or), &token::OrOr],
1340                     SeqSep::trailing_allowed(token::Comma),
1341                     TokenExpectType::NoExpect,
1342                     |p| p.parse_fn_block_param()
1343                 )?.0;
1344                 self.expect_or()?;
1345                 args
1346             }
1347         };
1348         let output = self.parse_ret_ty(true)?;
1349
1350         Ok(P(FnDecl {
1351             inputs: inputs_captures,
1352             output,
1353         }))
1354     }
1355
1356     /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
1357     fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
1358         let lo = self.token.span;
1359         let attrs = self.parse_outer_attributes()?;
1360         let pat = self.parse_pat(PARAM_EXPECTED)?;
1361         let t = if self.eat(&token::Colon) {
1362             self.parse_ty()?
1363         } else {
1364             P(Ty {
1365                 id: DUMMY_NODE_ID,
1366                 kind: TyKind::Infer,
1367                 span: self.prev_span,
1368             })
1369         };
1370         let span = lo.to(self.token.span);
1371         Ok(Param {
1372             attrs: attrs.into(),
1373             ty: t,
1374             pat,
1375             span,
1376             id: DUMMY_NODE_ID,
1377             is_placeholder: false,
1378         })
1379     }
1380
1381     /// Parses an `if` expression (`if` token already eaten).
1382     fn parse_if_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
1383         let lo = self.prev_span;
1384         let cond = self.parse_cond_expr()?;
1385
1386         // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
1387         // verify that the last statement is either an implicit return (no `;`) or an explicit
1388         // return. This won't catch blocks with an explicit `return`, but that would be caught by
1389         // the dead code lint.
1390         if self.eat_keyword(kw::Else) || !cond.returns() {
1391             let sp = self.sess.source_map().next_point(lo);
1392             let mut err = self.diagnostic()
1393                 .struct_span_err(sp, "missing condition for `if` expression");
1394             err.span_label(sp, "expected if condition here");
1395             return Err(err)
1396         }
1397         let not_block = self.token != token::OpenDelim(token::Brace);
1398         let thn = self.parse_block().map_err(|mut err| {
1399             if not_block {
1400                 err.span_label(lo, "this `if` statement has a condition, but no block");
1401             }
1402             err
1403         })?;
1404         let mut els: Option<P<Expr>> = None;
1405         let mut hi = thn.span;
1406         if self.eat_keyword(kw::Else) {
1407             let elexpr = self.parse_else_expr()?;
1408             hi = elexpr.span;
1409             els = Some(elexpr);
1410         }
1411         Ok(self.mk_expr(lo.to(hi), ExprKind::If(cond, thn, els), attrs))
1412     }
1413
1414     /// Parses the condition of a `if` or `while` expression.
1415     fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
1416         let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
1417
1418         if let ExprKind::Let(..) = cond.kind {
1419             // Remove the last feature gating of a `let` expression since it's stable.
1420             self.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
1421         }
1422
1423         Ok(cond)
1424     }
1425
1426     /// Parses a `let $pat = $expr` pseudo-expression.
1427     /// The `let` token has already been eaten.
1428     fn parse_let_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
1429         let lo = self.prev_span;
1430         let pat = self.parse_top_pat(GateOr::No)?;
1431         self.expect(&token::Eq)?;
1432         let expr = self.with_res(
1433             Restrictions::NO_STRUCT_LITERAL,
1434             |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
1435         )?;
1436         let span = lo.to(expr.span);
1437         self.sess.gated_spans.gate(sym::let_chains, span);
1438         Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs))
1439     }
1440
1441     /// Parses an `else { ... }` expression (`else` token already eaten).
1442     fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
1443         if self.eat_keyword(kw::If) {
1444             return self.parse_if_expr(ThinVec::new());
1445         } else {
1446             let blk = self.parse_block()?;
1447             return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), ThinVec::new()));
1448         }
1449     }
1450
1451     /// Parses a `for ... in` expression (`for` token already eaten).
1452     fn parse_for_expr(
1453         &mut self,
1454         opt_label: Option<Label>,
1455         span_lo: Span,
1456         mut attrs: ThinVec<Attribute>
1457     ) -> PResult<'a, P<Expr>> {
1458         // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
1459
1460         // Record whether we are about to parse `for (`.
1461         // This is used below for recovery in case of `for ( $stuff ) $block`
1462         // in which case we will suggest `for $stuff $block`.
1463         let begin_paren = match self.token.kind {
1464             token::OpenDelim(token::Paren) => Some(self.token.span),
1465             _ => None,
1466         };
1467
1468         let pat = self.parse_top_pat(GateOr::Yes)?;
1469         if !self.eat_keyword(kw::In) {
1470             let in_span = self.prev_span.between(self.token.span);
1471             self.struct_span_err(in_span, "missing `in` in `for` loop")
1472                 .span_suggestion_short(
1473                     in_span,
1474                     "try adding `in` here", " in ".into(),
1475                     // has been misleading, at least in the past (closed Issue #48492)
1476                     Applicability::MaybeIncorrect
1477                 )
1478                 .emit();
1479         }
1480         let in_span = self.prev_span;
1481         self.check_for_for_in_in_typo(in_span);
1482         let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
1483
1484         let pat = self.recover_parens_around_for_head(pat, &expr, begin_paren);
1485
1486         let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
1487         attrs.extend(iattrs);
1488
1489         let hi = self.prev_span;
1490         Ok(self.mk_expr(span_lo.to(hi), ExprKind::ForLoop(pat, expr, loop_block, opt_label), attrs))
1491     }
1492
1493     /// Parses a `while` or `while let` expression (`while` token already eaten).
1494     fn parse_while_expr(
1495         &mut self,
1496         opt_label: Option<Label>,
1497         span_lo: Span,
1498         mut attrs: ThinVec<Attribute>
1499     ) -> PResult<'a, P<Expr>> {
1500         let cond = self.parse_cond_expr()?;
1501         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
1502         attrs.extend(iattrs);
1503         let span = span_lo.to(body.span);
1504         Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs))
1505     }
1506
1507     /// Parses `loop { ... }` (`loop` token already eaten).
1508     fn parse_loop_expr(
1509         &mut self,
1510         opt_label: Option<Label>,
1511         span_lo: Span,
1512         mut attrs: ThinVec<Attribute>
1513     ) -> PResult<'a, P<Expr>> {
1514         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
1515         attrs.extend(iattrs);
1516         let span = span_lo.to(body.span);
1517         Ok(self.mk_expr(span, ExprKind::Loop(body, opt_label), attrs))
1518     }
1519
1520     fn eat_label(&mut self) -> Option<Label> {
1521         if let Some(ident) = self.token.lifetime() {
1522             let span = self.token.span;
1523             self.bump();
1524             Some(Label { ident: Ident::new(ident.name, span) })
1525         } else {
1526             None
1527         }
1528     }
1529
1530     /// Parses a `match ... { ... }` expression (`match` token already eaten).
1531     fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
1532         let match_span = self.prev_span;
1533         let lo = self.prev_span;
1534         let discriminant = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
1535         if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) {
1536             if self.token == token::Semi {
1537                 e.span_suggestion_short(
1538                     match_span,
1539                     "try removing this `match`",
1540                     String::new(),
1541                     Applicability::MaybeIncorrect // speculative
1542                 );
1543             }
1544             return Err(e)
1545         }
1546         attrs.extend(self.parse_inner_attributes()?);
1547
1548         let mut arms: Vec<Arm> = Vec::new();
1549         while self.token != token::CloseDelim(token::Brace) {
1550             match self.parse_arm() {
1551                 Ok(arm) => arms.push(arm),
1552                 Err(mut e) => {
1553                     // Recover by skipping to the end of the block.
1554                     e.emit();
1555                     self.recover_stmt();
1556                     let span = lo.to(self.token.span);
1557                     if self.token == token::CloseDelim(token::Brace) {
1558                         self.bump();
1559                     }
1560                     return Ok(self.mk_expr(span, ExprKind::Match(discriminant, arms), attrs));
1561                 }
1562             }
1563         }
1564         let hi = self.token.span;
1565         self.bump();
1566         return Ok(self.mk_expr(lo.to(hi), ExprKind::Match(discriminant, arms), attrs));
1567     }
1568
1569     pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
1570         let attrs = self.parse_outer_attributes()?;
1571         let lo = self.token.span;
1572         let pat = self.parse_top_pat(GateOr::No)?;
1573         let guard = if self.eat_keyword(kw::If) {
1574             Some(self.parse_expr()?)
1575         } else {
1576             None
1577         };
1578         let arrow_span = self.token.span;
1579         self.expect(&token::FatArrow)?;
1580         let arm_start_span = self.token.span;
1581
1582         let expr = self.parse_expr_res(Restrictions::STMT_EXPR, None)
1583             .map_err(|mut err| {
1584                 err.span_label(arrow_span, "while parsing the `match` arm starting here");
1585                 err
1586             })?;
1587
1588         let require_comma = classify::expr_requires_semi_to_be_stmt(&expr)
1589             && self.token != token::CloseDelim(token::Brace);
1590
1591         let hi = self.token.span;
1592
1593         if require_comma {
1594             let cm = self.sess.source_map();
1595             self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])
1596                 .map_err(|mut err| {
1597                     match (cm.span_to_lines(expr.span), cm.span_to_lines(arm_start_span)) {
1598                         (Ok(ref expr_lines), Ok(ref arm_start_lines))
1599                         if arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col
1600                             && expr_lines.lines.len() == 2
1601                             && self.token == token::FatArrow => {
1602                             // We check whether there's any trailing code in the parse span,
1603                             // if there isn't, we very likely have the following:
1604                             //
1605                             // X |     &Y => "y"
1606                             //   |        --    - missing comma
1607                             //   |        |
1608                             //   |        arrow_span
1609                             // X |     &X => "x"
1610                             //   |      - ^^ self.token.span
1611                             //   |      |
1612                             //   |      parsed until here as `"y" & X`
1613                             err.span_suggestion_short(
1614                                 cm.next_point(arm_start_span),
1615                                 "missing a comma here to end this `match` arm",
1616                                 ",".to_owned(),
1617                                 Applicability::MachineApplicable
1618                             );
1619                         }
1620                         _ => {
1621                             err.span_label(arrow_span,
1622                                            "while parsing the `match` arm starting here");
1623                         }
1624                     }
1625                     err
1626                 })?;
1627         } else {
1628             self.eat(&token::Comma);
1629         }
1630
1631         Ok(ast::Arm {
1632             attrs,
1633             pat,
1634             guard,
1635             body: expr,
1636             span: lo.to(hi),
1637             id: DUMMY_NODE_ID,
1638             is_placeholder: false,
1639         })
1640     }
1641
1642     /// Parses a `try {...}` expression (`try` token already eaten).
1643     fn parse_try_block(
1644         &mut self,
1645         span_lo: Span,
1646         mut attrs: ThinVec<Attribute>
1647     ) -> PResult<'a, P<Expr>> {
1648         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
1649         attrs.extend(iattrs);
1650         if self.eat_keyword(kw::Catch) {
1651             let mut error = self.struct_span_err(self.prev_span,
1652                                                  "keyword `catch` cannot follow a `try` block");
1653             error.help("try using `match` on the result of the `try` block instead");
1654             error.emit();
1655             Err(error)
1656         } else {
1657             let span = span_lo.to(body.span);
1658             self.sess.gated_spans.gate(sym::try_blocks, span);
1659             Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
1660         }
1661     }
1662
1663     fn is_do_catch_block(&self) -> bool {
1664         self.token.is_keyword(kw::Do) &&
1665         self.is_keyword_ahead(1, &[kw::Catch]) &&
1666         self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) &&
1667         !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
1668     }
1669
1670     fn is_try_block(&self) -> bool {
1671         self.token.is_keyword(kw::Try) &&
1672         self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
1673         self.token.span.rust_2018() &&
1674         // Prevent `while try {} {}`, `if try {} {} else {}`, etc.
1675         !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
1676     }
1677
1678     /// Parses an `async move? {...}` expression.
1679     fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
1680         let span_lo = self.token.span;
1681         self.expect_keyword(kw::Async)?;
1682         let capture_clause = self.parse_capture_clause();
1683         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
1684         attrs.extend(iattrs);
1685         Ok(self.mk_expr(
1686             span_lo.to(body.span),
1687             ExprKind::Async(capture_clause, DUMMY_NODE_ID, body), attrs))
1688     }
1689
1690     fn is_async_block(&self) -> bool {
1691         self.token.is_keyword(kw::Async) &&
1692         (
1693             ( // `async move {`
1694                 self.is_keyword_ahead(1, &[kw::Move]) &&
1695                 self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))
1696             ) || ( // `async {`
1697                 self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
1698             )
1699         )
1700     }
1701
1702     fn maybe_parse_struct_expr(
1703         &mut self,
1704         lo: Span,
1705         path: &ast::Path,
1706         attrs: &ThinVec<Attribute>,
1707     ) -> Option<PResult<'a, P<Expr>>> {
1708         let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
1709         let certainly_not_a_block = || self.look_ahead(1, |t| t.is_ident()) && (
1710             // `{ ident, ` cannot start a block.
1711             self.look_ahead(2, |t| t == &token::Comma) ||
1712             self.look_ahead(2, |t| t == &token::Colon) && (
1713                 // `{ ident: token, ` cannot start a block.
1714                 self.look_ahead(4, |t| t == &token::Comma) ||
1715                 // `{ ident: ` cannot start a block unless it's a type ascription `ident: Type`.
1716                 self.look_ahead(3, |t| !t.can_begin_type())
1717             )
1718         );
1719
1720         if struct_allowed || certainly_not_a_block() {
1721             // This is a struct literal, but we don't can't accept them here.
1722             let expr = self.parse_struct_expr(lo, path.clone(), attrs.clone());
1723             if let (Ok(expr), false) = (&expr, struct_allowed) {
1724                 self.struct_span_err(
1725                     expr.span,
1726                     "struct literals are not allowed here",
1727                 )
1728                 .multipart_suggestion(
1729                     "surround the struct literal with parentheses",
1730                     vec![
1731                         (lo.shrink_to_lo(), "(".to_string()),
1732                         (expr.span.shrink_to_hi(), ")".to_string()),
1733                     ],
1734                     Applicability::MachineApplicable,
1735                 )
1736                 .emit();
1737             }
1738             return Some(expr);
1739         }
1740         None
1741     }
1742
1743     pub(super) fn parse_struct_expr(
1744         &mut self,
1745         lo: Span,
1746         pth: ast::Path,
1747         mut attrs: ThinVec<Attribute>
1748     ) -> PResult<'a, P<Expr>> {
1749         let struct_sp = lo.to(self.prev_span);
1750         self.bump();
1751         let mut fields = Vec::new();
1752         let mut base = None;
1753
1754         attrs.extend(self.parse_inner_attributes()?);
1755
1756         while self.token != token::CloseDelim(token::Brace) {
1757             if self.eat(&token::DotDot) {
1758                 let exp_span = self.prev_span;
1759                 match self.parse_expr() {
1760                     Ok(e) => {
1761                         base = Some(e);
1762                     }
1763                     Err(mut e) => {
1764                         e.emit();
1765                         self.recover_stmt();
1766                     }
1767                 }
1768                 if self.token == token::Comma {
1769                     self.struct_span_err(
1770                         exp_span.to(self.prev_span),
1771                         "cannot use a comma after the base struct",
1772                     )
1773                     .span_suggestion_short(
1774                         self.token.span,
1775                         "remove this comma",
1776                         String::new(),
1777                         Applicability::MachineApplicable
1778                     )
1779                     .note("the base struct must always be the last field")
1780                     .emit();
1781                     self.recover_stmt();
1782                 }
1783                 break;
1784             }
1785
1786             let mut recovery_field = None;
1787             if let token::Ident(name, _) = self.token.kind {
1788                 if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) {
1789                     // Use in case of error after field-looking code: `S { foo: () with a }`.
1790                     recovery_field = Some(ast::Field {
1791                         ident: Ident::new(name, self.token.span),
1792                         span: self.token.span,
1793                         expr: self.mk_expr(self.token.span, ExprKind::Err, ThinVec::new()),
1794                         is_shorthand: false,
1795                         attrs: ThinVec::new(),
1796                         id: DUMMY_NODE_ID,
1797                         is_placeholder: false,
1798                     });
1799                 }
1800             }
1801             let mut parsed_field = None;
1802             match self.parse_field() {
1803                 Ok(f) => parsed_field = Some(f),
1804                 Err(mut e) => {
1805                     e.span_label(struct_sp, "while parsing this struct");
1806                     e.emit();
1807
1808                     // If the next token is a comma, then try to parse
1809                     // what comes next as additional fields, rather than
1810                     // bailing out until next `}`.
1811                     if self.token != token::Comma {
1812                         self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
1813                         if self.token != token::Comma {
1814                             break;
1815                         }
1816                     }
1817                 }
1818             }
1819
1820             match self.expect_one_of(&[token::Comma],
1821                                      &[token::CloseDelim(token::Brace)]) {
1822                 Ok(_) => if let Some(f) = parsed_field.or(recovery_field) {
1823                     // Only include the field if there's no parse error for the field name.
1824                     fields.push(f);
1825                 }
1826                 Err(mut e) => {
1827                     if let Some(f) = recovery_field {
1828                         fields.push(f);
1829                     }
1830                     e.span_label(struct_sp, "while parsing this struct");
1831                     e.emit();
1832                     self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
1833                     self.eat(&token::Comma);
1834                 }
1835             }
1836         }
1837
1838         let span = lo.to(self.token.span);
1839         self.expect(&token::CloseDelim(token::Brace))?;
1840         return Ok(self.mk_expr(span, ExprKind::Struct(pth, fields, base), attrs));
1841     }
1842
1843     /// Parses `ident (COLON expr)?`.
1844     fn parse_field(&mut self) -> PResult<'a, Field> {
1845         let attrs = self.parse_outer_attributes()?;
1846         let lo = self.token.span;
1847
1848         // Check if a colon exists one ahead. This means we're parsing a fieldname.
1849         let (fieldname, expr, is_shorthand) = if self.look_ahead(1, |t| {
1850             t == &token::Colon || t == &token::Eq
1851         }) {
1852             let fieldname = self.parse_field_name()?;
1853
1854             // Check for an equals token. This means the source incorrectly attempts to
1855             // initialize a field with an eq rather than a colon.
1856             if self.token == token::Eq {
1857                 self.diagnostic()
1858                     .struct_span_err(self.token.span, "expected `:`, found `=`")
1859                     .span_suggestion(
1860                         fieldname.span.shrink_to_hi().to(self.token.span),
1861                         "replace equals symbol with a colon",
1862                         ":".to_string(),
1863                         Applicability::MachineApplicable,
1864                     )
1865                     .emit();
1866             }
1867             self.bump(); // `:`
1868             (fieldname, self.parse_expr()?, false)
1869         } else {
1870             let fieldname = self.parse_ident_common(false)?;
1871
1872             // Mimic `x: x` for the `x` field shorthand.
1873             let path = ast::Path::from_ident(fieldname);
1874             let expr = self.mk_expr(fieldname.span, ExprKind::Path(None, path), ThinVec::new());
1875             (fieldname, expr, true)
1876         };
1877         Ok(ast::Field {
1878             ident: fieldname,
1879             span: lo.to(expr.span),
1880             expr,
1881             is_shorthand,
1882             attrs: attrs.into(),
1883             id: DUMMY_NODE_ID,
1884             is_placeholder: false,
1885         })
1886     }
1887
1888     fn err_dotdotdot_syntax(&self, span: Span) {
1889         self.struct_span_err(span, "unexpected token: `...`")
1890             .span_suggestion(
1891                 span,
1892                 "use `..` for an exclusive range", "..".to_owned(),
1893                 Applicability::MaybeIncorrect
1894             )
1895             .span_suggestion(
1896                 span,
1897                 "or `..=` for an inclusive range", "..=".to_owned(),
1898                 Applicability::MaybeIncorrect
1899             )
1900             .emit();
1901     }
1902
1903     fn err_larrow_operator(&self, span: Span) {
1904         self.struct_span_err(
1905             span,
1906             "unexpected token: `<-`"
1907         ).span_suggestion(
1908             span,
1909             "if you meant to write a comparison against a negative value, add a \
1910              space in between `<` and `-`",
1911             "< -".to_string(),
1912             Applicability::MaybeIncorrect
1913         ).emit();
1914     }
1915
1916     fn mk_assign_op(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
1917         ExprKind::AssignOp(binop, lhs, rhs)
1918     }
1919
1920     fn mk_range(
1921         &self,
1922         start: Option<P<Expr>>,
1923         end: Option<P<Expr>>,
1924         limits: RangeLimits
1925     ) -> PResult<'a, ExprKind> {
1926         if end.is_none() && limits == RangeLimits::Closed {
1927             Err(self.span_fatal_err(self.token.span, Error::InclusiveRangeWithNoEnd))
1928         } else {
1929             Ok(ExprKind::Range(start, end, limits))
1930         }
1931     }
1932
1933     fn mk_unary(&self, unop: UnOp, expr: P<Expr>) -> ExprKind {
1934         ExprKind::Unary(unop, expr)
1935     }
1936
1937     fn mk_binary(&self, binop: BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ExprKind {
1938         ExprKind::Binary(binop, lhs, rhs)
1939     }
1940
1941     fn mk_index(&self, expr: P<Expr>, idx: P<Expr>) -> ExprKind {
1942         ExprKind::Index(expr, idx)
1943     }
1944
1945     fn mk_call(&self, f: P<Expr>, args: Vec<P<Expr>>) -> ExprKind {
1946         ExprKind::Call(f, args)
1947     }
1948
1949     fn mk_await_expr(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
1950         let span = lo.to(self.prev_span);
1951         let await_expr = self.mk_expr(span, ExprKind::Await(self_arg), ThinVec::new());
1952         self.recover_from_await_method_call();
1953         Ok(await_expr)
1954     }
1955
1956     crate fn mk_expr(&self, span: Span, kind: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
1957         P(Expr { kind, span, attrs, id: DUMMY_NODE_ID })
1958     }
1959
1960     pub(super) fn mk_expr_err(&self, span: Span) -> P<Expr> {
1961         self.mk_expr(span, ExprKind::Err, ThinVec::new())
1962     }
1963 }