Skip to content

Commit 62b8ea6

Browse files
committed
Emit both subexp and standalone sugg for postfix
This solves the TODO.
1 parent 7287f92 commit 62b8ea6

File tree

4 files changed

+70
-31
lines changed

4 files changed

+70
-31
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,10 @@ impl AttemptLocalParseRecovery {
160160
/// C-style `i++`, `--i`, etc.
161161
#[derive(Debug, Copy, Clone)]
162162
struct IncDecRecovery {
163-
/// This increment/decrement is not a subexpression.
164-
standalone: bool,
163+
/// Is this increment/decrement its own statement?
164+
///
165+
/// This is `None` when we are unsure.
166+
standalone: Option<bool>,
165167
/// Is this an increment or decrement?
166168
op: IncOrDec,
167169
/// Is this pre- or postfix?
@@ -1225,7 +1227,7 @@ impl<'a> Parser<'a> {
12251227
prev_is_semi: bool,
12261228
) -> PResult<'a, P<Expr>> {
12271229
let kind = IncDecRecovery {
1228-
standalone: prev_is_semi,
1230+
standalone: Some(prev_is_semi),
12291231
op: IncOrDec::Inc,
12301232
fixity: UnaryFixity::Pre,
12311233
};
@@ -1237,13 +1239,9 @@ impl<'a> Parser<'a> {
12371239
&mut self,
12381240
operand_expr: P<Expr>,
12391241
op_span: Span,
1240-
prev_is_semi: bool,
12411242
) -> PResult<'a, P<Expr>> {
1242-
let kind = IncDecRecovery {
1243-
standalone: prev_is_semi,
1244-
op: IncOrDec::Inc,
1245-
fixity: UnaryFixity::Post,
1246-
};
1243+
let kind =
1244+
IncDecRecovery { standalone: None, op: IncOrDec::Inc, fixity: UnaryFixity::Post };
12471245

12481246
self.recover_from_inc_dec(operand_expr, kind, op_span)
12491247
}
@@ -1272,25 +1270,44 @@ impl<'a> Parser<'a> {
12721270
UnaryFixity::Post => (base.span.shrink_to_lo(), op_span),
12731271
};
12741272

1275-
if kind.standalone {
1276-
self.inc_dec_standalone_recovery(err, kind, spans)
1277-
} else {
1278-
let Ok(base_src) = self.span_to_snippet(base.span)
1279-
else { return help_base_case(err, base) };
1280-
match kind.fixity {
1281-
UnaryFixity::Pre => self.prefix_inc_dec_suggest(base_src, err, kind, spans),
1282-
UnaryFixity::Post => self.postfix_inc_dec_suggest(base_src, err, kind, spans),
1273+
match kind.standalone {
1274+
Some(true) => self.inc_dec_standalone_recovery(&mut err, kind, spans, false),
1275+
Some(false) => {
1276+
let Ok(base_src) = self.span_to_snippet(base.span)
1277+
else { return help_base_case(err, base) };
1278+
match kind.fixity {
1279+
UnaryFixity::Pre => {
1280+
self.prefix_inc_dec_suggest(base_src, &mut err, kind, spans)
1281+
}
1282+
UnaryFixity::Post => {
1283+
self.postfix_inc_dec_suggest(base_src, &mut err, kind, spans)
1284+
}
1285+
}
1286+
}
1287+
None => {
1288+
let Ok(base_src) = self.span_to_snippet(base.span)
1289+
else { return help_base_case(err, base) };
1290+
match kind.fixity {
1291+
UnaryFixity::Pre => {
1292+
self.prefix_inc_dec_suggest(base_src, &mut err, kind, spans)
1293+
}
1294+
UnaryFixity::Post => {
1295+
self.postfix_inc_dec_suggest(base_src, &mut err, kind, spans)
1296+
}
1297+
}
1298+
self.inc_dec_standalone_recovery(&mut err, kind, spans, true)
12831299
}
12841300
}
1301+
Err(err)
12851302
}
12861303

12871304
fn prefix_inc_dec_suggest(
12881305
&mut self,
12891306
base_src: String,
1290-
mut err: DiagnosticBuilder<'a>,
1307+
err: &mut DiagnosticBuilder<'a>,
12911308
kind: IncDecRecovery,
12921309
(pre_span, post_span): (Span, Span),
1293-
) -> PResult<'a, P<Expr>> {
1310+
) {
12941311
err.multipart_suggestion(
12951312
&format!("use `{}= 1` instead", kind.op.chr()),
12961313
vec![
@@ -1299,16 +1316,15 @@ impl<'a> Parser<'a> {
12991316
],
13001317
Applicability::MachineApplicable,
13011318
);
1302-
Err(err)
13031319
}
13041320

13051321
fn postfix_inc_dec_suggest(
13061322
&mut self,
13071323
base_src: String,
1308-
mut err: DiagnosticBuilder<'a>,
1324+
err: &mut DiagnosticBuilder<'a>,
13091325
kind: IncDecRecovery,
13101326
(pre_span, post_span): (Span, Span),
1311-
) -> PResult<'a, P<Expr>> {
1327+
) {
13121328
err.multipart_suggestion(
13131329
&format!("use `{}= 1` instead", kind.op.chr()),
13141330
vec![
@@ -1317,21 +1333,31 @@ impl<'a> Parser<'a> {
13171333
],
13181334
Applicability::MachineApplicable,
13191335
);
1320-
Err(err)
13211336
}
13221337

13231338
fn inc_dec_standalone_recovery(
13241339
&mut self,
1325-
mut err: DiagnosticBuilder<'a>,
1340+
err: &mut DiagnosticBuilder<'a>,
13261341
kind: IncDecRecovery,
13271342
(pre_span, post_span): (Span, Span),
1328-
) -> PResult<'a, P<Expr>> {
1343+
maybe_not_standalone: bool,
1344+
) {
1345+
let msg = if maybe_not_standalone {
1346+
"or, if you don't need to use it as an expression, change it to this".to_owned()
1347+
} else {
1348+
format!("use `{}= 1` instead", kind.op.chr())
1349+
};
1350+
let applicability = if maybe_not_standalone {
1351+
// FIXME: Unspecified isn't right, but it's the least wrong option
1352+
Applicability::Unspecified
1353+
} else {
1354+
Applicability::MachineApplicable
1355+
};
13291356
err.multipart_suggestion(
1330-
&format!("use `{}= 1` instead", kind.op.chr()),
1357+
&msg,
13311358
vec![(pre_span, String::new()), (post_span, format!(" {}= 1", kind.op.chr()))],
1332-
Applicability::MachineApplicable,
1359+
applicability,
13331360
);
1334-
Err(err)
13351361
}
13361362

13371363
/// Tries to recover from associated item paths like `[T]::AssocItem` / `(T, U)::AssocItem`.

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,7 @@ impl<'a> Parser<'a> {
273273
let op_span = self.prev_token.span.to(self.token.span);
274274
// Eat the second `+`
275275
self.bump();
276-
// TODO: implement
277-
let start_is_semi = false;
278-
lhs = self.maybe_recover_from_postfix_increment(lhs, op_span, start_is_semi)?;
276+
lhs = self.maybe_recover_from_postfix_increment(lhs, op_span)?;
279277
continue;
280278
}
281279

src/test/ui/parser/increment-autofix.stderr

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ help: use `+= 1` instead
88
|
99
LL | { let tmp = i; i += 1; tmp };
1010
| +++++++++++ ~~~~~~~~~~~~~~~
11+
help: or, if you don't need to use it as an expression, change it to this
12+
|
13+
LL - i++;
14+
LL + i += 1;
15+
|
1116

1217
error: Rust has no postfix increment operator
1318
--> $DIR/increment-autofix.rs:11:12
@@ -19,6 +24,11 @@ help: use `+= 1` instead
1924
|
2025
LL | while { let tmp = i; i += 1; tmp } < 5 {
2126
| +++++++++++ ~~~~~~~~~~~~~~~
27+
help: or, if you don't need to use it as an expression, change it to this
28+
|
29+
LL - while i++ < 5 {
30+
LL + while i += 1 < 5 {
31+
|
2232

2333
error: Rust has no prefix increment operator
2434
--> $DIR/increment-autofix.rs:19:5

src/test/ui/parser/increment-notfixed.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ help: use `+= 1` instead
88
|
99
LL | { let tmp = foo.bar.qux; foo.bar.qux += 1; tmp };
1010
| +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~
11+
help: or, if you don't need to use it as an expression, change it to this
12+
|
13+
LL - foo.bar.qux++;
14+
LL + foo.bar.qux += 1;
15+
|
1116

1217
error: Rust has no prefix increment operator
1318
--> $DIR/increment-notfixed.rs:18:5

0 commit comments

Comments
 (0)