Emit both subexp and standalone sugg for postfix
This solves the TODO.
This commit is contained in:
parent
7287f929b9
commit
62b8ea67b7
4 changed files with 70 additions and 31 deletions
|
@ -160,8 +160,10 @@ impl AttemptLocalParseRecovery {
|
||||||
/// C-style `i++`, `--i`, etc.
|
/// C-style `i++`, `--i`, etc.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
struct IncDecRecovery {
|
struct IncDecRecovery {
|
||||||
/// This increment/decrement is not a subexpression.
|
/// Is this increment/decrement its own statement?
|
||||||
standalone: bool,
|
///
|
||||||
|
/// This is `None` when we are unsure.
|
||||||
|
standalone: Option<bool>,
|
||||||
/// Is this an increment or decrement?
|
/// Is this an increment or decrement?
|
||||||
op: IncOrDec,
|
op: IncOrDec,
|
||||||
/// Is this pre- or postfix?
|
/// Is this pre- or postfix?
|
||||||
|
@ -1225,7 +1227,7 @@ impl<'a> Parser<'a> {
|
||||||
prev_is_semi: bool,
|
prev_is_semi: bool,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
let kind = IncDecRecovery {
|
let kind = IncDecRecovery {
|
||||||
standalone: prev_is_semi,
|
standalone: Some(prev_is_semi),
|
||||||
op: IncOrDec::Inc,
|
op: IncOrDec::Inc,
|
||||||
fixity: UnaryFixity::Pre,
|
fixity: UnaryFixity::Pre,
|
||||||
};
|
};
|
||||||
|
@ -1237,13 +1239,9 @@ impl<'a> Parser<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
operand_expr: P<Expr>,
|
operand_expr: P<Expr>,
|
||||||
op_span: Span,
|
op_span: Span,
|
||||||
prev_is_semi: bool,
|
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
let kind = IncDecRecovery {
|
let kind =
|
||||||
standalone: prev_is_semi,
|
IncDecRecovery { standalone: None, op: IncOrDec::Inc, fixity: UnaryFixity::Post };
|
||||||
op: IncOrDec::Inc,
|
|
||||||
fixity: UnaryFixity::Post,
|
|
||||||
};
|
|
||||||
|
|
||||||
self.recover_from_inc_dec(operand_expr, kind, op_span)
|
self.recover_from_inc_dec(operand_expr, kind, op_span)
|
||||||
}
|
}
|
||||||
|
@ -1272,25 +1270,44 @@ impl<'a> Parser<'a> {
|
||||||
UnaryFixity::Post => (base.span.shrink_to_lo(), op_span),
|
UnaryFixity::Post => (base.span.shrink_to_lo(), op_span),
|
||||||
};
|
};
|
||||||
|
|
||||||
if kind.standalone {
|
match kind.standalone {
|
||||||
self.inc_dec_standalone_recovery(err, kind, spans)
|
Some(true) => self.inc_dec_standalone_recovery(&mut err, kind, spans, false),
|
||||||
} else {
|
Some(false) => {
|
||||||
let Ok(base_src) = self.span_to_snippet(base.span)
|
let Ok(base_src) = self.span_to_snippet(base.span)
|
||||||
else { return help_base_case(err, base) };
|
else { return help_base_case(err, base) };
|
||||||
match kind.fixity {
|
match kind.fixity {
|
||||||
UnaryFixity::Pre => self.prefix_inc_dec_suggest(base_src, err, kind, spans),
|
UnaryFixity::Pre => {
|
||||||
UnaryFixity::Post => self.postfix_inc_dec_suggest(base_src, err, kind, spans),
|
self.prefix_inc_dec_suggest(base_src, &mut err, kind, spans)
|
||||||
|
}
|
||||||
|
UnaryFixity::Post => {
|
||||||
|
self.postfix_inc_dec_suggest(base_src, &mut err, kind, spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
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, &mut err, kind, spans)
|
||||||
|
}
|
||||||
|
UnaryFixity::Post => {
|
||||||
|
self.postfix_inc_dec_suggest(base_src, &mut err, kind, spans)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.inc_dec_standalone_recovery(&mut err, kind, spans, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_inc_dec_suggest(
|
fn prefix_inc_dec_suggest(
|
||||||
&mut self,
|
&mut self,
|
||||||
base_src: String,
|
base_src: String,
|
||||||
mut err: DiagnosticBuilder<'a>,
|
err: &mut DiagnosticBuilder<'a>,
|
||||||
kind: IncDecRecovery,
|
kind: IncDecRecovery,
|
||||||
(pre_span, post_span): (Span, Span),
|
(pre_span, post_span): (Span, Span),
|
||||||
) -> PResult<'a, P<Expr>> {
|
) {
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
&format!("use `{}= 1` instead", kind.op.chr()),
|
&format!("use `{}= 1` instead", kind.op.chr()),
|
||||||
vec![
|
vec![
|
||||||
|
@ -1299,16 +1316,15 @@ impl<'a> Parser<'a> {
|
||||||
],
|
],
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
Err(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn postfix_inc_dec_suggest(
|
fn postfix_inc_dec_suggest(
|
||||||
&mut self,
|
&mut self,
|
||||||
base_src: String,
|
base_src: String,
|
||||||
mut err: DiagnosticBuilder<'a>,
|
err: &mut DiagnosticBuilder<'a>,
|
||||||
kind: IncDecRecovery,
|
kind: IncDecRecovery,
|
||||||
(pre_span, post_span): (Span, Span),
|
(pre_span, post_span): (Span, Span),
|
||||||
) -> PResult<'a, P<Expr>> {
|
) {
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
&format!("use `{}= 1` instead", kind.op.chr()),
|
&format!("use `{}= 1` instead", kind.op.chr()),
|
||||||
vec![
|
vec![
|
||||||
|
@ -1317,21 +1333,31 @@ impl<'a> Parser<'a> {
|
||||||
],
|
],
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
Err(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inc_dec_standalone_recovery(
|
fn inc_dec_standalone_recovery(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut err: DiagnosticBuilder<'a>,
|
err: &mut DiagnosticBuilder<'a>,
|
||||||
kind: IncDecRecovery,
|
kind: IncDecRecovery,
|
||||||
(pre_span, post_span): (Span, Span),
|
(pre_span, post_span): (Span, Span),
|
||||||
) -> PResult<'a, P<Expr>> {
|
maybe_not_standalone: bool,
|
||||||
|
) {
|
||||||
|
let msg = if maybe_not_standalone {
|
||||||
|
"or, if you don't need to use it as an expression, change it to this".to_owned()
|
||||||
|
} else {
|
||||||
|
format!("use `{}= 1` instead", kind.op.chr())
|
||||||
|
};
|
||||||
|
let applicability = if maybe_not_standalone {
|
||||||
|
// FIXME: Unspecified isn't right, but it's the least wrong option
|
||||||
|
Applicability::Unspecified
|
||||||
|
} else {
|
||||||
|
Applicability::MachineApplicable
|
||||||
|
};
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
&format!("use `{}= 1` instead", kind.op.chr()),
|
&msg,
|
||||||
vec![(pre_span, String::new()), (post_span, format!(" {}= 1", kind.op.chr()))],
|
vec![(pre_span, String::new()), (post_span, format!(" {}= 1", kind.op.chr()))],
|
||||||
Applicability::MachineApplicable,
|
applicability,
|
||||||
);
|
);
|
||||||
Err(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to recover from associated item paths like `[T]::AssocItem` / `(T, U)::AssocItem`.
|
/// Tries to recover from associated item paths like `[T]::AssocItem` / `(T, U)::AssocItem`.
|
||||||
|
|
|
@ -273,9 +273,7 @@ impl<'a> Parser<'a> {
|
||||||
let op_span = self.prev_token.span.to(self.token.span);
|
let op_span = self.prev_token.span.to(self.token.span);
|
||||||
// Eat the second `+`
|
// Eat the second `+`
|
||||||
self.bump();
|
self.bump();
|
||||||
// TODO: implement
|
lhs = self.maybe_recover_from_postfix_increment(lhs, op_span)?;
|
||||||
let start_is_semi = false;
|
|
||||||
lhs = self.maybe_recover_from_postfix_increment(lhs, op_span, start_is_semi)?;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,11 @@ help: use `+= 1` instead
|
||||||
|
|
|
|
||||||
LL | { let tmp = i; i += 1; tmp };
|
LL | { let tmp = i; i += 1; tmp };
|
||||||
| +++++++++++ ~~~~~~~~~~~~~~~
|
| +++++++++++ ~~~~~~~~~~~~~~~
|
||||||
|
help: or, if you don't need to use it as an expression, change it to this
|
||||||
|
|
|
||||||
|
LL - i++;
|
||||||
|
LL + i += 1;
|
||||||
|
|
|
||||||
|
|
||||||
error: Rust has no postfix increment operator
|
error: Rust has no postfix increment operator
|
||||||
--> $DIR/increment-autofix.rs:11:12
|
--> $DIR/increment-autofix.rs:11:12
|
||||||
|
@ -19,6 +24,11 @@ help: use `+= 1` instead
|
||||||
|
|
|
|
||||||
LL | while { let tmp = i; i += 1; tmp } < 5 {
|
LL | while { let tmp = i; i += 1; tmp } < 5 {
|
||||||
| +++++++++++ ~~~~~~~~~~~~~~~
|
| +++++++++++ ~~~~~~~~~~~~~~~
|
||||||
|
help: or, if you don't need to use it as an expression, change it to this
|
||||||
|
|
|
||||||
|
LL - while i++ < 5 {
|
||||||
|
LL + while i += 1 < 5 {
|
||||||
|
|
|
||||||
|
|
||||||
error: Rust has no prefix increment operator
|
error: Rust has no prefix increment operator
|
||||||
--> $DIR/increment-autofix.rs:19:5
|
--> $DIR/increment-autofix.rs:19:5
|
||||||
|
|
|
@ -8,6 +8,11 @@ help: use `+= 1` instead
|
||||||
|
|
|
|
||||||
LL | { let tmp = foo.bar.qux; foo.bar.qux += 1; tmp };
|
LL | { let tmp = foo.bar.qux; foo.bar.qux += 1; tmp };
|
||||||
| +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~
|
| +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
help: or, if you don't need to use it as an expression, change it to this
|
||||||
|
|
|
||||||
|
LL - foo.bar.qux++;
|
||||||
|
LL + foo.bar.qux += 1;
|
||||||
|
|
|
||||||
|
|
||||||
error: Rust has no prefix increment operator
|
error: Rust has no prefix increment operator
|
||||||
--> $DIR/increment-notfixed.rs:18:5
|
--> $DIR/increment-notfixed.rs:18:5
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue