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
;
7 use rustc_data_structures
::thin_vec
::ThinVec
;
8 use rustc_errors
::{PResult, Applicability}
;
9 use syntax
::ast
::{self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode}
;
10 use syntax
::ast
::{Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind}
;
11 use syntax
::ast
::{FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field, Lit}
;
12 use syntax
::token
::{self, Token, TokenKind}
;
13 use syntax
::print
::pprust
;
15 use syntax
::util
::classify
;
16 use syntax
::util
::literal
::LitError
;
17 use syntax
::util
::parser
::{AssocOp, Fixity, prec_let_scrutinee_needs_par}
;
18 use syntax_pos
::source_map
::{self, Span}
;
19 use syntax_pos
::symbol
::{kw, sym, Symbol}
;
22 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
23 /// dropped into the token stream, which happens while parsing the result of
24 /// macro expansion). Placement of these is not as complex as I feared it would
25 /// be. The important thing is to make sure that lookahead doesn't balk at
26 /// `token::Interpolated` tokens.
27 macro_rules
! maybe_whole_expr
{
29 if let token
::Interpolated(nt
) = &$p
.token
.kind
{
31 token
::NtExpr(e
) | token
::NtLiteral(e
) => {
36 token
::NtPath(path
) => {
37 let path
= path
.clone();
40 $p
.token
.span
, ExprKind
::Path(None
, path
), ThinVec
::new()
43 token
::NtBlock(block
) => {
44 let block
= block
.clone();
47 $p
.token
.span
, ExprKind
::Block(block
, None
), ThinVec
::new()
50 // N.B., `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
58 pub(super) enum LhsExpr
{
60 AttributesParsed(ThinVec
<Attribute
>),
61 AlreadyParsed(P
<Expr
>),
64 impl From
<Option
<ThinVec
<Attribute
>>> for LhsExpr
{
65 /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)`
66 /// and `None` into `LhsExpr::NotYetParsed`.
68 /// This conversion does not allocate.
69 fn from(o
: Option
<ThinVec
<Attribute
>>) -> Self {
70 if let Some(attrs
) = o
{
71 LhsExpr
::AttributesParsed(attrs
)
78 impl From
<P
<Expr
>> for LhsExpr
{
79 /// Converts the `expr: P<Expr>` into `LhsExpr::AlreadyParsed(expr)`.
81 /// This conversion does not allocate.
82 fn from(expr
: P
<Expr
>) -> Self {
83 LhsExpr
::AlreadyParsed(expr
)
88 /// Parses an expression.
90 pub fn parse_expr(&mut self) -> PResult
<'a
, P
<Expr
>> {
91 self.parse_expr_res(Restrictions
::empty(), None
)
94 fn parse_paren_expr_seq(&mut self) -> PResult
<'a
, Vec
<P
<Expr
>>> {
95 self.parse_paren_comma_seq(|p
| {
96 match p
.parse_expr() {
98 Err(mut err
) => match p
.token
.kind
{
99 token
::Ident(name
, false)
100 if name
== kw
::Underscore
&& p
.look_ahead(1, |t
| {
103 // Special-case handling of `foo(_, _, _)`
105 let sp
= p
.token
.span
;
107 Ok(p
.mk_expr(sp
, ExprKind
::Err
, ThinVec
::new()))
115 /// Parses an expression, subject to the given restrictions.
117 pub(super) fn parse_expr_res(
120 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>
121 ) -> PResult
<'a
, P
<Expr
>> {
122 self.with_res(r
, |this
| this
.parse_assoc_expr(already_parsed_attrs
))
125 /// Parses an associative expression.
127 /// This parses an expression accounting for associativity and precedence of the operators in
132 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>,
133 ) -> PResult
<'a
, P
<Expr
>> {
134 self.parse_assoc_expr_with(0, already_parsed_attrs
.into())
137 /// Parses an associative expression with operators of at least `min_prec` precedence.
138 pub(super) fn parse_assoc_expr_with(
142 ) -> PResult
<'a
, P
<Expr
>> {
143 let mut lhs
= if let LhsExpr
::AlreadyParsed(expr
) = lhs
{
146 let attrs
= match lhs
{
147 LhsExpr
::AttributesParsed(attrs
) => Some(attrs
),
150 if [token
::DotDot
, token
::DotDotDot
, token
::DotDotEq
].contains(&self.token
.kind
) {
151 return self.parse_prefix_range_expr(attrs
);
153 self.parse_prefix_expr(attrs
)?
156 let last_type_ascription_set
= self.last_type_ascription
.is_some();
158 match (self.expr_is_complete(&lhs
), AssocOp
::from_token(&self.token
)) {
160 self.last_type_ascription
= None
;
161 // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
164 (false, _
) => {}
// continue parsing the expression
165 // An exhaustive check is done in the following block, but these are checked first
166 // because they *are* ambiguous but also reasonable looking incorrect syntax, so we
167 // want to keep their span info to improve diagnostics in these cases in a later stage.
168 (true, Some(AssocOp
::Multiply
)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
169 (true, Some(AssocOp
::Subtract
)) | // `{ 42 } -5`
170 (true, Some(AssocOp
::LAnd
)) | // `{ 42 } &&x` (#61475)
171 (true, Some(AssocOp
::Add
)) // `{ 42 } + 42
172 // If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
173 // `if x { a } else { b } && if y { c } else { d }`
174 if !self.look_ahead(1, |t
| t
.is_reserved_ident()) => {
175 self.last_type_ascription
= None
;
176 // These cases are ambiguous and can't be identified in the parser alone
177 let sp
= self.sess
.source_map().start_point(self.token
.span
);
178 self.sess
.ambiguous_block_expr_parse
.borrow_mut().insert(sp
, lhs
.span
);
181 (true, Some(ref op
)) if !op
.can_continue_expr_unambiguously() => {
182 self.last_type_ascription
= None
;
186 // We've found an expression that would be parsed as a statement, but the next
187 // token implies this should be parsed as an expression.
188 // For example: `if let Some(x) = x { x } else { 0 } / 2`
189 let mut err
= self.struct_span_err(self.token
.span
, &format
!(
190 "expected expression, found `{}`",
191 pprust
::token_to_string(&self.token
),
193 err
.span_label(self.token
.span
, "expected expression");
194 self.sess
.expr_parentheses_needed(
197 Some(pprust
::expr_to_string(&lhs
),
202 self.expected_tokens
.push(TokenType
::Operator
);
203 while let Some(op
) = AssocOp
::from_token(&self.token
) {
205 // Adjust the span for interpolated LHS to point to the `$lhs` token and not to what
206 // it refers to. Interpolated identifiers are unwrapped early and never show up here
207 // as `PrevTokenKind::Interpolated` so if LHS is a single identifier we always process
208 // it as "interpolated", it doesn't change the answer for non-interpolated idents.
209 let lhs_span
= match (self.prev_token_kind
, &lhs
.kind
) {
210 (PrevTokenKind
::Interpolated
, _
) => self.prev_span
,
211 (PrevTokenKind
::Ident
, &ExprKind
::Path(None
, ref path
))
212 if path
.segments
.len() == 1 => self.prev_span
,
216 let cur_op_span
= self.token
.span
;
217 let restrictions
= if op
.is_assign_like() {
218 self.restrictions
& Restrictions
::NO_STRUCT_LITERAL
222 let prec
= op
.precedence();
226 // Check for deprecated `...` syntax
227 if self.token
== token
::DotDotDot
&& op
== AssocOp
::DotDotEq
{
228 self.err_dotdotdot_syntax(self.token
.span
);
231 if self.token
== token
::LArrow
{
232 self.err_larrow_operator(self.token
.span
);
236 if op
.is_comparison() {
237 if let Some(expr
) = self.check_no_chained_comparison(&lhs
, &op
)?
{
242 if op
== AssocOp
::As
{
243 lhs
= self.parse_assoc_op_cast(lhs
, lhs_span
, ExprKind
::Cast
)?
;
245 } else if op
== AssocOp
::Colon
{
246 let maybe_path
= self.could_ascription_be_path(&lhs
.kind
);
247 self.last_type_ascription
= Some((self.prev_span
, maybe_path
));
249 lhs
= self.parse_assoc_op_cast(lhs
, lhs_span
, ExprKind
::Type
)?
;
250 self.sess
.gated_spans
.gate(sym
::type_ascription
, lhs
.span
);
252 } else if op
== AssocOp
::DotDot
|| op
== AssocOp
::DotDotEq
{
253 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
254 // generalise it to the Fixity::None code.
256 // We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
257 // two variants are handled with `parse_prefix_range_expr` call above.
258 let rhs
= if self.is_at_start_of_range_notation_rhs() {
259 Some(self.parse_assoc_expr_with(prec
+ 1, LhsExpr
::NotYetParsed
)?
)
263 let (lhs_span
, rhs_span
) = (lhs
.span
, if let Some(ref x
) = rhs
{
268 let limits
= if op
== AssocOp
::DotDot
{
269 RangeLimits
::HalfOpen
274 let r
= self.mk_range(Some(lhs
), rhs
, limits
)?
;
275 lhs
= self.mk_expr(lhs_span
.to(rhs_span
), r
, ThinVec
::new());
279 let fixity
= op
.fixity();
280 let prec_adjustment
= match fixity
{
283 // We currently have no non-associative operators that are not handled above by
284 // the special cases. The code is here only for future convenience.
287 let rhs
= self.with_res(
288 restrictions
- Restrictions
::STMT_EXPR
,
289 |this
| this
.parse_assoc_expr_with(prec
+ prec_adjustment
, LhsExpr
::NotYetParsed
)
292 // Make sure that the span of the parent node is larger than the span of lhs and rhs,
293 // including the attributes.
297 .filter(|a
| a
.style
== AttrStyle
::Outer
)
299 .map_or(lhs_span
, |a
| a
.span
);
300 let span
= lhs_span
.to(rhs
.span
);
302 AssocOp
::Add
| AssocOp
::Subtract
| AssocOp
::Multiply
| AssocOp
::Divide
|
303 AssocOp
::Modulus
| AssocOp
::LAnd
| AssocOp
::LOr
| AssocOp
::BitXor
|
304 AssocOp
::BitAnd
| AssocOp
::BitOr
| AssocOp
::ShiftLeft
| AssocOp
::ShiftRight
|
305 AssocOp
::Equal
| AssocOp
::Less
| AssocOp
::LessEqual
| AssocOp
::NotEqual
|
306 AssocOp
::Greater
| AssocOp
::GreaterEqual
=> {
307 let ast_op
= op
.to_ast_binop().unwrap();
308 let binary
= self.mk_binary(source_map
::respan(cur_op_span
, ast_op
), lhs
, rhs
);
309 self.mk_expr(span
, binary
, ThinVec
::new())
311 AssocOp
::Assign
=> self.mk_expr(span
, ExprKind
::Assign(lhs
, rhs
), ThinVec
::new()),
312 AssocOp
::AssignOp(k
) => {
314 token
::Plus
=> BinOpKind
::Add
,
315 token
::Minus
=> BinOpKind
::Sub
,
316 token
::Star
=> BinOpKind
::Mul
,
317 token
::Slash
=> BinOpKind
::Div
,
318 token
::Percent
=> BinOpKind
::Rem
,
319 token
::Caret
=> BinOpKind
::BitXor
,
320 token
::And
=> BinOpKind
::BitAnd
,
321 token
::Or
=> BinOpKind
::BitOr
,
322 token
::Shl
=> BinOpKind
::Shl
,
323 token
::Shr
=> BinOpKind
::Shr
,
325 let aopexpr
= self.mk_assign_op(source_map
::respan(cur_op_span
, aop
), lhs
, rhs
);
326 self.mk_expr(span
, aopexpr
, ThinVec
::new())
328 AssocOp
::As
| AssocOp
::Colon
| AssocOp
::DotDot
| AssocOp
::DotDotEq
=> {
329 self.bug("AssocOp should have been handled by special case")
333 if let Fixity
::None
= fixity { break }
335 if last_type_ascription_set
{
336 self.last_type_ascription
= None
;
341 /// Checks if this expression is a successfully parsed statement.
342 fn expr_is_complete(&self, e
: &Expr
) -> bool
{
343 self.restrictions
.contains(Restrictions
::STMT_EXPR
) &&
344 !classify
::expr_requires_semi_to_be_stmt(e
)
347 fn is_at_start_of_range_notation_rhs(&self) -> bool
{
348 if self.token
.can_begin_expr() {
349 // Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
350 if self.token
== token
::OpenDelim(token
::Brace
) {
351 return !self.restrictions
.contains(Restrictions
::NO_STRUCT_LITERAL
);
359 /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
360 fn parse_prefix_range_expr(
362 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>
363 ) -> PResult
<'a
, P
<Expr
>> {
364 // Check for deprecated `...` syntax.
365 if self.token
== token
::DotDotDot
{
366 self.err_dotdotdot_syntax(self.token
.span
);
369 debug_assert
!([token
::DotDot
, token
::DotDotDot
, token
::DotDotEq
].contains(&self.token
.kind
),
370 "parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
372 let tok
= self.token
.clone();
373 let attrs
= self.parse_or_use_outer_attributes(already_parsed_attrs
)?
;
374 let lo
= self.token
.span
;
375 let mut hi
= self.token
.span
;
377 let opt_end
= if self.is_at_start_of_range_notation_rhs() {
378 // RHS must be parsed with more associativity than the dots.
379 let next_prec
= AssocOp
::from_token(&tok
).unwrap().precedence() + 1;
380 Some(self.parse_assoc_expr_with(next_prec
, LhsExpr
::NotYetParsed
)
388 let limits
= if tok
== token
::DotDot
{
389 RangeLimits
::HalfOpen
394 let r
= self.mk_range(None
, opt_end
, limits
)?
;
395 Ok(self.mk_expr(lo
.to(hi
), r
, attrs
))
398 /// Parses a prefix-unary-operator expr.
399 fn parse_prefix_expr(
401 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>
402 ) -> PResult
<'a
, P
<Expr
>> {
403 let attrs
= self.parse_or_use_outer_attributes(already_parsed_attrs
)?
;
404 let lo
= self.token
.span
;
405 // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
406 let (hi
, ex
) = match self.token
.kind
{
409 let e
= self.parse_prefix_expr(None
);
410 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
411 (lo
.to(span
), self.mk_unary(UnOp
::Not
, e
))
413 // Suggest `!` for bitwise negation when encountering a `~`
416 let e
= self.parse_prefix_expr(None
);
417 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
418 let span_of_tilde
= lo
;
419 self.struct_span_err(span_of_tilde
, "`~` cannot be used as a unary operator")
420 .span_suggestion_short(
422 "use `!` to perform bitwise not",
424 Applicability
::MachineApplicable
427 (lo
.to(span
), self.mk_unary(UnOp
::Not
, e
))
429 token
::BinOp(token
::Minus
) => {
431 let e
= self.parse_prefix_expr(None
);
432 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
433 (lo
.to(span
), self.mk_unary(UnOp
::Neg
, e
))
435 token
::BinOp(token
::Star
) => {
437 let e
= self.parse_prefix_expr(None
);
438 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
439 (lo
.to(span
), self.mk_unary(UnOp
::Deref
, e
))
441 token
::BinOp(token
::And
) | token
::AndAnd
=> {
442 self.parse_address_of(lo
)?
444 token
::Ident(..) if self.token
.is_keyword(kw
::Box
) => {
446 let e
= self.parse_prefix_expr(None
);
447 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
448 let span
= lo
.to(span
);
449 self.sess
.gated_spans
.gate(sym
::box_syntax
, span
);
450 (span
, ExprKind
::Box(e
))
452 token
::Ident(..) if self.token
.is_ident_named(sym
::not
) => {
453 // `not` is just an ordinary identifier in Rust-the-language,
454 // but as `rustc`-the-compiler, we can issue clever diagnostics
455 // for confused users who really want to say `!`
456 let token_cannot_continue_expr
= |t
: &Token
| match t
.kind
{
457 // These tokens can start an expression after `!`, but
458 // can't continue an expression after an ident
459 token
::Ident(name
, is_raw
) => token
::ident_can_begin_expr(name
, t
.span
, is_raw
),
460 token
::Literal(..) | token
::Pound
=> true,
461 _
=> t
.is_whole_expr(),
463 let cannot_continue_expr
= self.look_ahead(1, token_cannot_continue_expr
);
464 if cannot_continue_expr
{
466 // Emit the error ...
467 self.struct_span_err(
469 &format
!("unexpected {} after identifier",self.this_token_descr())
471 .span_suggestion_short(
472 // Span the `not` plus trailing whitespace to avoid
473 // trailing whitespace after the `!` in our suggestion
474 self.sess
.source_map()
475 .span_until_non_whitespace(lo
.to(self.token
.span
)),
476 "use `!` to perform logical negation",
478 Applicability
::MachineApplicable
481 // —and recover! (just as if we were in the block
482 // for the `token::Not` arm)
483 let e
= self.parse_prefix_expr(None
);
484 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
485 (lo
.to(span
), self.mk_unary(UnOp
::Not
, e
))
487 return self.parse_dot_or_call_expr(Some(attrs
));
490 _
=> { return self.parse_dot_or_call_expr(Some(attrs)); }
492 return Ok(self.mk_expr(lo
.to(hi
), ex
, attrs
));
495 /// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
496 fn interpolated_or_expr_span(
498 expr
: PResult
<'a
, P
<Expr
>>,
499 ) -> PResult
<'a
, (Span
, P
<Expr
>)> {
501 if self.prev_token_kind
== PrevTokenKind
::Interpolated
{
509 fn parse_assoc_op_cast(&mut self, lhs
: P
<Expr
>, lhs_span
: Span
,
510 expr_kind
: fn(P
<Expr
>, P
<Ty
>) -> ExprKind
)
511 -> PResult
<'a
, P
<Expr
>> {
512 let mk_expr
= |this
: &mut Self, rhs
: P
<Ty
>| {
513 this
.mk_expr(lhs_span
.to(rhs
.span
), expr_kind(lhs
, rhs
), ThinVec
::new())
516 // Save the state of the parser before parsing type normally, in case there is a
517 // LessThan comparison after this cast.
518 let parser_snapshot_before_type
= self.clone();
519 match self.parse_ty_no_plus() {
521 Ok(mk_expr(self, rhs
))
523 Err(mut type_err
) => {
524 // Rewind to before attempting to parse the type with generics, to recover
525 // from situations like `x as usize < y` in which we first tried to parse
526 // `usize < y` as a type with generic arguments.
527 let parser_snapshot_after_type
= self.clone();
528 mem
::replace(self, parser_snapshot_before_type
);
530 match self.parse_path(PathStyle
::Expr
) {
532 let (op_noun
, op_verb
) = match self.token
.kind
{
533 token
::Lt
=> ("comparison", "comparing"),
534 token
::BinOp(token
::Shl
) => ("shift", "shifting"),
536 // We can end up here even without `<` being the next token, for
537 // example because `parse_ty_no_plus` returns `Err` on keywords,
538 // but `parse_path` returns `Ok` on them due to error recovery.
539 // Return original error and parser state.
540 mem
::replace(self, parser_snapshot_after_type
);
541 return Err(type_err
);
545 // Successfully parsed the type path leaving a `<` yet to parse.
548 // Report non-fatal diagnostics, keep `x as usize` as an expression
549 // in AST and continue parsing.
551 "`<` is interpreted as a start of generic arguments for `{}`, not a {}",
552 pprust
::path_to_string(&path
),
555 let span_after_type
= parser_snapshot_after_type
.token
.span
;
556 let expr
= mk_expr(self, P(Ty
{
558 kind
: TyKind
::Path(None
, path
),
562 let expr_str
= self.span_to_snippet(expr
.span
)
563 .unwrap_or_else(|_
| pprust
::expr_to_string(&expr
));
565 self.struct_span_err(self.token
.span
, &msg
)
567 self.look_ahead(1, |t
| t
.span
).to(span_after_type
),
568 "interpreted as generic arguments"
570 .span_label(self.token
.span
, format
!("not interpreted as {}", op_noun
))
573 &format
!("try {} the cast value", op_verb
),
574 format
!("({})", expr_str
),
575 Applicability
::MachineApplicable
,
581 Err(mut path_err
) => {
582 // Couldn't parse as a path, return original error and parser state.
584 mem
::replace(self, parser_snapshot_after_type
);
592 /// Parse `& mut? <expr>` or `& raw [ const | mut ] <expr>`.
593 fn parse_address_of(&mut self, lo
: Span
) -> PResult
<'a
, (Span
, ExprKind
)> {
595 let (k
, m
) = if self.check_keyword(kw
::Raw
)
596 && self.look_ahead(1, Token
::is_mutability
)
598 let found_raw
= self.eat_keyword(kw
::Raw
);
600 let mutability
= self.parse_const_or_mut().unwrap();
601 self.sess
.gated_spans
.gate(sym
::raw_ref_op
, lo
.to(self.prev_span
));
602 (ast
::BorrowKind
::Raw
, mutability
)
604 (ast
::BorrowKind
::Ref
, self.parse_mutability())
606 let e
= self.parse_prefix_expr(None
);
607 let (span
, e
) = self.interpolated_or_expr_span(e
)?
;
608 Ok((lo
.to(span
), ExprKind
::AddrOf(k
, m
, e
)))
611 /// Parses `a.b` or `a(13)` or `a[4]` or just `a`.
612 fn parse_dot_or_call_expr(
614 already_parsed_attrs
: Option
<ThinVec
<Attribute
>>,
615 ) -> PResult
<'a
, P
<Expr
>> {
616 let attrs
= self.parse_or_use_outer_attributes(already_parsed_attrs
)?
;
618 let b
= self.parse_bottom_expr();
619 let (span
, b
) = self.interpolated_or_expr_span(b
)?
;
620 self.parse_dot_or_call_expr_with(b
, span
, attrs
)
623 pub(super) fn parse_dot_or_call_expr_with(
627 mut attrs
: ThinVec
<Attribute
>,
628 ) -> PResult
<'a
, P
<Expr
>> {
629 // Stitch the list of outer attributes onto the return value.
630 // A little bit ugly, but the best way given the current code
632 self.parse_dot_or_call_expr_with_(e0
, lo
).map(|expr
|
633 expr
.map(|mut expr
| {
634 attrs
.extend
::<Vec
<_
>>(expr
.attrs
.into());
637 ExprKind
::If(..) if !expr
.attrs
.is_empty() => {
638 // Just point to the first attribute in there...
639 let span
= expr
.attrs
[0].span
;
640 self.span_err(span
, "attributes are not yet allowed on `if` expressions");
649 fn parse_dot_or_call_expr_with_(&mut self, e0
: P
<Expr
>, lo
: Span
) -> PResult
<'a
, P
<Expr
>> {
654 while self.eat(&token
::Question
) {
655 let hi
= self.prev_span
;
656 e
= self.mk_expr(lo
.to(hi
), ExprKind
::Try(e
), ThinVec
::new());
660 if self.eat(&token
::Dot
) {
661 match self.token
.kind
{
662 token
::Ident(..) => {
663 e
= self.parse_dot_suffix(e
, lo
)?
;
665 token
::Literal(token
::Lit { kind: token::Integer, symbol, suffix }
) => {
666 let span
= self.token
.span
;
668 let field
= ExprKind
::Field(e
, Ident
::new(symbol
, span
));
669 e
= self.mk_expr(lo
.to(span
), field
, ThinVec
::new());
671 self.expect_no_suffix(span
, "a tuple index", suffix
);
673 token
::Literal(token
::Lit { kind: token::Float, symbol, .. }
) => {
675 let fstr
= symbol
.as_str();
676 let msg
= format
!("unexpected token: `{}`", symbol
);
677 let mut err
= self.diagnostic().struct_span_err(self.prev_span
, &msg
);
678 err
.span_label(self.prev_span
, "unexpected token");
679 if fstr
.chars().all(|x
| "0123456789.".contains(x
)) {
680 let float
= match fstr
.parse
::<f64>().ok() {
684 let sugg
= pprust
::to_string(|s
| {
688 s
.print_usize(float
.trunc() as usize);
691 s
.s
.word(fstr
.splitn(2, ".").last().unwrap().to_string())
694 lo
.to(self.prev_span
),
695 "try parenthesizing the first index",
697 Applicability
::MachineApplicable
704 // FIXME Could factor this out into non_fatal_unexpected or something.
705 let actual
= self.this_token_to_string();
706 self.span_err(self.token
.span
, &format
!("unexpected token: `{}`", actual
));
711 if self.expr_is_complete(&e
) { break; }
712 match self.token
.kind
{
714 token
::OpenDelim(token
::Paren
) => {
715 let seq
= self.parse_paren_expr_seq().map(|es
| {
716 let nd
= self.mk_call(e
, es
);
717 let hi
= self.prev_span
;
718 self.mk_expr(lo
.to(hi
), nd
, ThinVec
::new())
720 e
= self.recover_seq_parse_error(token
::Paren
, lo
, seq
);
724 // Could be either an index expression or a slicing expression.
725 token
::OpenDelim(token
::Bracket
) => {
727 let ix
= self.parse_expr()?
;
728 hi
= self.token
.span
;
729 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
730 let index
= self.mk_index(e
, ix
);
731 e
= self.mk_expr(lo
.to(hi
), index
, ThinVec
::new())
739 /// Assuming we have just parsed `.`, continue parsing into an expression.
740 fn parse_dot_suffix(&mut self, self_arg
: P
<Expr
>, lo
: Span
) -> PResult
<'a
, P
<Expr
>> {
741 if self.token
.span
.rust_2018() && self.eat_keyword(kw
::Await
) {
742 return self.mk_await_expr(self_arg
, lo
);
745 let segment
= self.parse_path_segment(PathStyle
::Expr
)?
;
746 self.check_trailing_angle_brackets(&segment
, token
::OpenDelim(token
::Paren
));
748 Ok(match self.token
.kind
{
749 token
::OpenDelim(token
::Paren
) => {
750 // Method call `expr.f()`
751 let mut args
= self.parse_paren_expr_seq()?
;
752 args
.insert(0, self_arg
);
754 let span
= lo
.to(self.prev_span
);
755 self.mk_expr(span
, ExprKind
::MethodCall(segment
, args
), ThinVec
::new())
758 // Field access `expr.f`
759 if let Some(args
) = segment
.args
{
760 self.span_err(args
.span(),
761 "field expressions may not have generic arguments");
764 let span
= lo
.to(self.prev_span
);
765 self.mk_expr(span
, ExprKind
::Field(self_arg
, segment
.ident
), ThinVec
::new())
770 /// At the bottom (top?) of the precedence hierarchy,
771 /// Parses things like parenthesized exprs, macros, `return`, etc.
773 /// N.B., this does not parse outer attributes, and is private because it only works
774 /// correctly if called from `parse_dot_or_call_expr()`.
775 fn parse_bottom_expr(&mut self) -> PResult
<'a
, P
<Expr
>> {
776 maybe_recover_from_interpolated_ty_qpath
!(self, true);
777 maybe_whole_expr
!(self);
779 // Outer attributes are already parsed and will be
780 // added to the return value after the fact.
782 // Therefore, prevent sub-parser from parsing
783 // attributes by giving them a empty "already-parsed" list.
784 let mut attrs
= ThinVec
::new();
786 let lo
= self.token
.span
;
787 let mut hi
= self.token
.span
;
791 macro_rules
! parse_lit
{
793 match self.parse_opt_lit() {
796 ex
= ExprKind
::Lit(literal
);
799 return Err(self.expected_expression_found());
805 // Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
806 match self.token
.kind
{
807 // This match arm is a special-case of the `_` match arm below and
808 // could be removed without changing functionality, but it's faster
809 // to have it here, especially for programs with large constants.
810 token
::Literal(_
) => {
813 token
::OpenDelim(token
::Paren
) => {
816 attrs
.extend(self.parse_inner_attributes()?
);
818 // `(e)` is parenthesized `e`.
819 // `(e,)` is a tuple with only one field, `e`.
821 let mut trailing_comma
= false;
822 let mut recovered
= false;
823 while self.token
!= token
::CloseDelim(token
::Paren
) {
824 es
.push(match self.parse_expr() {
827 // Recover from parse error in tuple list.
828 match self.token
.kind
{
829 token
::Ident(name
, false)
830 if name
== kw
::Underscore
&& self.look_ahead(1, |t
| {
833 // Special-case handling of `Foo<(_, _, _)>`
835 let sp
= self.token
.span
;
837 self.mk_expr(sp
, ExprKind
::Err
, ThinVec
::new())
840 self.recover_seq_parse_error(token
::Paren
, lo
, Err(err
)),
845 recovered
= self.expect_one_of(
847 &[token
::Comma
, token
::CloseDelim(token
::Paren
)],
849 if self.eat(&token
::Comma
) {
850 trailing_comma
= true;
852 trailing_comma
= false;
861 ex
= if es
.len() == 1 && !trailing_comma
{
862 ExprKind
::Paren(es
.into_iter().nth(0).unwrap())
867 token
::OpenDelim(token
::Brace
) => {
868 return self.parse_block_expr(None
, lo
, BlockCheckMode
::Default
, attrs
);
870 token
::BinOp(token
::Or
) | token
::OrOr
=> {
871 return self.parse_closure_expr(attrs
);
873 token
::OpenDelim(token
::Bracket
) => {
876 attrs
.extend(self.parse_inner_attributes()?
);
878 if self.eat(&token
::CloseDelim(token
::Bracket
)) {
880 ex
= ExprKind
::Array(Vec
::new());
883 let first_expr
= self.parse_expr()?
;
884 if self.eat(&token
::Semi
) {
885 // Repeating array syntax: `[ 0; 512 ]`
886 let count
= AnonConst
{
888 value
: self.parse_expr()?
,
890 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
891 ex
= ExprKind
::Repeat(first_expr
, count
);
892 } else if self.eat(&token
::Comma
) {
893 // Vector with two or more elements
894 let remaining_exprs
= self.parse_seq_to_end(
895 &token
::CloseDelim(token
::Bracket
),
896 SeqSep
::trailing_allowed(token
::Comma
),
897 |p
| Ok(p
.parse_expr()?
)
899 let mut exprs
= vec
![first_expr
];
900 exprs
.extend(remaining_exprs
);
901 ex
= ExprKind
::Array(exprs
);
903 // Vector with one element
904 self.expect(&token
::CloseDelim(token
::Bracket
))?
;
905 ex
= ExprKind
::Array(vec
![first_expr
]);
912 let (qself
, path
) = self.parse_qpath(PathStyle
::Expr
)?
;
914 return Ok(self.mk_expr(lo
.to(hi
), ExprKind
::Path(Some(qself
), path
), attrs
));
916 if self.token
.is_path_start() {
917 let path
= self.parse_path(PathStyle
::Expr
)?
;
919 // `!`, as an operator, is prefix, so we know this isn't that.
920 if self.eat(&token
::Not
) {
921 // MACRO INVOCATION expression
922 let args
= self.parse_mac_args()?
;
924 ex
= ExprKind
::Mac(Mac
{
927 prior_type_ascription
: self.last_type_ascription
,
929 } else if self.check(&token
::OpenDelim(token
::Brace
)) {
930 if let Some(expr
) = self.maybe_parse_struct_expr(lo
, &path
, &attrs
) {
934 ex
= ExprKind
::Path(None
, path
);
938 ex
= ExprKind
::Path(None
, path
);
941 let expr
= self.mk_expr(lo
.to(hi
), ex
, attrs
);
942 return self.maybe_recover_from_bad_qpath(expr
, true);
944 if self.check_keyword(kw
::Move
) || self.check_keyword(kw
::Static
) {
945 return self.parse_closure_expr(attrs
);
947 if self.eat_keyword(kw
::If
) {
948 return self.parse_if_expr(attrs
);
950 if self.eat_keyword(kw
::For
) {
951 let lo
= self.prev_span
;
952 return self.parse_for_expr(None
, lo
, attrs
);
954 if self.eat_keyword(kw
::While
) {
955 let lo
= self.prev_span
;
956 return self.parse_while_expr(None
, lo
, attrs
);
958 if let Some(label
) = self.eat_label() {
959 let lo
= label
.ident
.span
;
960 self.expect(&token
::Colon
)?
;
961 if self.eat_keyword(kw
::While
) {
962 return self.parse_while_expr(Some(label
), lo
, attrs
)
964 if self.eat_keyword(kw
::For
) {
965 return self.parse_for_expr(Some(label
), lo
, attrs
)
967 if self.eat_keyword(kw
::Loop
) {
968 return self.parse_loop_expr(Some(label
), lo
, attrs
)
970 if self.token
== token
::OpenDelim(token
::Brace
) {
971 return self.parse_block_expr(Some(label
),
973 BlockCheckMode
::Default
,
976 let msg
= "expected `while`, `for`, `loop` or `{` after a label";
977 let mut err
= self.fatal(msg
);
978 err
.span_label(self.token
.span
, msg
);
981 if self.eat_keyword(kw
::Loop
) {
982 let lo
= self.prev_span
;
983 return self.parse_loop_expr(None
, lo
, attrs
);
985 if self.eat_keyword(kw
::Continue
) {
986 let label
= self.eat_label();
987 let ex
= ExprKind
::Continue(label
);
988 let hi
= self.prev_span
;
989 return Ok(self.mk_expr(lo
.to(hi
), ex
, attrs
));
991 if self.eat_keyword(kw
::Match
) {
992 let match_sp
= self.prev_span
;
993 return self.parse_match_expr(attrs
).map_err(|mut err
| {
994 err
.span_label(match_sp
, "while parsing this match expression");
998 if self.eat_keyword(kw
::Unsafe
) {
999 return self.parse_block_expr(
1002 BlockCheckMode
::Unsafe(ast
::UserProvided
),
1005 if self.is_do_catch_block() {
1006 let mut db
= self.fatal("found removed `do catch` syntax");
1007 db
.help("following RFC #2388, the new non-placeholder syntax is `try`");
1010 if self.is_try_block() {
1011 let lo
= self.token
.span
;
1012 assert
!(self.eat_keyword(kw
::Try
));
1013 return self.parse_try_block(lo
, attrs
);
1016 // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly.
1017 let is_span_rust_2018
= self.token
.span
.rust_2018();
1018 if is_span_rust_2018
&& self.check_keyword(kw
::Async
) {
1019 return if self.is_async_block() { // Check for `async {` and `async move {`.
1020 self.parse_async_block(attrs
)
1022 self.parse_closure_expr(attrs
)
1025 if self.eat_keyword(kw
::Return
) {
1026 if self.token
.can_begin_expr() {
1027 let e
= self.parse_expr()?
;
1029 ex
= ExprKind
::Ret(Some(e
));
1031 ex
= ExprKind
::Ret(None
);
1033 } else if self.eat_keyword(kw
::Break
) {
1034 let label
= self.eat_label();
1035 let e
= if self.token
.can_begin_expr()
1036 && !(self.token
== token
::OpenDelim(token
::Brace
)
1037 && self.restrictions
.contains(
1038 Restrictions
::NO_STRUCT_LITERAL
)) {
1039 Some(self.parse_expr()?
)
1043 ex
= ExprKind
::Break(label
, e
);
1044 hi
= self.prev_span
;
1045 } else if self.eat_keyword(kw
::Yield
) {
1046 if self.token
.can_begin_expr() {
1047 let e
= self.parse_expr()?
;
1049 ex
= ExprKind
::Yield(Some(e
));
1051 ex
= ExprKind
::Yield(None
);
1054 let span
= lo
.to(hi
);
1055 self.sess
.gated_spans
.gate(sym
::generators
, span
);
1056 } else if self.eat_keyword(kw
::Let
) {
1057 return self.parse_let_expr(attrs
);
1058 } else if is_span_rust_2018
&& self.eat_keyword(kw
::Await
) {
1059 let (await_hi
, e_kind
) = self.parse_incorrect_await_syntax(lo
, self.prev_span
)?
;
1063 if !self.unclosed_delims
.is_empty() && self.check(&token
::Semi
) {
1064 // Don't complain about bare semicolons after unclosed braces
1065 // recovery in order to keep the error count down. Fixing the
1066 // delimiters will possibly also fix the bare semicolon found in
1067 // expression context. For example, silence the following error:
1069 // error: expected expression, found `;`
1073 // | ^ expected expression
1075 return Ok(self.mk_expr(self.token
.span
, ExprKind
::Err
, ThinVec
::new()));
1082 let expr
= self.mk_expr(lo
.to(hi
), ex
, attrs
);
1083 self.maybe_recover_from_bad_qpath(expr
, true)
1086 /// Returns a string literal if the next token is a string literal.
1087 /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
1088 /// and returns `None` if the next token is not literal at all.
1089 pub fn parse_str_lit(&mut self) -> Result
<ast
::StrLit
, Option
<Lit
>> {
1090 match self.parse_opt_lit() {
1091 Some(lit
) => match lit
.kind
{
1092 ast
::LitKind
::Str(symbol_unescaped
, style
) => Ok(ast
::StrLit
{
1094 symbol
: lit
.token
.symbol
,
1095 suffix
: lit
.token
.suffix
,
1099 _
=> Err(Some(lit
)),
1105 pub(super) fn parse_lit(&mut self) -> PResult
<'a
, Lit
> {
1106 self.parse_opt_lit().ok_or_else(|| {
1107 let msg
= format
!("unexpected token: {}", self.this_token_descr());
1108 self.span_fatal(self.token
.span
, &msg
)
1112 /// Matches `lit = true | false | token_lit`.
1113 /// Returns `None` if the next token is not a literal.
1114 pub(super) fn parse_opt_lit(&mut self) -> Option
<Lit
> {
1115 let mut recovered
= None
;
1116 if self.token
== token
::Dot
{
1117 // Attempt to recover `.4` as `0.4`. We don't currently have any syntax where
1118 // dot would follow an optional literal, so we do this unconditionally.
1119 recovered
= self.look_ahead(1, |next_token
| {
1120 if let token
::Literal(token
::Lit { kind: token::Integer, symbol, suffix }
)
1122 if self.token
.span
.hi() == next_token
.span
.lo() {
1123 let s
= String
::from("0.") + &symbol
.as_str();
1124 let kind
= TokenKind
::lit(token
::Float
, Symbol
::intern(&s
), suffix
);
1125 return Some(Token
::new(kind
, self.token
.span
.to(next_token
.span
)));
1130 if let Some(token
) = &recovered
{
1132 self.struct_span_err(token
.span
, "float literals must have an integer part")
1135 "must have an integer part",
1136 pprust
::token_to_string(token
),
1137 Applicability
::MachineApplicable
,
1143 let token
= recovered
.as_ref().unwrap_or(&self.token
);
1144 match Lit
::from_token(token
) {
1149 Err(LitError
::NotLiteral
) => {
1153 let span
= token
.span
;
1154 let lit
= match token
.kind
{
1155 token
::Literal(lit
) => lit
,
1156 _
=> unreachable
!(),
1159 self.report_lit_error(err
, lit
, span
);
1160 // Pack possible quotes and prefixes from the original literal into
1161 // the error literal's symbol so they can be pretty-printed faithfully.
1162 let suffixless_lit
= token
::Lit
::new(lit
.kind
, lit
.symbol
, None
);
1163 let symbol
= Symbol
::intern(&suffixless_lit
.to_string());
1164 let lit
= token
::Lit
::new(token
::Err
, symbol
, lit
.suffix
);
1165 Some(Lit
::from_lit_token(lit
, span
).unwrap_or_else(|_
| unreachable
!()))
1170 fn report_lit_error(&self, err
: LitError
, lit
: token
::Lit
, span
: Span
) {
1171 // Checks if `s` looks like i32 or u1234 etc.
1172 fn looks_like_width_suffix(first_chars
: &[char], s
: &str) -> bool
{
1174 && s
.starts_with(first_chars
)
1175 && s
[1..].chars().all(|c
| c
.is_ascii_digit())
1178 let token
::Lit { kind, suffix, .. }
= lit
;
1180 // `NotLiteral` is not an error by itself, so we don't report
1181 // it and give the parser opportunity to try something else.
1182 LitError
::NotLiteral
=> {}
1183 // `LexerError` *is* an error, but it was already reported
1184 // by lexer, so here we don't report it the second time.
1185 LitError
::LexerError
=> {}
1186 LitError
::InvalidSuffix
=> {
1187 self.expect_no_suffix(
1189 &format
!("{} {} literal", kind
.article(), kind
.descr()),
1193 LitError
::InvalidIntSuffix
=> {
1194 let suf
= suffix
.expect("suffix error with no suffix").as_str();
1195 if looks_like_width_suffix(&['i'
, 'u'
], &suf
) {
1196 // If it looks like a width, try to be helpful.
1197 let msg
= format
!("invalid width `{}` for integer literal", &suf
[1..]);
1198 self.struct_span_err(span
, &msg
)
1199 .help("valid widths are 8, 16, 32, 64 and 128")
1202 let msg
= format
!("invalid suffix `{}` for integer literal", suf
);
1203 self.struct_span_err(span
, &msg
)
1204 .span_label(span
, format
!("invalid suffix `{}`", suf
))
1205 .help("the suffix must be one of the integral types (`u32`, `isize`, etc)")
1209 LitError
::InvalidFloatSuffix
=> {
1210 let suf
= suffix
.expect("suffix error with no suffix").as_str();
1211 if looks_like_width_suffix(&['f'
], &suf
) {
1212 // If it looks like a width, try to be helpful.
1213 let msg
= format
!("invalid width `{}` for float literal", &suf
[1..]);
1214 self.struct_span_err(span
, &msg
)
1215 .help("valid widths are 32 and 64")
1218 let msg
= format
!("invalid suffix `{}` for float literal", suf
);
1219 self.struct_span_err(span
, &msg
)
1220 .span_label(span
, format
!("invalid suffix `{}`", suf
))
1221 .help("valid suffixes are `f32` and `f64`")
1225 LitError
::NonDecimalFloat(base
) => {
1226 let descr
= match base
{
1227 16 => "hexadecimal",
1230 _
=> unreachable
!(),
1232 self.struct_span_err(span
, &format
!("{} float literal is not supported", descr
))
1233 .span_label(span
, "not supported")
1236 LitError
::IntTooLarge
=> {
1237 self.struct_span_err(span
, "integer literal is too large")
1243 pub(super) fn expect_no_suffix(&self, sp
: Span
, kind
: &str, suffix
: Option
<Symbol
>) {
1244 if let Some(suf
) = suffix
{
1245 let mut err
= if kind
== "a tuple index"
1246 && [sym
::i32, sym
::u32, sym
::isize, sym
::usize].contains(&suf
)
1248 // #59553: warn instead of reject out of hand to allow the fix to percolate
1249 // through the ecosystem when people fix their macros
1250 let mut err
= self.sess
.span_diagnostic
.struct_span_warn(
1252 &format
!("suffixes on {} are invalid", kind
),
1255 "`{}` is *temporarily* accepted on tuple index fields as it was \
1256 incorrectly accepted on stable for a few releases",
1260 "on proc macros, you'll want to use `syn::Index::from` or \
1261 `proc_macro::Literal::*_unsuffixed` for code that will desugar \
1262 to tuple field access",
1265 "for more context, see https://github.com/rust-lang/rust/issues/60210",
1269 self.struct_span_err(sp
, &format
!("suffixes on {} are invalid", kind
))
1271 err
.span_label(sp
, format
!("invalid suffix `{}`", suf
));
1276 /// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
1277 pub fn parse_literal_maybe_minus(&mut self) -> PResult
<'a
, P
<Expr
>> {
1278 maybe_whole_expr
!(self);
1280 let minus_lo
= self.token
.span
;
1281 let minus_present
= self.eat(&token
::BinOp(token
::Minus
));
1282 let lo
= self.token
.span
;
1283 let literal
= self.parse_lit()?
;
1284 let hi
= self.prev_span
;
1285 let expr
= self.mk_expr(lo
.to(hi
), ExprKind
::Lit(literal
), ThinVec
::new());
1288 let minus_hi
= self.prev_span
;
1289 let unary
= self.mk_unary(UnOp
::Neg
, expr
);
1290 Ok(self.mk_expr(minus_lo
.to(minus_hi
), unary
, ThinVec
::new()))
1296 /// Parses a block or unsafe block.
1297 pub(super) fn parse_block_expr(
1299 opt_label
: Option
<Label
>,
1301 blk_mode
: BlockCheckMode
,
1302 outer_attrs
: ThinVec
<Attribute
>,
1303 ) -> PResult
<'a
, P
<Expr
>> {
1304 if let Some(label
) = opt_label
{
1305 self.sess
.gated_spans
.gate(sym
::label_break_value
, label
.ident
.span
);
1308 self.expect(&token
::OpenDelim(token
::Brace
))?
;
1310 let mut attrs
= outer_attrs
;
1311 attrs
.extend(self.parse_inner_attributes()?
);
1313 let blk
= self.parse_block_tail(lo
, blk_mode
)?
;
1314 Ok(self.mk_expr(blk
.span
, ExprKind
::Block(blk
, opt_label
), attrs
))
1317 /// Parses a closure expression (e.g., `move |args| expr`).
1318 fn parse_closure_expr(&mut self, attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
1319 let lo
= self.token
.span
;
1321 let movability
= if self.eat_keyword(kw
::Static
) {
1327 let asyncness
= if self.token
.span
.rust_2018() {
1328 self.parse_asyncness()
1332 if asyncness
.is_async() {
1333 // Feature-gate `async ||` closures.
1334 self.sess
.gated_spans
.gate(sym
::async_closure
, self.prev_span
);
1337 let capture_clause
= self.parse_capture_clause();
1338 let decl
= self.parse_fn_block_decl()?
;
1339 let decl_hi
= self.prev_span
;
1340 let body
= match decl
.output
{
1341 FunctionRetTy
::Default(_
) => {
1342 let restrictions
= self.restrictions
- Restrictions
::STMT_EXPR
;
1343 self.parse_expr_res(restrictions
, None
)?
1346 // If an explicit return type is given, require a block to appear (RFC 968).
1347 let body_lo
= self.token
.span
;
1348 self.parse_block_expr(None
, body_lo
, BlockCheckMode
::Default
, ThinVec
::new())?
1354 ExprKind
::Closure(capture_clause
, asyncness
, movability
, decl
, body
, lo
.to(decl_hi
)),
1358 /// Parses an optional `move` prefix to a closure lke construct.
1359 fn parse_capture_clause(&mut self) -> CaptureBy
{
1360 if self.eat_keyword(kw
::Move
) {
1367 /// Parses the `|arg, arg|` header of a closure.
1368 fn parse_fn_block_decl(&mut self) -> PResult
<'a
, P
<FnDecl
>> {
1369 let inputs_captures
= {
1370 if self.eat(&token
::OrOr
) {
1373 self.expect(&token
::BinOp(token
::Or
))?
;
1374 let args
= self.parse_seq_to_before_tokens(
1375 &[&token
::BinOp(token
::Or
), &token
::OrOr
],
1376 SeqSep
::trailing_allowed(token
::Comma
),
1377 TokenExpectType
::NoExpect
,
1378 |p
| p
.parse_fn_block_param()
1384 let output
= self.parse_ret_ty(true)?
;
1387 inputs
: inputs_captures
,
1392 /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
1393 fn parse_fn_block_param(&mut self) -> PResult
<'a
, Param
> {
1394 let lo
= self.token
.span
;
1395 let attrs
= self.parse_outer_attributes()?
;
1396 let pat
= self.parse_pat(PARAM_EXPECTED
)?
;
1397 let t
= if self.eat(&token
::Colon
) {
1402 kind
: TyKind
::Infer
,
1403 span
: self.prev_span
,
1406 let span
= lo
.to(self.token
.span
);
1408 attrs
: attrs
.into(),
1413 is_placeholder
: false,
1417 /// Parses an `if` expression (`if` token already eaten).
1418 fn parse_if_expr(&mut self, attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
1419 let lo
= self.prev_span
;
1420 let cond
= self.parse_cond_expr()?
;
1422 // Verify that the parsed `if` condition makes sense as a condition. If it is a block, then
1423 // verify that the last statement is either an implicit return (no `;`) or an explicit
1424 // return. This won't catch blocks with an explicit `return`, but that would be caught by
1425 // the dead code lint.
1426 if self.eat_keyword(kw
::Else
) || !cond
.returns() {
1427 let sp
= self.sess
.source_map().next_point(lo
);
1428 let mut err
= self.diagnostic()
1429 .struct_span_err(sp
, "missing condition for `if` expression");
1430 err
.span_label(sp
, "expected if condition here");
1433 let not_block
= self.token
!= token
::OpenDelim(token
::Brace
);
1434 let thn
= self.parse_block().map_err(|mut err
| {
1436 err
.span_label(lo
, "this `if` statement has a condition, but no block");
1440 let mut els
: Option
<P
<Expr
>> = None
;
1441 let mut hi
= thn
.span
;
1442 if self.eat_keyword(kw
::Else
) {
1443 let elexpr
= self.parse_else_expr()?
;
1447 Ok(self.mk_expr(lo
.to(hi
), ExprKind
::If(cond
, thn
, els
), attrs
))
1450 /// Parses the condition of a `if` or `while` expression.
1451 fn parse_cond_expr(&mut self) -> PResult
<'a
, P
<Expr
>> {
1452 let cond
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
1454 if let ExprKind
::Let(..) = cond
.kind
{
1455 // Remove the last feature gating of a `let` expression since it's stable.
1456 self.sess
.gated_spans
.ungate_last(sym
::let_chains
, cond
.span
);
1462 /// Parses a `let $pat = $expr` pseudo-expression.
1463 /// The `let` token has already been eaten.
1464 fn parse_let_expr(&mut self, attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
1465 let lo
= self.prev_span
;
1466 let pat
= self.parse_top_pat(GateOr
::No
)?
;
1467 self.expect(&token
::Eq
)?
;
1468 let expr
= self.with_res(
1469 Restrictions
::NO_STRUCT_LITERAL
,
1470 |this
| this
.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None
.into())
1472 let span
= lo
.to(expr
.span
);
1473 self.sess
.gated_spans
.gate(sym
::let_chains
, span
);
1474 Ok(self.mk_expr(span
, ExprKind
::Let(pat
, expr
), attrs
))
1477 /// Parses an `else { ... }` expression (`else` token already eaten).
1478 fn parse_else_expr(&mut self) -> PResult
<'a
, P
<Expr
>> {
1479 if self.eat_keyword(kw
::If
) {
1480 return self.parse_if_expr(ThinVec
::new());
1482 let blk
= self.parse_block()?
;
1483 return Ok(self.mk_expr(blk
.span
, ExprKind
::Block(blk
, None
), ThinVec
::new()));
1487 /// Parses a `for ... in` expression (`for` token already eaten).
1490 opt_label
: Option
<Label
>,
1492 mut attrs
: ThinVec
<Attribute
>
1493 ) -> PResult
<'a
, P
<Expr
>> {
1494 // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
1496 // Record whether we are about to parse `for (`.
1497 // This is used below for recovery in case of `for ( $stuff ) $block`
1498 // in which case we will suggest `for $stuff $block`.
1499 let begin_paren
= match self.token
.kind
{
1500 token
::OpenDelim(token
::Paren
) => Some(self.token
.span
),
1504 let pat
= self.parse_top_pat(GateOr
::Yes
)?
;
1505 if !self.eat_keyword(kw
::In
) {
1506 let in_span
= self.prev_span
.between(self.token
.span
);
1507 self.struct_span_err(in_span
, "missing `in` in `for` loop")
1508 .span_suggestion_short(
1510 "try adding `in` here", " in ".into(),
1511 // has been misleading, at least in the past (closed Issue #48492)
1512 Applicability
::MaybeIncorrect
1516 let in_span
= self.prev_span
;
1517 self.check_for_for_in_in_typo(in_span
);
1518 let expr
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
1520 let pat
= self.recover_parens_around_for_head(pat
, &expr
, begin_paren
);
1522 let (iattrs
, loop_block
) = self.parse_inner_attrs_and_block()?
;
1523 attrs
.extend(iattrs
);
1525 let hi
= self.prev_span
;
1526 Ok(self.mk_expr(span_lo
.to(hi
), ExprKind
::ForLoop(pat
, expr
, loop_block
, opt_label
), attrs
))
1529 /// Parses a `while` or `while let` expression (`while` token already eaten).
1530 fn parse_while_expr(
1532 opt_label
: Option
<Label
>,
1534 mut attrs
: ThinVec
<Attribute
>
1535 ) -> PResult
<'a
, P
<Expr
>> {
1536 let cond
= self.parse_cond_expr()?
;
1537 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
1538 attrs
.extend(iattrs
);
1539 let span
= span_lo
.to(body
.span
);
1540 Ok(self.mk_expr(span
, ExprKind
::While(cond
, body
, opt_label
), attrs
))
1543 /// Parses `loop { ... }` (`loop` token already eaten).
1546 opt_label
: Option
<Label
>,
1548 mut attrs
: ThinVec
<Attribute
>
1549 ) -> PResult
<'a
, P
<Expr
>> {
1550 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
1551 attrs
.extend(iattrs
);
1552 let span
= span_lo
.to(body
.span
);
1553 Ok(self.mk_expr(span
, ExprKind
::Loop(body
, opt_label
), attrs
))
1556 fn eat_label(&mut self) -> Option
<Label
> {
1557 if let Some(ident
) = self.token
.lifetime() {
1558 let span
= self.token
.span
;
1560 Some(Label { ident: Ident::new(ident.name, span) }
)
1566 /// Parses a `match ... { ... }` expression (`match` token already eaten).
1567 fn parse_match_expr(&mut self, mut attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
1568 let match_span
= self.prev_span
;
1569 let lo
= self.prev_span
;
1570 let discriminant
= self.parse_expr_res(Restrictions
::NO_STRUCT_LITERAL
, None
)?
;
1571 if let Err(mut e
) = self.expect(&token
::OpenDelim(token
::Brace
)) {
1572 if self.token
== token
::Semi
{
1573 e
.span_suggestion_short(
1575 "try removing this `match`",
1577 Applicability
::MaybeIncorrect
// speculative
1582 attrs
.extend(self.parse_inner_attributes()?
);
1584 let mut arms
: Vec
<Arm
> = Vec
::new();
1585 while self.token
!= token
::CloseDelim(token
::Brace
) {
1586 match self.parse_arm() {
1587 Ok(arm
) => arms
.push(arm
),
1589 // Recover by skipping to the end of the block.
1591 self.recover_stmt();
1592 let span
= lo
.to(self.token
.span
);
1593 if self.token
== token
::CloseDelim(token
::Brace
) {
1596 return Ok(self.mk_expr(span
, ExprKind
::Match(discriminant
, arms
), attrs
));
1600 let hi
= self.token
.span
;
1602 return Ok(self.mk_expr(lo
.to(hi
), ExprKind
::Match(discriminant
, arms
), attrs
));
1605 pub(super) fn parse_arm(&mut self) -> PResult
<'a
, Arm
> {
1606 let attrs
= self.parse_outer_attributes()?
;
1607 let lo
= self.token
.span
;
1608 let pat
= self.parse_top_pat(GateOr
::No
)?
;
1609 let guard
= if self.eat_keyword(kw
::If
) {
1610 Some(self.parse_expr()?
)
1614 let arrow_span
= self.token
.span
;
1615 self.expect(&token
::FatArrow
)?
;
1616 let arm_start_span
= self.token
.span
;
1618 let expr
= self.parse_expr_res(Restrictions
::STMT_EXPR
, None
)
1619 .map_err(|mut err
| {
1620 err
.span_label(arrow_span
, "while parsing the `match` arm starting here");
1624 let require_comma
= classify
::expr_requires_semi_to_be_stmt(&expr
)
1625 && self.token
!= token
::CloseDelim(token
::Brace
);
1627 let hi
= self.token
.span
;
1630 let cm
= self.sess
.source_map();
1631 self.expect_one_of(&[token
::Comma
], &[token
::CloseDelim(token
::Brace
)])
1632 .map_err(|mut err
| {
1633 match (cm
.span_to_lines(expr
.span
), cm
.span_to_lines(arm_start_span
)) {
1634 (Ok(ref expr_lines
), Ok(ref arm_start_lines
))
1635 if arm_start_lines
.lines
[0].end_col
== expr_lines
.lines
[0].end_col
1636 && expr_lines
.lines
.len() == 2
1637 && self.token
== token
::FatArrow
=> {
1638 // We check whether there's any trailing code in the parse span,
1639 // if there isn't, we very likely have the following:
1642 // | -- - missing comma
1646 // | - ^^ self.token.span
1648 // | parsed until here as `"y" & X`
1649 err
.span_suggestion_short(
1650 arm_start_span
.shrink_to_hi(),
1651 "missing a comma here to end this `match` arm",
1653 Applicability
::MachineApplicable
1657 err
.span_label(arrow_span
,
1658 "while parsing the `match` arm starting here");
1664 self.eat(&token
::Comma
);
1674 is_placeholder
: false,
1678 /// Parses a `try {...}` expression (`try` token already eaten).
1682 mut attrs
: ThinVec
<Attribute
>
1683 ) -> PResult
<'a
, P
<Expr
>> {
1684 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
1685 attrs
.extend(iattrs
);
1686 if self.eat_keyword(kw
::Catch
) {
1687 let mut error
= self.struct_span_err(self.prev_span
,
1688 "keyword `catch` cannot follow a `try` block");
1689 error
.help("try using `match` on the result of the `try` block instead");
1693 let span
= span_lo
.to(body
.span
);
1694 self.sess
.gated_spans
.gate(sym
::try_blocks
, span
);
1695 Ok(self.mk_expr(span
, ExprKind
::TryBlock(body
), attrs
))
1699 fn is_do_catch_block(&self) -> bool
{
1700 self.token
.is_keyword(kw
::Do
) &&
1701 self.is_keyword_ahead(1, &[kw
::Catch
]) &&
1702 self.look_ahead(2, |t
| *t
== token
::OpenDelim(token
::Brace
)) &&
1703 !self.restrictions
.contains(Restrictions
::NO_STRUCT_LITERAL
)
1706 fn is_try_block(&self) -> bool
{
1707 self.token
.is_keyword(kw
::Try
) &&
1708 self.look_ahead(1, |t
| *t
== token
::OpenDelim(token
::Brace
)) &&
1709 self.token
.span
.rust_2018() &&
1710 // Prevent `while try {} {}`, `if try {} {} else {}`, etc.
1711 !self.restrictions
.contains(Restrictions
::NO_STRUCT_LITERAL
)
1714 /// Parses an `async move? {...}` expression.
1715 fn parse_async_block(&mut self, mut attrs
: ThinVec
<Attribute
>) -> PResult
<'a
, P
<Expr
>> {
1716 let span_lo
= self.token
.span
;
1717 self.expect_keyword(kw
::Async
)?
;
1718 let capture_clause
= self.parse_capture_clause();
1719 let (iattrs
, body
) = self.parse_inner_attrs_and_block()?
;
1720 attrs
.extend(iattrs
);
1722 span_lo
.to(body
.span
),
1723 ExprKind
::Async(capture_clause
, DUMMY_NODE_ID
, body
), attrs
))
1726 fn is_async_block(&self) -> bool
{
1727 self.token
.is_keyword(kw
::Async
) &&
1730 self.is_keyword_ahead(1, &[kw
::Move
]) &&
1731 self.look_ahead(2, |t
| *t
== token
::OpenDelim(token
::Brace
))
1733 self.look_ahead(1, |t
| *t
== token
::OpenDelim(token
::Brace
))
1738 fn maybe_parse_struct_expr(
1742 attrs
: &ThinVec
<Attribute
>,
1743 ) -> Option
<PResult
<'a
, P
<Expr
>>> {
1744 let struct_allowed
= !self.restrictions
.contains(Restrictions
::NO_STRUCT_LITERAL
);
1745 let certainly_not_a_block
= || self.look_ahead(1, |t
| t
.is_ident()) && (
1746 // `{ ident, ` cannot start a block.
1747 self.look_ahead(2, |t
| t
== &token
::Comma
) ||
1748 self.look_ahead(2, |t
| t
== &token
::Colon
) && (
1749 // `{ ident: token, ` cannot start a block.
1750 self.look_ahead(4, |t
| t
== &token
::Comma
) ||
1751 // `{ ident: ` cannot start a block unless it's a type ascription `ident: Type`.
1752 self.look_ahead(3, |t
| !t
.can_begin_type())
1756 if struct_allowed
|| certainly_not_a_block() {
1757 // This is a struct literal, but we don't can't accept them here.
1758 let expr
= self.parse_struct_expr(lo
, path
.clone(), attrs
.clone());
1759 if let (Ok(expr
), false) = (&expr
, struct_allowed
) {
1760 self.struct_span_err(
1762 "struct literals are not allowed here",
1764 .multipart_suggestion(
1765 "surround the struct literal with parentheses",
1767 (lo
.shrink_to_lo(), "(".to_string()),
1768 (expr
.span
.shrink_to_hi(), ")".to_string()),
1770 Applicability
::MachineApplicable
,
1779 pub(super) fn parse_struct_expr(
1783 mut attrs
: ThinVec
<Attribute
>
1784 ) -> PResult
<'a
, P
<Expr
>> {
1785 let struct_sp
= lo
.to(self.prev_span
);
1787 let mut fields
= Vec
::new();
1788 let mut base
= None
;
1790 attrs
.extend(self.parse_inner_attributes()?
);
1792 while self.token
!= token
::CloseDelim(token
::Brace
) {
1793 if self.eat(&token
::DotDot
) {
1794 let exp_span
= self.prev_span
;
1795 match self.parse_expr() {
1801 self.recover_stmt();
1804 if self.token
== token
::Comma
{
1805 self.struct_span_err(
1806 exp_span
.to(self.prev_span
),
1807 "cannot use a comma after the base struct",
1809 .span_suggestion_short(
1811 "remove this comma",
1813 Applicability
::MachineApplicable
1815 .note("the base struct must always be the last field")
1817 self.recover_stmt();
1822 let mut recovery_field
= None
;
1823 if let token
::Ident(name
, _
) = self.token
.kind
{
1824 if !self.token
.is_reserved_ident() && self.look_ahead(1, |t
| *t
== token
::Colon
) {
1825 // Use in case of error after field-looking code: `S { foo: () with a }`.
1826 recovery_field
= Some(ast
::Field
{
1827 ident
: Ident
::new(name
, self.token
.span
),
1828 span
: self.token
.span
,
1829 expr
: self.mk_expr(self.token
.span
, ExprKind
::Err
, ThinVec
::new()),
1830 is_shorthand
: false,
1831 attrs
: ThinVec
::new(),
1833 is_placeholder
: false,
1837 let mut parsed_field
= None
;
1838 match self.parse_field() {
1839 Ok(f
) => parsed_field
= Some(f
),
1841 e
.span_label(struct_sp
, "while parsing this struct");
1844 // If the next token is a comma, then try to parse
1845 // what comes next as additional fields, rather than
1846 // bailing out until next `}`.
1847 if self.token
!= token
::Comma
{
1848 self.recover_stmt_(SemiColonMode
::Comma
, BlockMode
::Ignore
);
1849 if self.token
!= token
::Comma
{
1856 match self.expect_one_of(&[token
::Comma
],
1857 &[token
::CloseDelim(token
::Brace
)]) {
1858 Ok(_
) => if let Some(f
) = parsed_field
.or(recovery_field
) {
1859 // Only include the field if there's no parse error for the field name.
1863 if let Some(f
) = recovery_field
{
1866 e
.span_label(struct_sp
, "while parsing this struct");
1868 self.recover_stmt_(SemiColonMode
::Comma
, BlockMode
::Ignore
);
1869 self.eat(&token
::Comma
);
1874 let span
= lo
.to(self.token
.span
);
1875 self.expect(&token
::CloseDelim(token
::Brace
))?
;
1876 return Ok(self.mk_expr(span
, ExprKind
::Struct(pth
, fields
, base
), attrs
));
1879 /// Parses `ident (COLON expr)?`.
1880 fn parse_field(&mut self) -> PResult
<'a
, Field
> {
1881 let attrs
= self.parse_outer_attributes()?
;
1882 let lo
= self.token
.span
;
1884 // Check if a colon exists one ahead. This means we're parsing a fieldname.
1885 let (fieldname
, expr
, is_shorthand
) = if self.look_ahead(1, |t
| {
1886 t
== &token
::Colon
|| t
== &token
::Eq
1888 let fieldname
= self.parse_field_name()?
;
1890 // Check for an equals token. This means the source incorrectly attempts to
1891 // initialize a field with an eq rather than a colon.
1892 if self.token
== token
::Eq
{
1894 .struct_span_err(self.token
.span
, "expected `:`, found `=`")
1896 fieldname
.span
.shrink_to_hi().to(self.token
.span
),
1897 "replace equals symbol with a colon",
1899 Applicability
::MachineApplicable
,
1904 (fieldname
, self.parse_expr()?
, false)
1906 let fieldname
= self.parse_ident_common(false)?
;
1908 // Mimic `x: x` for the `x` field shorthand.
1909 let path
= ast
::Path
::from_ident(fieldname
);
1910 let expr
= self.mk_expr(fieldname
.span
, ExprKind
::Path(None
, path
), ThinVec
::new());
1911 (fieldname
, expr
, true)
1915 span
: lo
.to(expr
.span
),
1918 attrs
: attrs
.into(),
1920 is_placeholder
: false,
1924 fn err_dotdotdot_syntax(&self, span
: Span
) {
1925 self.struct_span_err(span
, "unexpected token: `...`")
1928 "use `..` for an exclusive range", "..".to_owned(),
1929 Applicability
::MaybeIncorrect
1933 "or `..=` for an inclusive range", "..=".to_owned(),
1934 Applicability
::MaybeIncorrect
1939 fn err_larrow_operator(&self, span
: Span
) {
1940 self.struct_span_err(
1942 "unexpected token: `<-`"
1945 "if you meant to write a comparison against a negative value, add a \
1946 space in between `<` and `-`",
1948 Applicability
::MaybeIncorrect
1952 fn mk_assign_op(&self, binop
: BinOp
, lhs
: P
<Expr
>, rhs
: P
<Expr
>) -> ExprKind
{
1953 ExprKind
::AssignOp(binop
, lhs
, rhs
)
1958 start
: Option
<P
<Expr
>>,
1959 end
: Option
<P
<Expr
>>,
1961 ) -> PResult
<'a
, ExprKind
> {
1962 if end
.is_none() && limits
== RangeLimits
::Closed
{
1963 Err(self.span_fatal_err(self.token
.span
, Error
::InclusiveRangeWithNoEnd
))
1965 Ok(ExprKind
::Range(start
, end
, limits
))
1969 fn mk_unary(&self, unop
: UnOp
, expr
: P
<Expr
>) -> ExprKind
{
1970 ExprKind
::Unary(unop
, expr
)
1973 fn mk_binary(&self, binop
: BinOp
, lhs
: P
<Expr
>, rhs
: P
<Expr
>) -> ExprKind
{
1974 ExprKind
::Binary(binop
, lhs
, rhs
)
1977 fn mk_index(&self, expr
: P
<Expr
>, idx
: P
<Expr
>) -> ExprKind
{
1978 ExprKind
::Index(expr
, idx
)
1981 fn mk_call(&self, f
: P
<Expr
>, args
: Vec
<P
<Expr
>>) -> ExprKind
{
1982 ExprKind
::Call(f
, args
)
1985 fn mk_await_expr(&mut self, self_arg
: P
<Expr
>, lo
: Span
) -> PResult
<'a
, P
<Expr
>> {
1986 let span
= lo
.to(self.prev_span
);
1987 let await_expr
= self.mk_expr(span
, ExprKind
::Await(self_arg
), ThinVec
::new());
1988 self.recover_from_await_method_call();
1992 crate fn mk_expr(&self, span
: Span
, kind
: ExprKind
, attrs
: ThinVec
<Attribute
>) -> P
<Expr
> {
1993 P(Expr { kind, span, attrs, id: DUMMY_NODE_ID }
)
1996 pub(super) fn mk_expr_err(&self, span
: Span
) -> P
<Expr
> {
1997 self.mk_expr(span
, ExprKind
::Err
, ThinVec
::new())