add start_stmt to handle postfix increment
This commit is contained in:
parent
7c11a53f9c
commit
dee85a391f
10 changed files with 203 additions and 38 deletions
|
@ -1259,10 +1259,9 @@ impl<'a> Parser<'a> {
|
|||
&mut self,
|
||||
operand_expr: P<Expr>,
|
||||
op_span: Span,
|
||||
prev_is_semi: bool,
|
||||
start_stmt: bool,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
let standalone =
|
||||
if prev_is_semi { IsStandalone::Standalone } else { IsStandalone::Subexpr };
|
||||
let standalone = if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr };
|
||||
let kind = IncDecRecovery { standalone, op: IncOrDec::Inc, fixity: UnaryFixity::Pre };
|
||||
self.recover_from_inc_dec(operand_expr, kind, op_span)
|
||||
}
|
||||
|
@ -1271,10 +1270,10 @@ impl<'a> Parser<'a> {
|
|||
&mut self,
|
||||
operand_expr: P<Expr>,
|
||||
op_span: Span,
|
||||
prev_is_semi: bool,
|
||||
start_stmt: bool,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
let kind = IncDecRecovery {
|
||||
standalone: if prev_is_semi { IsStandalone::Standalone } else { IsStandalone::Subexpr },
|
||||
standalone: if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr },
|
||||
op: IncOrDec::Inc,
|
||||
fixity: UnaryFixity::Post,
|
||||
};
|
||||
|
@ -1305,20 +1304,22 @@ impl<'a> Parser<'a> {
|
|||
UnaryFixity::Post => (base.span.shrink_to_lo(), op_span),
|
||||
};
|
||||
|
||||
let Ok(base_src) = self.span_to_snippet(base.span)
|
||||
else { return help_base_case(err, base) };
|
||||
match kind.standalone {
|
||||
IsStandalone::Standalone => {
|
||||
self.inc_dec_standalone_suggest(kind, spans).emit_verbose(&mut err)
|
||||
}
|
||||
IsStandalone::Subexpr => match kind.fixity {
|
||||
UnaryFixity::Pre => {
|
||||
self.prefix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
|
||||
IsStandalone::Subexpr => {
|
||||
let Ok(base_src) = self.span_to_snippet(base.span)
|
||||
else { return help_base_case(err, base) };
|
||||
match kind.fixity {
|
||||
UnaryFixity::Pre => {
|
||||
self.prefix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
|
||||
}
|
||||
UnaryFixity::Post => {
|
||||
self.postfix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
|
||||
}
|
||||
}
|
||||
UnaryFixity::Post => {
|
||||
self.postfix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ macro_rules! maybe_whole_expr {
|
|||
pub(super) enum LhsExpr {
|
||||
NotYetParsed,
|
||||
AttributesParsed(AttrWrapper),
|
||||
AlreadyParsed(P<Expr>),
|
||||
AlreadyParsed(P<Expr>, bool), // (expr, starts_statement)
|
||||
}
|
||||
|
||||
impl From<Option<AttrWrapper>> for LhsExpr {
|
||||
|
@ -101,7 +101,7 @@ impl From<P<Expr>> for LhsExpr {
|
|||
///
|
||||
/// This conversion does not allocate.
|
||||
fn from(expr: P<Expr>) -> Self {
|
||||
LhsExpr::AlreadyParsed(expr)
|
||||
LhsExpr::AlreadyParsed(expr, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,9 @@ impl<'a> Parser<'a> {
|
|||
min_prec: usize,
|
||||
lhs: LhsExpr,
|
||||
) -> PResult<'a, P<Expr>> {
|
||||
let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
|
||||
let mut starts_stmt = false;
|
||||
let mut lhs = if let LhsExpr::AlreadyParsed(expr, starts_statement) = lhs {
|
||||
starts_stmt = starts_statement;
|
||||
expr
|
||||
} else {
|
||||
let attrs = match lhs {
|
||||
|
@ -292,15 +294,7 @@ impl<'a> Parser<'a> {
|
|||
let op_span = self.prev_token.span.to(self.token.span);
|
||||
// Eat the second `+`
|
||||
self.bump();
|
||||
let prev_is_semi = {
|
||||
if let Ok(prev_code) = self.sess.source_map().span_to_prev_source(lhs.span) &&
|
||||
prev_code.trim_end().ends_with(";") {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
lhs = self.recover_from_postfix_increment(lhs, op_span, prev_is_semi)?;
|
||||
lhs = self.recover_from_postfix_increment(lhs, op_span, starts_stmt)?;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -607,14 +601,15 @@ impl<'a> Parser<'a> {
|
|||
token::BinOp(token::Plus)
|
||||
if this.look_ahead(1, |t| *t == token::BinOp(token::Plus)) =>
|
||||
{
|
||||
let prev_is_semi = this.prev_token == token::Semi;
|
||||
let starts_stmt = this.prev_token == token::Semi
|
||||
|| this.prev_token == token::CloseDelim(Delimiter::Brace);
|
||||
let pre_span = this.token.span.to(this.look_ahead(1, |t| t.span));
|
||||
// Eat both `+`s.
|
||||
this.bump();
|
||||
this.bump();
|
||||
|
||||
let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
|
||||
this.recover_from_prefix_increment(operand_expr, pre_span, prev_is_semi)
|
||||
this.recover_from_prefix_increment(operand_expr, pre_span, starts_stmt)
|
||||
}
|
||||
token::Ident(..) if this.token.is_keyword(kw::Box) => {
|
||||
make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
|
||||
|
|
|
@ -156,7 +156,7 @@ impl<'a> Parser<'a> {
|
|||
// Perform this outside of the `collect_tokens_trailing_token` closure,
|
||||
// since our outer attributes do not apply to this part of the expression
|
||||
let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
|
||||
this.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(expr))
|
||||
this.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(expr, true))
|
||||
})?;
|
||||
Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Expr(expr)))
|
||||
} else {
|
||||
|
@ -190,7 +190,7 @@ impl<'a> Parser<'a> {
|
|||
let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
|
||||
let e = self.maybe_recover_from_bad_qpath(e)?;
|
||||
let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
|
||||
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
|
||||
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e, false))?;
|
||||
StmtKind::Expr(e)
|
||||
};
|
||||
Ok(self.mk_stmt(lo.to(hi), kind))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue