From dee85a391f091f314a24fb5a090f2e528f4eb81c Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 26 Nov 2022 05:33:13 +0800 Subject: [PATCH] add start_stmt to handle postfix increment --- .../rustc_parse/src/parser/diagnostics.rs | 29 +++--- compiler/rustc_parse/src/parser/expr.rs | 23 ++--- compiler/rustc_parse/src/parser/stmt.rs | 4 +- ...tfixed.fixed => increment-autofix-2.fixed} | 0 ...ent-notfixed.rs => increment-autofix-2.rs} | 0 ...ixed.stderr => increment-autofix-2.stderr} | 14 +-- src/test/ui/parser/issue-104867-inc-dec-2.rs | 41 +++++++++ .../ui/parser/issue-104867-inc-dec-2.stderr | 90 +++++++++++++++++++ src/test/ui/parser/issue-104867-inc-dec.rs | 15 ++++ .../ui/parser/issue-104867-inc-dec.stderr | 25 +++++- 10 files changed, 203 insertions(+), 38 deletions(-) rename src/test/ui/parser/{increment-notfixed.fixed => increment-autofix-2.fixed} (100%) rename src/test/ui/parser/{increment-notfixed.rs => increment-autofix-2.rs} (100%) rename src/test/ui/parser/{increment-notfixed.stderr => increment-autofix-2.stderr} (85%) 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 diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index eba0f22f37f3..f8c6ff994c4a 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) + 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) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b98372d0f28c..36fe328cb193 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 1b56cd72db07..53aa0315151c 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-notfixed.fixed b/src/test/ui/parser/increment-autofix-2.fixed similarity index 100% rename from src/test/ui/parser/increment-notfixed.fixed rename to src/test/ui/parser/increment-autofix-2.fixed diff --git a/src/test/ui/parser/increment-notfixed.rs b/src/test/ui/parser/increment-autofix-2.rs similarity index 100% rename from src/test/ui/parser/increment-notfixed.rs rename to src/test/ui/parser/increment-autofix-2.rs diff --git a/src/test/ui/parser/increment-notfixed.stderr b/src/test/ui/parser/increment-autofix-2.stderr similarity index 85% rename from src/test/ui/parser/increment-notfixed.stderr rename to src/test/ui/parser/increment-autofix-2.stderr index ffee8b64637c..11e985480d69 100644 --- a/src/test/ui/parser/increment-notfixed.stderr +++ b/src/test/ui/parser/increment-autofix-2.stderr @@ -1,5 +1,5 @@ error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:13:6 + --> $DIR/increment-autofix-2.rs:13:6 | LL | i++; | ^^ not a valid postfix operator @@ -10,7 +10,7 @@ LL | i += 1; | ~~~~ error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:19:12 + --> $DIR/increment-autofix-2.rs:19:12 | LL | while i++ < 5 { | ----- ^^ not a valid postfix operator @@ -23,7 +23,7 @@ LL | while { let tmp = i; i += 1; tmp } < 5 { | +++++++++++ ~~~~~~~~~~~~~~~ error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:27:8 + --> $DIR/increment-autofix-2.rs:27:8 | LL | tmp++; | ^^ not a valid postfix operator @@ -34,7 +34,7 @@ LL | tmp += 1; | ~~~~ error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:33:14 + --> $DIR/increment-autofix-2.rs:33:14 | LL | while tmp++ < 5 { | ----- ^^ not a valid postfix operator @@ -47,7 +47,7 @@ LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 { | ++++++++++++ ~~~~~~~~~~~~~~~~~~ error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:41:16 + --> $DIR/increment-autofix-2.rs:41:16 | LL | foo.bar.qux++; | ^^ not a valid postfix operator @@ -58,7 +58,7 @@ LL | foo.bar.qux += 1; | ~~~~ error: Rust has no postfix increment operator - --> $DIR/increment-notfixed.rs:51:10 + --> $DIR/increment-autofix-2.rs:51:10 | LL | s.tmp++; | ^^ not a valid postfix operator @@ -69,7 +69,7 @@ LL | s.tmp += 1; | ~~~~ error: Rust has no prefix increment operator - --> $DIR/increment-notfixed.rs:58:5 + --> $DIR/increment-autofix-2.rs:58:5 | LL | ++foo.bar.qux; | ^^ not a valid prefix operator 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 000000000000..e64dfbcdc287 --- /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 000000000000..21cfa4e8b78b --- /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 d08d74ec1f91..760c67b4bed7 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 d45b92bf8990..78bfd3e82f0d 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