From 7c11a53f9ccb4040995b9e054b093a47fef29cc1 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 25 Nov 2022 17:11:47 +0800 Subject: fix #104867, Properly handle postfix inc/dec in standalone and subexpr scenarios --- compiler/rustc_parse/src/parser/diagnostics.rs | 57 ++++++++------------------ compiler/rustc_parse/src/parser/expr.rs | 10 ++++- 2 files changed, 25 insertions(+), 42 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 3f5baf343c9..eba0f22f37f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -159,8 +159,6 @@ enum IsStandalone { Standalone, /// It's a subexpression, i.e., *not* standalone. Subexpr, - /// It's maybe standalone; we're not sure. - Maybe, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -213,14 +211,8 @@ impl MultiSugg { err.multipart_suggestion(&self.msg, self.patches, self.applicability); } - /// Overrides individual messages and applicabilities. - fn emit_many( - err: &mut Diagnostic, - msg: &str, - applicability: Applicability, - suggestions: impl Iterator, - ) { - err.multipart_suggestions(msg, suggestions.map(|s| s.patches), applicability); + fn emit_verbose(self, err: &mut Diagnostic) { + err.multipart_suggestion_verbose(&self.msg, self.patches, self.applicability); } } @@ -1272,7 +1264,6 @@ impl<'a> Parser<'a> { let standalone = if prev_is_semi { 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) } @@ -1280,13 +1271,13 @@ impl<'a> Parser<'a> { &mut self, operand_expr: P, op_span: Span, + prev_is_semi: bool, ) -> PResult<'a, P> { let kind = IncDecRecovery { - standalone: IsStandalone::Maybe, + standalone: if prev_is_semi { IsStandalone::Standalone } else { IsStandalone::Subexpr }, op: IncOrDec::Inc, fixity: UnaryFixity::Post, }; - self.recover_from_inc_dec(operand_expr, kind, op_span) } @@ -1314,35 +1305,20 @@ 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(&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) - } - } - } - IsStandalone::Maybe => { - let Ok(base_src) = self.span_to_snippet(base.span) - else { return help_base_case(err, base) }; - let sugg1 = match kind.fixity { - UnaryFixity::Pre => self.prefix_inc_dec_suggest(base_src, kind, spans), - UnaryFixity::Post => self.postfix_inc_dec_suggest(base_src, kind, spans), - }; - let sugg2 = self.inc_dec_standalone_suggest(kind, spans); - MultiSugg::emit_many( - &mut err, - "use `+= 1` instead", - Applicability::Unspecified, - [sugg1, sugg2].into_iter(), - ) + 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) + } + UnaryFixity::Post => { + self.postfix_inc_dec_suggest(base_src, kind, spans).emit(&mut err) + } + }, } Err(err) } @@ -1392,7 +1368,6 @@ impl<'a> Parser<'a> { } patches.push((post_span, format!(" {}= 1", kind.op.chr()))); - MultiSugg { msg: format!("use `{}= 1` instead", kind.op.chr()), patches, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 9f2267efb82..b98372d0f28 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -292,7 +292,15 @@ impl<'a> Parser<'a> { let op_span = self.prev_token.span.to(self.token.span); // Eat the second `+` self.bump(); - lhs = self.recover_from_postfix_increment(lhs, op_span)?; + 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)?; continue; } -- cgit 1.4.1-3-g733a5 From dee85a391f091f314a24fb5a090f2e528f4eb81c Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 26 Nov 2022 05:33:13 +0800 Subject: add start_stmt to handle postfix increment --- compiler/rustc_parse/src/parser/diagnostics.rs | 29 ++++---- compiler/rustc_parse/src/parser/expr.rs | 23 +++--- compiler/rustc_parse/src/parser/stmt.rs | 4 +- src/test/ui/parser/increment-autofix-2.fixed | 63 +++++++++++++++++ src/test/ui/parser/increment-autofix-2.rs | 63 +++++++++++++++++ src/test/ui/parser/increment-autofix-2.stderr | 84 ++++++++++++++++++++++ src/test/ui/parser/increment-notfixed.fixed | 63 ----------------- src/test/ui/parser/increment-notfixed.rs | 63 ----------------- src/test/ui/parser/increment-notfixed.stderr | 84 ---------------------- src/test/ui/parser/issue-104867-inc-dec-2.rs | 41 +++++++++++ src/test/ui/parser/issue-104867-inc-dec-2.stderr | 90 ++++++++++++++++++++++++ src/test/ui/parser/issue-104867-inc-dec.rs | 15 ++++ src/test/ui/parser/issue-104867-inc-dec.stderr | 25 ++++++- 13 files changed, 406 insertions(+), 241 deletions(-) create mode 100644 src/test/ui/parser/increment-autofix-2.fixed create mode 100644 src/test/ui/parser/increment-autofix-2.rs create mode 100644 src/test/ui/parser/increment-autofix-2.stderr delete mode 100644 src/test/ui/parser/increment-notfixed.fixed delete mode 100644 src/test/ui/parser/increment-notfixed.rs delete mode 100644 src/test/ui/parser/increment-notfixed.stderr create mode 100644 src/test/ui/parser/issue-104867-inc-dec-2.rs create mode 100644 src/test/ui/parser/issue-104867-inc-dec-2.stderr (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index eba0f22f37f..f8c6ff994c4 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1259,10 +1259,9 @@ impl<'a> Parser<'a> { &mut self, operand_expr: P, op_span: Span, - prev_is_semi: bool, + start_stmt: bool, ) -> PResult<'a, P> { - 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, op_span: Span, - prev_is_semi: bool, + start_stmt: bool, ) -> PResult<'a, P> { 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) - } - UnaryFixity::Post => { - self.postfix_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) + } } - }, + } } Err(err) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b98372d0f28..36fe328cb19 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -83,7 +83,7 @@ macro_rules! maybe_whole_expr { pub(super) enum LhsExpr { NotYetParsed, AttributesParsed(AttrWrapper), - AlreadyParsed(P), + AlreadyParsed(P, bool), // (expr, starts_statement) } impl From> for LhsExpr { @@ -101,7 +101,7 @@ impl From> for LhsExpr { /// /// This conversion does not allocate. fn from(expr: P) -> Self { - LhsExpr::AlreadyParsed(expr) + LhsExpr::AlreadyParsed(expr, false) } } @@ -173,7 +173,9 @@ impl<'a> Parser<'a> { min_prec: usize, lhs: LhsExpr, ) -> PResult<'a, P> { - 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)) diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 1b56cd72db0..53aa0315151 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -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)) diff --git a/src/test/ui/parser/increment-autofix-2.fixed b/src/test/ui/parser/increment-autofix-2.fixed new file mode 100644 index 00000000000..580ebaf5dbb --- /dev/null +++ b/src/test/ui/parser/increment-autofix-2.fixed @@ -0,0 +1,63 @@ +// run-rustfix + +struct Foo { + bar: Bar, +} + +struct Bar { + qux: i32, +} + +pub fn post_regular() { + let mut i = 0; + i += 1; //~ ERROR Rust has no postfix increment operator + println!("{}", i); +} + +pub fn post_while() { + let mut i = 0; + while { let tmp = i; i += 1; tmp } < 5 { + //~^ ERROR Rust has no postfix increment operator + println!("{}", i); + } +} + +pub fn post_regular_tmp() { + let mut tmp = 0; + tmp += 1; //~ ERROR Rust has no postfix increment operator + println!("{}", tmp); +} + +pub fn post_while_tmp() { + let mut tmp = 0; + while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 { + //~^ ERROR Rust has no postfix increment operator + println!("{}", tmp); + } +} + +pub fn post_field() { + let mut foo = Foo { bar: Bar { qux: 0 } }; + foo.bar.qux += 1; + //~^ ERROR Rust has no postfix increment operator + println!("{}", foo.bar.qux); +} + +pub fn post_field_tmp() { + struct S { + tmp: i32 + } + let mut s = S { tmp: 0 }; + s.tmp += 1; + //~^ ERROR Rust has no postfix increment operator + println!("{}", s.tmp); +} + +pub fn pre_field() { + let mut foo = Foo { bar: Bar { qux: 0 } }; + foo.bar.qux += 1; + //~^ ERROR Rust has no prefix increment operator + println!("{}", foo.bar.qux); +} + +fn main() {} diff --git a/src/test/ui/parser/increment-autofix-2.rs b/src/test/ui/parser/increment-autofix-2.rs new file mode 100644 index 00000000000..ebe5fa6ca1e --- /dev/null +++ b/src/test/ui/parser/increment-autofix-2.rs @@ -0,0 +1,63 @@ +// run-rustfix + +struct Foo { + bar: Bar, +} + +struct Bar { + qux: i32, +} + +pub fn post_regular() { + let mut i = 0; + i++; //~ ERROR Rust has no postfix increment operator + println!("{}", i); +} + +pub fn post_while() { + let mut i = 0; + while i++ < 5 { + //~^ ERROR Rust has no postfix increment operator + println!("{}", i); + } +} + +pub fn post_regular_tmp() { + let mut tmp = 0; + tmp++; //~ ERROR Rust has no postfix increment operator + println!("{}", tmp); +} + +pub fn post_while_tmp() { + let mut tmp = 0; + while tmp++ < 5 { + //~^ ERROR Rust has no postfix increment operator + println!("{}", tmp); + } +} + +pub fn post_field() { + let mut foo = Foo { bar: Bar { qux: 0 } }; + foo.bar.qux++; + //~^ ERROR Rust has no postfix increment operator + println!("{}", foo.bar.qux); +} + +pub fn post_field_tmp() { + struct S { + tmp: i32 + } + let mut s = S { tmp: 0 }; + s.tmp++; + //~^ ERROR Rust has no postfix increment operator + println!("{}", s.tmp); +} + +pub fn pre_field() { + let mut foo = Foo { bar: Bar { qux: 0 } }; + ++foo.bar.qux; + //~^ ERROR Rust has no prefix increment operator + println!("{}", foo.bar.qux); +} + +fn main() {} diff --git a/src/test/ui/parser/increment-autofix-2.stderr b/src/test/ui/parser/increment-autofix-2.stderr new file mode 100644 index 00000000000..11e985480d6 --- /dev/null +++ b/src/test/ui/parser/increment-autofix-2.stderr @@ -0,0 +1,84 @@ +error: Rust has no postfix increment operator + --> $DIR/increment-autofix-2.rs:13:6 + | +LL | i++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | i += 1; + | ~~~~ + +error: Rust has no postfix increment operator + --> $DIR/increment-autofix-2.rs:19:12 + | +LL | while i++ < 5 { + | ----- ^^ not a valid postfix operator + | | + | while parsing the condition of this `while` expression + | +help: use `+= 1` instead + | +LL | while { let tmp = i; i += 1; tmp } < 5 { + | +++++++++++ ~~~~~~~~~~~~~~~ + +error: Rust has no postfix increment operator + --> $DIR/increment-autofix-2.rs:27:8 + | +LL | tmp++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | tmp += 1; + | ~~~~ + +error: Rust has no postfix increment operator + --> $DIR/increment-autofix-2.rs:33:14 + | +LL | while tmp++ < 5 { + | ----- ^^ not a valid postfix operator + | | + | while parsing the condition of this `while` expression + | +help: use `+= 1` instead + | +LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 { + | ++++++++++++ ~~~~~~~~~~~~~~~~~~ + +error: Rust has no postfix increment operator + --> $DIR/increment-autofix-2.rs:41:16 + | +LL | foo.bar.qux++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | foo.bar.qux += 1; + | ~~~~ + +error: Rust has no postfix increment operator + --> $DIR/increment-autofix-2.rs:51:10 + | +LL | s.tmp++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | s.tmp += 1; + | ~~~~ + +error: Rust has no prefix increment operator + --> $DIR/increment-autofix-2.rs:58:5 + | +LL | ++foo.bar.qux; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL - ++foo.bar.qux; +LL + foo.bar.qux += 1; + | + +error: aborting due to 7 previous errors + diff --git a/src/test/ui/parser/increment-notfixed.fixed b/src/test/ui/parser/increment-notfixed.fixed deleted file mode 100644 index 580ebaf5dbb..00000000000 --- a/src/test/ui/parser/increment-notfixed.fixed +++ /dev/null @@ -1,63 +0,0 @@ -// run-rustfix - -struct Foo { - bar: Bar, -} - -struct Bar { - qux: i32, -} - -pub fn post_regular() { - let mut i = 0; - i += 1; //~ ERROR Rust has no postfix increment operator - println!("{}", i); -} - -pub fn post_while() { - let mut i = 0; - while { let tmp = i; i += 1; tmp } < 5 { - //~^ ERROR Rust has no postfix increment operator - println!("{}", i); - } -} - -pub fn post_regular_tmp() { - let mut tmp = 0; - tmp += 1; //~ ERROR Rust has no postfix increment operator - println!("{}", tmp); -} - -pub fn post_while_tmp() { - let mut tmp = 0; - while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 { - //~^ ERROR Rust has no postfix increment operator - println!("{}", tmp); - } -} - -pub fn post_field() { - let mut foo = Foo { bar: Bar { qux: 0 } }; - foo.bar.qux += 1; - //~^ ERROR Rust has no postfix increment operator - println!("{}", foo.bar.qux); -} - -pub fn post_field_tmp() { - struct S { - tmp: i32 - } - let mut s = S { tmp: 0 }; - s.tmp += 1; - //~^ ERROR Rust has no postfix increment operator - println!("{}", s.tmp); -} - -pub fn pre_field() { - let mut foo = Foo { bar: Bar { qux: 0 } }; - foo.bar.qux += 1; - //~^ ERROR Rust has no prefix increment operator - println!("{}", foo.bar.qux); -} - -fn main() {} diff --git a/src/test/ui/parser/increment-notfixed.rs b/src/test/ui/parser/increment-notfixed.rs deleted file mode 100644 index ebe5fa6ca1e..00000000000 --- a/src/test/ui/parser/increment-notfixed.rs +++ /dev/null @@ -1,63 +0,0 @@ -// run-rustfix - -struct Foo { - bar: Bar, -} - -struct Bar { - qux: i32, -} - -pub fn post_regular() { - let mut i = 0; - i++; //~ ERROR Rust has no postfix increment operator - println!("{}", i); -} - -pub fn post_while() { - let mut i = 0; - while i++ < 5 { - //~^ ERROR Rust has no postfix increment operator - println!("{}", i); - } -} - -pub fn post_regular_tmp() { - let mut tmp = 0; - tmp++; //~ ERROR Rust has no postfix increment operator - println!("{}", tmp); -} - -pub fn post_while_tmp() { - let mut tmp = 0; - while tmp++ < 5 { - //~^ ERROR Rust has no postfix increment operator - println!("{}", tmp); - } -} - -pub fn post_field() { - let mut foo = Foo { bar: Bar { qux: 0 } }; - foo.bar.qux++; - //~^ ERROR Rust has no postfix increment operator - println!("{}", foo.bar.qux); -} - -pub fn post_field_tmp() { - struct S { - tmp: i32 - } - let mut s = S { tmp: 0 }; - s.tmp++; - //~^ ERROR Rust has no postfix increment operator - println!("{}", s.tmp); -} - -pub fn pre_field() { - let mut foo = Foo { bar: Bar { qux: 0 } }; - ++foo.bar.qux; - //~^ ERROR Rust has no prefix increment operator - println!("{}", foo.bar.qux); -} - -fn main() {} diff --git a/src/test/ui/parser/increment-notfixed.stderr b/src/test/ui/parser/increment-notfixed.stderr deleted file mode 100644 index ffee8b64637..00000000000 --- a/src/test/ui/parser/increment-notfixed.stderr +++ /dev/null @@ -1,84 +0,0 @@ -error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:13:6 - | -LL | i++; - | ^^ not a valid postfix operator - | -help: use `+= 1` instead - | -LL | i += 1; - | ~~~~ - -error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:19:12 - | -LL | while i++ < 5 { - | ----- ^^ not a valid postfix operator - | | - | while parsing the condition of this `while` expression - | -help: use `+= 1` instead - | -LL | while { let tmp = i; i += 1; tmp } < 5 { - | +++++++++++ ~~~~~~~~~~~~~~~ - -error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:27:8 - | -LL | tmp++; - | ^^ not a valid postfix operator - | -help: use `+= 1` instead - | -LL | tmp += 1; - | ~~~~ - -error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:33:14 - | -LL | while tmp++ < 5 { - | ----- ^^ not a valid postfix operator - | | - | while parsing the condition of this `while` expression - | -help: use `+= 1` instead - | -LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 { - | ++++++++++++ ~~~~~~~~~~~~~~~~~~ - -error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:41:16 - | -LL | foo.bar.qux++; - | ^^ not a valid postfix operator - | -help: use `+= 1` instead - | -LL | foo.bar.qux += 1; - | ~~~~ - -error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:51:10 - | -LL | s.tmp++; - | ^^ not a valid postfix operator - | -help: use `+= 1` instead - | -LL | s.tmp += 1; - | ~~~~ - -error: Rust has no prefix increment operator - --> $DIR/increment-notfixed.rs:58:5 - | -LL | ++foo.bar.qux; - | ^^ not a valid prefix operator - | -help: use `+= 1` instead - | -LL - ++foo.bar.qux; -LL + foo.bar.qux += 1; - | - -error: aborting due to 7 previous errors - diff --git a/src/test/ui/parser/issue-104867-inc-dec-2.rs b/src/test/ui/parser/issue-104867-inc-dec-2.rs new file mode 100644 index 00000000000..e64dfbcdc28 --- /dev/null +++ b/src/test/ui/parser/issue-104867-inc-dec-2.rs @@ -0,0 +1,41 @@ +fn test1() { + let mut i = 0; + let _ = i + ++i; //~ ERROR Rust has no prefix increment operator +} + +fn test2() { + let mut i = 0; + let _ = ++i + i; //~ ERROR Rust has no prefix increment operator +} + +fn test3() { + let mut i = 0; + let _ = ++i + ++i; //~ ERROR Rust has no prefix increment operator +} + +fn test4() { + let mut i = 0; + let _ = i + i++; //~ ERROR Rust has no postfix increment operator +} + +fn test5() { + let mut i = 0; + let _ = i++ + i; //~ ERROR Rust has no postfix increment operator +} + +fn test6() { + let mut i = 0; + let _ = i++ + i++; //~ ERROR Rust has no postfix increment operator +} + +fn test7() { + let mut i = 0; + let _ = ++i + i++; //~ ERROR Rust has no prefix increment operator +} + +fn test8() { + let mut i = 0; + let _ = i++ + ++i; //~ ERROR Rust has no postfix increment operator +} + +fn main() { } diff --git a/src/test/ui/parser/issue-104867-inc-dec-2.stderr b/src/test/ui/parser/issue-104867-inc-dec-2.stderr new file mode 100644 index 00000000000..21cfa4e8b78 --- /dev/null +++ b/src/test/ui/parser/issue-104867-inc-dec-2.stderr @@ -0,0 +1,90 @@ +error: Rust has no prefix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:3:17 + | +LL | let _ = i + ++i; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL | let _ = i + { i += 1; i }; + | ~ +++++++++ + +error: Rust has no prefix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:8:13 + | +LL | let _ = ++i + i; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL | let _ = { i += 1; i } + i; + | ~ +++++++++ + +error: Rust has no prefix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:13:13 + | +LL | let _ = ++i + ++i; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL | let _ = { i += 1; i } + ++i; + | ~ +++++++++ + +error: Rust has no postfix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:18:18 + | +LL | let _ = i + i++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | let _ = { let tmp = i + i; i + i += 1; tmp }; + | +++++++++++ ~~~~~~~~~~~~~~~~~~~ + +error: Rust has no postfix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:23:14 + | +LL | let _ = i++ + i; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | let _ = { let tmp = i; i += 1; tmp } + i; + | +++++++++++ ~~~~~~~~~~~~~~~ + +error: Rust has no postfix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:28:14 + | +LL | let _ = i++ + i++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | let _ = { let tmp = i; i += 1; tmp } + i++; + | +++++++++++ ~~~~~~~~~~~~~~~ + +error: Rust has no prefix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:33:13 + | +LL | let _ = ++i + i++; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL | let _ = { i += 1; i } + i++; + | ~ +++++++++ + +error: Rust has no postfix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:38:14 + | +LL | let _ = i++ + ++i; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | let _ = { let tmp = i; i += 1; tmp } + ++i; + | +++++++++++ ~~~~~~~~~~~~~~~ + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/parser/issue-104867-inc-dec.rs b/src/test/ui/parser/issue-104867-inc-dec.rs index d08d74ec1f9..760c67b4bed 100644 --- a/src/test/ui/parser/issue-104867-inc-dec.rs +++ b/src/test/ui/parser/issue-104867-inc-dec.rs @@ -27,4 +27,19 @@ fn test5() { if ++i == 1 { } //~ ERROR Rust has no prefix increment operator } +fn test6() { + let mut i = 0; + loop { break; } + i++; //~ ERROR Rust has no postfix increment operator + loop { break; } + ++i; +} + +fn test7() { + let mut i = 0; + loop { break; } + ++i; //~ ERROR Rust has no prefix increment operator +} + + fn main() {} diff --git a/src/test/ui/parser/issue-104867-inc-dec.stderr b/src/test/ui/parser/issue-104867-inc-dec.stderr index d45b92bf899..78bfd3e82f0 100644 --- a/src/test/ui/parser/issue-104867-inc-dec.stderr +++ b/src/test/ui/parser/issue-104867-inc-dec.stderr @@ -54,5 +54,28 @@ help: use `+= 1` instead LL | if { i += 1; i } == 1 { } | ~ +++++++++ -error: aborting due to 5 previous errors +error: Rust has no postfix increment operator + --> $DIR/issue-104867-inc-dec.rs:33:6 + | +LL | i++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | i += 1; + | ~~~~ + +error: Rust has no prefix increment operator + --> $DIR/issue-104867-inc-dec.rs:41:5 + | +LL | ++i; + | ^^ not a valid prefix operator + | +help: use `+= 1` instead + | +LL - ++i; +LL + i += 1; + | + +error: aborting due to 7 previous errors -- cgit 1.4.1-3-g733a5 From ded10a13d2a0ccb4475cb7a330179a1f39e2b4ff Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 26 Nov 2022 07:10:04 +0800 Subject: will not suggest for postfix operator when can not handle precedences well --- compiler/rustc_parse/src/parser/diagnostics.rs | 6 +++- src/test/ui/parser/issue-104867-inc-dec-2.rs | 11 +++++++ src/test/ui/parser/issue-104867-inc-dec-2.stderr | 37 +++++++++++++++++------- 3 files changed, 43 insertions(+), 11 deletions(-) (limited to 'compiler/rustc_parse/src/parser') diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index f8c6ff994c4..a9555cddb1b 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1316,7 +1316,11 @@ impl<'a> Parser<'a> { 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) + // won't suggest since we can not handle the precedences + // for example: `a + b++` has been parsed (a + b)++ and we can not suggest here + if !matches!(base.kind, ExprKind::Binary(_, _, _)) { + self.postfix_inc_dec_suggest(base_src, kind, spans).emit(&mut err) + } } } } diff --git a/src/test/ui/parser/issue-104867-inc-dec-2.rs b/src/test/ui/parser/issue-104867-inc-dec-2.rs index e64dfbcdc28..a006421a975 100644 --- a/src/test/ui/parser/issue-104867-inc-dec-2.rs +++ b/src/test/ui/parser/issue-104867-inc-dec-2.rs @@ -16,6 +16,7 @@ fn test3() { fn test4() { let mut i = 0; let _ = i + i++; //~ ERROR Rust has no postfix increment operator + // won't suggest since we can not handle the precedences } fn test5() { @@ -38,4 +39,14 @@ fn test8() { let _ = i++ + ++i; //~ ERROR Rust has no postfix increment operator } +fn test9() { + let mut i = 0; + let _ = (1 + 2 + i)++; //~ ERROR Rust has no postfix increment operator +} + +fn test10() { + let mut i = 0; + let _ = (i++ + 1) + 2; //~ ERROR Rust has no postfix increment operator +} + fn main() { } diff --git a/src/test/ui/parser/issue-104867-inc-dec-2.stderr b/src/test/ui/parser/issue-104867-inc-dec-2.stderr index 21cfa4e8b78..4e2d0546851 100644 --- a/src/test/ui/parser/issue-104867-inc-dec-2.stderr +++ b/src/test/ui/parser/issue-104867-inc-dec-2.stderr @@ -36,14 +36,9 @@ error: Rust has no postfix increment operator | LL | let _ = i + i++; | ^^ not a valid postfix operator - | -help: use `+= 1` instead - | -LL | let _ = { let tmp = i + i; i + i += 1; tmp }; - | +++++++++++ ~~~~~~~~~~~~~~~~~~~ error: Rust has no postfix increment operator - --> $DIR/issue-104867-inc-dec-2.rs:23:14 + --> $DIR/issue-104867-inc-dec-2.rs:24:14 | LL | let _ = i++ + i; | ^^ not a valid postfix operator @@ -54,7 +49,7 @@ LL | let _ = { let tmp = i; i += 1; tmp } + i; | +++++++++++ ~~~~~~~~~~~~~~~ error: Rust has no postfix increment operator - --> $DIR/issue-104867-inc-dec-2.rs:28:14 + --> $DIR/issue-104867-inc-dec-2.rs:29:14 | LL | let _ = i++ + i++; | ^^ not a valid postfix operator @@ -65,7 +60,7 @@ LL | let _ = { let tmp = i; i += 1; tmp } + i++; | +++++++++++ ~~~~~~~~~~~~~~~ error: Rust has no prefix increment operator - --> $DIR/issue-104867-inc-dec-2.rs:33:13 + --> $DIR/issue-104867-inc-dec-2.rs:34:13 | LL | let _ = ++i + i++; | ^^ not a valid prefix operator @@ -76,7 +71,7 @@ LL | let _ = { i += 1; i } + i++; | ~ +++++++++ error: Rust has no postfix increment operator - --> $DIR/issue-104867-inc-dec-2.rs:38:14 + --> $DIR/issue-104867-inc-dec-2.rs:39:14 | LL | let _ = i++ + ++i; | ^^ not a valid postfix operator @@ -86,5 +81,27 @@ help: use `+= 1` instead LL | let _ = { let tmp = i; i += 1; tmp } + ++i; | +++++++++++ ~~~~~~~~~~~~~~~ -error: aborting due to 8 previous errors +error: Rust has no postfix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:44:24 + | +LL | let _ = (1 + 2 + i)++; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | let _ = { let tmp = (1 + 2 + i); (1 + 2 + i) += 1; tmp }; + | +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: Rust has no postfix increment operator + --> $DIR/issue-104867-inc-dec-2.rs:49:15 + | +LL | let _ = (i++ + 1) + 2; + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL | let _ = ({ let tmp = i; i += 1; tmp } + 1) + 2; + | +++++++++++ ~~~~~~~~~~~~~~~ + +error: aborting due to 10 previous errors -- cgit 1.4.1-3-g733a5