-use super::{Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle};
-use super::{BlockMode, SemiColonMode};
-use super::{SeqSep, TokenExpectType};
+use super::{
+ Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode, SemiColonMode,
+ SeqSep, TokenExpectType,
+};
use super::pat::{GateOr, PARAM_EXPECTED};
+use crate::ast::{
+ self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode,
+ Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind,
+ FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field,
+};
use crate::maybe_recover_from_interpolated_ty_qpath;
-use crate::ptr::P;
-use crate::ast::{self, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode};
-use crate::ast::{Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm};
-use crate::ast::{Ty, TyKind, FunctionRetTy, Param, FnDecl};
-use crate::ast::{BinOpKind, BinOp, UnOp};
-use crate::ast::{Mac, AnonConst, Field};
-
use crate::parse::classify;
use crate::parse::token::{self, Token};
-use crate::parse::diagnostics::{Error};
+use crate::parse::diagnostics::Error;
use crate::print::pprust;
+use crate::ptr::P;
use crate::source_map::{self, Span};
use crate::symbol::{kw, sym};
use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
-use std::mem;
use errors::Applicability;
+use std::mem;
use rustc_data_structures::thin_vec::ThinVec;
/// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
$p.token.span, ExprKind::Block(block, None), ThinVec::new()
));
}
- // N.B: `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
+ // N.B., `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
_ => {},
};
}
self.bump();
if op.is_comparison() {
- self.check_no_chained_comparison(&lhs, &op);
+ self.check_no_chained_comparison(&lhs, &op)?;
}
// Special cases:
if op == AssocOp::As {
fn is_at_start_of_range_notation_rhs(&self) -> bool {
if self.token.can_begin_expr() {
- // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
+ // Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
if self.token == token::OpenDelim(token::Brace) {
return !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
}
}
}
- /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr`
+ /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
fn parse_prefix_range_expr(
&mut self,
already_parsed_attrs: Option<ThinVec<Attribute>>
) -> PResult<'a, P<Expr>> {
- // Check for deprecated `...` syntax
+ // Check for deprecated `...` syntax.
if self.token == token::DotDotDot {
self.err_dotdotdot_syntax(self.token.span);
}
Ok(self.mk_expr(lo.to(hi), r, attrs))
}
- /// Parse a prefix-unary-operator expr
+ /// Parses a prefix-unary-operator expr.
fn parse_prefix_expr(
&mut self,
already_parsed_attrs: Option<ThinVec<Attribute>>
let expr = mk_expr(self, P(Ty {
span: path.span,
node: TyKind::Path(None, path),
- id: ast::DUMMY_NODE_ID
+ id: DUMMY_NODE_ID,
}));
let expr_str = self.span_to_snippet(expr.span)
expr.span,
&format!("try {} the cast value", op_verb),
format!("({})", expr_str),
- Applicability::MachineApplicable
+ Applicability::MachineApplicable,
)
.emit();
})
}
-
/// At the bottom (top?) of the precedence hierarchy,
/// Parses things like parenthesized exprs, macros, `return`, etc.
///
// added to the return value after the fact.
//
// Therefore, prevent sub-parser from parsing
- // attributes by giving them a empty "already parsed" list.
+ // attributes by giving them a empty "already-parsed" list.
let mut attrs = ThinVec::new();
let lo = self.token.span;
}
}
- // Note: when adding new syntax here, don't forget to adjust TokenKind::can_begin_expr().
+ // Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
match self.token.kind {
// This match arm is a special-case of the `_` match arm below and
// could be removed without changing functionality, but it's faster
attrs.extend(self.parse_inner_attributes()?);
- // (e) is parenthesized e
- // (e,) is a tuple with only one field, e
+ // `(e)` is parenthesized `e`.
+ // `(e,)` is a tuple with only one field, `e`.
let mut es = vec![];
let mut trailing_comma = false;
let mut recovered = false;
es.push(match self.parse_expr() {
Ok(es) => es,
Err(mut err) => {
- // recover from parse error in tuple list
+ // Recover from parse error in tuple list.
match self.token.kind {
token::Ident(name, false)
if name == kw::Underscore && self.look_ahead(1, |t| {
return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs);
}
token::BinOp(token::Or) | token::OrOr => {
- return self.parse_lambda_expr(attrs);
+ return self.parse_closure_expr(attrs);
}
token::OpenDelim(token::Bracket) => {
self.bump();
attrs.extend(self.parse_inner_attributes()?);
if self.eat(&token::CloseDelim(token::Bracket)) {
- // Empty vector.
+ // Empty vector
ex = ExprKind::Array(Vec::new());
} else {
- // Nonempty vector.
+ // Non-empty vector
let first_expr = self.parse_expr()?;
if self.eat(&token::Semi) {
- // Repeating array syntax: [ 0; 512 ]
+ // Repeating array syntax: `[ 0; 512 ]`
let count = AnonConst {
- id: ast::DUMMY_NODE_ID,
+ id: DUMMY_NODE_ID,
value: self.parse_expr()?,
};
self.expect(&token::CloseDelim(token::Bracket))?;
ex = ExprKind::Repeat(first_expr, count);
} else if self.eat(&token::Comma) {
- // Vector with two or more elements.
+ // Vector with two or more elements
let remaining_exprs = self.parse_seq_to_end(
&token::CloseDelim(token::Bracket),
SeqSep::trailing_allowed(token::Comma),
exprs.extend(remaining_exprs);
ex = ExprKind::Array(exprs);
} else {
- // Vector with one element.
+ // Vector with one element
self.expect(&token::CloseDelim(token::Bracket))?;
ex = ExprKind::Array(vec![first_expr]);
}
if self.token.is_path_start() {
let path = self.parse_path(PathStyle::Expr)?;
- // `!`, as an operator, is prefix, so we know this isn't that
+ // `!`, as an operator, is prefix, so we know this isn't that.
if self.eat(&token::Not) {
// MACRO INVOCATION expression
let (delim, tts) = self.expect_delimited_token_tree()?;
return self.maybe_recover_from_bad_qpath(expr, true);
}
if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
- return self.parse_lambda_expr(attrs);
+ return self.parse_closure_expr(attrs);
}
if self.eat_keyword(kw::If) {
return self.parse_if_expr(attrs);
}
if self.is_do_catch_block() {
let mut db = self.fatal("found removed `do catch` syntax");
- db.help("Following RFC #2388, the new non-placeholder syntax is `try`");
+ db.help("following RFC #2388, the new non-placeholder syntax is `try`");
return Err(db);
}
if self.is_try_block() {
return self.parse_try_block(lo, attrs);
}
- // Span::rust_2018() is somewhat expensive; don't get it repeatedly.
+ // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly.
let is_span_rust_2018 = self.token.span.rust_2018();
if is_span_rust_2018 && self.check_keyword(kw::Async) {
- return if self.is_async_block() { // check for `async {` and `async move {`
+ return if self.is_async_block() { // Check for `async {` and `async move {`.
self.parse_async_block(attrs)
} else {
- self.parse_lambda_expr(attrs)
+ self.parse_closure_expr(attrs)
};
}
if self.eat_keyword(kw::Return) {
// recovery in order to keep the error count down. Fixing the
// delimiters will possibly also fix the bare semicolon found in
// expression context. For example, silence the following error:
- // ```
- // error: expected expression, found `;`
- // --> file.rs:2:13
- // |
- // 2 | foo(bar(;
- // | ^ expected expression
- // ```
+ //
+ // error: expected expression, found `;`
+ // --> file.rs:2:13
+ // |
+ // 2 | foo(bar(;
+ // | ^ expected expression
self.bump();
return Ok(self.mk_expr(self.token.span, ExprKind::Err, ThinVec::new()));
}
attrs.extend(self.parse_inner_attributes()?);
let blk = self.parse_block_tail(lo, blk_mode)?;
- return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs));
+ Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
}
- /// Parses `move |args| expr`.
- fn parse_lambda_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+ /// Parses a closure expression (e.g., `move |args| expr`).
+ fn parse_closure_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
let movability = if self.eat_keyword(kw::Static) {
IsAsync::NotAsync
};
if asyncness.is_async() {
- // Feature gate `async ||` closures.
+ // Feature-gate `async ||` closures.
self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span);
}
self.parse_expr_res(restrictions, None)?
},
_ => {
- // If an explicit return type is given, require a
- // block to appear (RFC 968).
+ // If an explicit return type is given, require a block to appear (RFC 968).
let body_lo = self.token.span;
self.parse_block_expr(None, body_lo, BlockCheckMode::Default, ThinVec::new())?
}
attrs))
}
- /// Parse an optional `move` prefix to a closure lke construct.
+ /// Parses an optional `move` prefix to a closure lke construct.
fn parse_capture_clause(&mut self) -> CaptureBy {
if self.eat_keyword(kw::Move) {
CaptureBy::Value
}))
}
- /// Parses a parameter in a lambda header (e.g., `|arg, arg|`).
+ /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
let lo = self.token.span;
let attrs = self.parse_param_attributes()?;
self.parse_ty()?
} else {
P(Ty {
- id: ast::DUMMY_NODE_ID,
+ id: DUMMY_NODE_ID,
node: TyKind::Infer,
span: self.prev_span,
})
ty: t,
pat,
span,
- id: ast::DUMMY_NODE_ID
+ id: DUMMY_NODE_ID
})
}
Ok(self.mk_expr(lo.to(hi), ExprKind::If(cond, thn, els), attrs))
}
- /// Parse the condition of a `if`- or `while`-expression
+ /// Parses the condition of a `if` or `while` expression.
fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
/// The `let` token has already been eaten.
fn parse_let_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
let lo = self.prev_span;
- // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
- let pat = self.parse_top_pat_unpack(GateOr::No)?;
+ let pat = self.parse_top_pat(GateOr::No)?;
self.expect(&token::Eq)?;
let expr = self.with_res(
Restrictions::NO_STRUCT_LITERAL,
Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs))
}
- /// `else` token already eaten
+ /// Parses an `else { ... }` expression (`else` token already eaten).
fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
if self.eat_keyword(kw::If) {
return self.parse_if_expr(ThinVec::new());
}
}
- /// Parse a 'for' .. 'in' expression ('for' token already eaten)
+ /// Parses a `for ... in` expression (`for` token already eaten).
fn parse_for_expr(
&mut self,
opt_label: Option<Label>,
Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs))
}
- /// Parse `loop {...}`, `loop` token already eaten.
+ /// Parses `loop { ... }` (`loop` token already eaten).
fn parse_loop_expr(
&mut self,
opt_label: Option<Label>,
}
}
- // `match` token already eaten
+ /// Parses a `match ... { ... }` expression (`match` token already eaten).
fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
let match_span = self.prev_span;
let lo = self.prev_span;
crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
let attrs = self.parse_outer_attributes()?;
let lo = self.token.span;
- // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
- let pat = self.parse_top_pat_unpack(GateOr::No)?;
+ let pat = self.parse_top_pat(GateOr::No)?;
let guard = if self.eat_keyword(kw::If) {
Some(self.parse_expr()?)
} else {
Ok(ast::Arm {
attrs,
- pats: pat, // FIXME(or_patterns, Centril | dlrobertson): this should just be `pat,`.
+ pat,
guard,
body: expr,
span: lo.to(hi),
- id: ast::DUMMY_NODE_ID,
+ id: DUMMY_NODE_ID,
})
}
self.token.is_keyword(kw::Try) &&
self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
self.token.span.rust_2018() &&
- // prevent `while try {} {}`, `if try {} {} else {}`, etc.
+ // Prevent `while try {} {}`, `if try {} {} else {}`, etc.
!self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
}
attrs.extend(iattrs);
Ok(self.mk_expr(
span_lo.to(body.span),
- ExprKind::Async(capture_clause, ast::DUMMY_NODE_ID, body), attrs))
+ ExprKind::Async(capture_clause, DUMMY_NODE_ID, body), attrs))
}
fn is_async_block(&self) -> bool {
) -> Option<PResult<'a, P<Expr>>> {
let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
let certainly_not_a_block = || self.look_ahead(1, |t| t.is_ident()) && (
- // `{ ident, ` cannot start a block
+ // `{ ident, ` cannot start a block.
self.look_ahead(2, |t| t == &token::Comma) ||
self.look_ahead(2, |t| t == &token::Colon) && (
- // `{ ident: token, ` cannot start a block
+ // `{ ident: token, ` cannot start a block.
self.look_ahead(4, |t| t == &token::Comma) ||
- // `{ ident: ` cannot start a block unless it's a type ascription `ident: Type`
+ // `{ ident: ` cannot start a block unless it's a type ascription `ident: Type`.
self.look_ahead(3, |t| !t.can_begin_type())
)
);
if struct_allowed || certainly_not_a_block() {
- // This is a struct literal, but we don't can't accept them here
+ // This is a struct literal, but we don't can't accept them here.
let expr = self.parse_struct_expr(lo, path.clone(), attrs.clone());
if let (Ok(expr), false) = (&expr, struct_allowed) {
self.struct_span_err(
let mut recovery_field = None;
if let token::Ident(name, _) = self.token.kind {
if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) {
- // Use in case of error after field-looking code: `S { foo: () with a }`
+ // Use in case of error after field-looking code: `S { foo: () with a }`.
recovery_field = Some(ast::Field {
ident: Ident::new(name, self.token.span),
span: self.token.span,
expr: self.mk_expr(self.token.span, ExprKind::Err, ThinVec::new()),
is_shorthand: false,
attrs: ThinVec::new(),
- id: ast::DUMMY_NODE_ID,
+ id: DUMMY_NODE_ID,
});
}
}
match self.expect_one_of(&[token::Comma],
&[token::CloseDelim(token::Brace)]) {
Ok(_) => if let Some(f) = parsed_field.or(recovery_field) {
- // only include the field if there's no parse error for the field name
+ // Only include the field if there's no parse error for the field name.
fields.push(f);
}
Err(mut e) => {
return Ok(self.mk_expr(span, ExprKind::Struct(pth, fields, base), attrs));
}
- /// Parse ident (COLON expr)?
+ /// Parses `ident (COLON expr)?`.
fn parse_field(&mut self) -> PResult<'a, Field> {
let attrs = self.parse_outer_attributes()?;
let lo = self.token.span;
expr,
is_shorthand,
attrs: attrs.into(),
- id: ast::DUMMY_NODE_ID,
+ id: DUMMY_NODE_ID,
})
}
}
crate fn mk_expr(&self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
- P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID })
+ P(Expr { node, span, attrs, id: DUMMY_NODE_ID })
}
}