From 5d9cd4b851f121d0bc84cab474d6c536aba207df Mon Sep 17 00:00:00 2001 From: Camelid Date: Thu, 25 Mar 2021 21:04:03 -0700 Subject: [PATCH] Suggest `i += 1` when we see `i++` or `++i` --- .../rustc_parse/src/parser/diagnostics.rs | 43 +++++++++++++++ src/test/ui/parser/increment.rs | 27 ++++++++++ src/test/ui/parser/increment.stderr | 52 +++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 src/test/ui/parser/increment.rs create mode 100644 src/test/ui/parser/increment.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index b5b628a3f55..0361f7063fc 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1882,6 +1882,49 @@ impl<'a> Parser<'a> { self.sess.expr_parentheses_needed(&mut err, *sp); } err.span_label(span, "expected expression"); + if self.prev_token.kind == TokenKind::BinOp(token::Plus) + && self.token.kind == TokenKind::BinOp(token::Plus) + && self.look_ahead(1, |t| !t.is_lit()) + { + let span = self.prev_token.span.to(self.token.span); + err.note("Rust has no dedicated increment operator"); + err.span_suggestion_verbose( + span, + "try using `+= 1` instead", + " += 1".into(), + Applicability::Unspecified, + ); + } else if self.token.kind == TokenKind::BinOp(token::Plus) + && self.look_ahead(1, |t| t.kind == TokenKind::BinOp(token::Plus)) + && self.look_ahead(2, |t| !t.is_lit()) + { + let target_span = self.look_ahead(2, |t| t.span); + let left_brace_span = target_span.shrink_to_lo(); + let pre_span = self.token.span.to(self.look_ahead(1, |t| t.span)); + let post_span = target_span.shrink_to_hi(); + + err.note("Rust has no dedicated increment operator"); + + if self.prev_token.kind == TokenKind::Semi { + err.multipart_suggestion( + "try using `+= 1` instead", + vec![(pre_span, String::new()), (post_span, " += 1".into())], + Applicability::MachineApplicable, + ); + } else if let Ok(target_snippet) = self.span_to_snippet(target_span) { + err.multipart_suggestion( + "try using `+= 1` instead", + vec![ + (left_brace_span, "{ ".to_string()), + (pre_span, String::new()), + (post_span, format!(" += 1; {} }}", target_snippet)), + ], + Applicability::MachineApplicable, + ); + } else { + err.span_help(pre_span.to(target_span), "try using `+= 1` instead"); + } + } err } diff --git a/src/test/ui/parser/increment.rs b/src/test/ui/parser/increment.rs new file mode 100644 index 00000000000..77a94b65f1f --- /dev/null +++ b/src/test/ui/parser/increment.rs @@ -0,0 +1,27 @@ +fn post_regular() { + let i = 0; + i++; //~ ERROR +} + +fn post_while() { + let i = 0; + while i++ < 5 { + //~^ ERROR + println!("{}", i); + } +} + +fn pre_regular() { + let i = 0; + ++i; //~ ERROR +} + +fn pre_while() { + let i = 0; + while ++i < 5 { + //~^ ERROR + println!("{}", i); + } +} + +fn main() {} diff --git a/src/test/ui/parser/increment.stderr b/src/test/ui/parser/increment.stderr new file mode 100644 index 00000000000..667956cdd7d --- /dev/null +++ b/src/test/ui/parser/increment.stderr @@ -0,0 +1,52 @@ +error: expected expression, found `+` + --> $DIR/increment.rs:3:7 + | +LL | i++; + | ^ expected expression + | + = note: Rust has no dedicated increment operator +help: try using `+= 1` instead + | +LL | i += 1; + | ~~~~ + +error: expected expression, found `+` + --> $DIR/increment.rs:8:13 + | +LL | while i++ < 5 { + | ^ expected expression + | + = note: Rust has no dedicated increment operator +help: try using `+= 1` instead + | +LL | while i += 1 < 5 { + | ~~~~ + +error: expected expression, found `+` + --> $DIR/increment.rs:16:5 + | +LL | ++i; + | ^ expected expression + | + = note: Rust has no dedicated increment operator +help: try using `+= 1` instead + | +LL - ++i; +LL + i += 1; + | + +error: expected expression, found `+` + --> $DIR/increment.rs:21:11 + | +LL | while ++i < 5 { + | ^ expected expression + | + = note: Rust has no dedicated increment operator +help: try using `+= 1` instead + | +LL - while ++i < 5 { +LL + while { i += 1; i } < 5 { + | + +error: aborting due to 4 previous errors +