From 46ea12a499aecd655a5c954431466db0a66e8ec9 Mon Sep 17 00:00:00 2001 From: nx2k3 Date: Sun, 26 Feb 2023 16:17:23 +0000 Subject: [PATCH] fix #108495, postfix decrement and prefix decrement has no warning --- .../rustc_parse/src/parser/diagnostics.rs | 29 ++++- compiler/rustc_parse/src/parser/expr.rs | 33 +++++- tests/ui/parser/issue-108495-dec.rs | 52 +++++++++ tests/ui/parser/issue-108495-dec.stderr | 107 ++++++++++++++++++ 4 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 tests/ui/parser/issue-108495-dec.rs create mode 100644 tests/ui/parser/issue-108495-dec.stderr diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d235b8a8176..e3dbe89b56c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -166,7 +166,7 @@ enum IsStandalone { enum IncOrDec { Inc, // FIXME: `i--` recovery isn't implemented yet - #[allow(dead_code)] + // #[allow(dead_code)] Dec, } @@ -1331,7 +1331,7 @@ impl<'a> Parser<'a> { Ok(()) } - + #[allow(dead_code)] pub(super) fn recover_from_prefix_increment( &mut self, operand_expr: P, @@ -1342,7 +1342,7 @@ impl<'a> Parser<'a> { let kind = IncDecRecovery { standalone, op: IncOrDec::Inc, fixity: UnaryFixity::Pre }; self.recover_from_inc_dec(operand_expr, kind, op_span) } - + #[allow(dead_code)] pub(super) fn recover_from_postfix_increment( &mut self, operand_expr: P, @@ -1356,7 +1356,30 @@ impl<'a> Parser<'a> { }; self.recover_from_inc_dec(operand_expr, kind, op_span) } + pub(super) fn recover_from_prefix_decrement( + &mut self, + operand_expr: P, + op_span: Span, + start_stmt: bool, + ) -> PResult<'a, P> { + let standalone = if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr }; + let kind = IncDecRecovery { standalone, op: IncOrDec::Dec, fixity: UnaryFixity::Pre }; + self.recover_from_inc_dec(operand_expr, kind, op_span) + } + pub(super) fn recover_from_postfix_decrement( + &mut self, + operand_expr: P, + op_span: Span, + start_stmt: bool, + ) -> PResult<'a, P> { + let kind = IncDecRecovery { + standalone: if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr }, + op: IncOrDec::Dec, + fixity: UnaryFixity::Post, + }; + self.recover_from_inc_dec(operand_expr, kind, op_span) + } fn recover_from_inc_dec( &mut self, base: P, diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 12f65a436e3..2004d0a8fe7 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -281,6 +281,16 @@ impl<'a> Parser<'a> { lhs = self.recover_from_postfix_increment(lhs, op_span, starts_stmt)?; continue; } + if self.prev_token == token::BinOp(token::Minus) + && self.token == token::BinOp(token::Minus) + && self.prev_token.span.between(self.token.span).is_empty() + { + let op_span = self.prev_token.span.to(self.token.span); + // Eat the second `+` + self.bump(); + lhs = self.recover_from_postfix_decrement(lhs, op_span, starts_stmt)?; + continue; + } let op = op.node; // Special cases: @@ -550,10 +560,7 @@ impl<'a> Parser<'a> { token::Not => make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Not)), // `~expr` token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)), - // `-expr` - token::BinOp(token::Minus) => { - make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg)) - } + // `*expr` token::BinOp(token::Star) => { make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Deref)) @@ -595,6 +602,24 @@ impl<'a> Parser<'a> { let operand_expr = this.parse_dot_or_call_expr(Default::default())?; this.recover_from_prefix_increment(operand_expr, pre_span, starts_stmt) } + // Recover from `++x`: + token::BinOp(token::Minus) + if this.look_ahead(1, |t| *t == token::BinOp(token::Minus)) => + { + 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_decrement(operand_expr, pre_span, starts_stmt) + } + // `-expr` + token::BinOp(token::Minus) => { + make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg)) + } token::Ident(..) if this.token.is_keyword(kw::Box) => { make_it!(this, attrs, |this, _| this.parse_box_expr(lo)) } diff --git a/tests/ui/parser/issue-108495-dec.rs b/tests/ui/parser/issue-108495-dec.rs new file mode 100644 index 00000000000..165e6142b46 --- /dev/null +++ b/tests/ui/parser/issue-108495-dec.rs @@ -0,0 +1,52 @@ +fn test1() { + let mut i = 0; + let _ = i + --i; //~ ERROR Rust has no prefix decrement operator +} + +fn test2() { + let mut i = 0; + let _ = --i + i; //~ ERROR Rust has no prefix decrement operator +} + +fn test3() { + let mut i = 0; + let _ = --i + --i; //~ ERROR Rust has no prefix decrement operator +} + +fn test4() { + let mut i = 0; + let _ = i + i--; //~ ERROR Rust has no postfix decrement operator + // won't suggest since we can not handle the precedences +} + +fn test5() { + let mut i = 0; + let _ = i-- + i; //~ ERROR Rust has no postfix decrement operator +} + +fn test6() { + let mut i = 0; + let _ = i-- + i--; //~ ERROR Rust has no postfix decrement operator +} + +fn test7() { + let mut i = 0; + let _ = --i + i--; //~ ERROR Rust has no prefix decrement operator +} + +fn test8() { + let mut i = 0; + let _ = i-- + --i; //~ ERROR Rust has no postfix decrement operator +} + +fn test9() { + let mut i = 0; + let _ = (1 + 2 + i)--; //~ ERROR Rust has no postfix decrement operator +} + +fn test10() { + let mut i = 0; + let _ = (i-- + 1) + 2; //~ ERROR Rust has no postfix decrement operator +} + +fn main() { } diff --git a/tests/ui/parser/issue-108495-dec.stderr b/tests/ui/parser/issue-108495-dec.stderr new file mode 100644 index 00000000000..078fec74c55 --- /dev/null +++ b/tests/ui/parser/issue-108495-dec.stderr @@ -0,0 +1,107 @@ +error: Rust has no prefix decrement operator + --> $DIR/issue-dec.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 decrement operator + --> $DIR/issue-dec.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 decrement operator + --> $DIR/issue-dec.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 decrement operator + --> $DIR/issue-dec.rs:18:18 + | +LL | let _ = i + i--; + | ^^ not a valid postfix operator + +error: Rust has no postfix decrement operator + --> $DIR/issue-dec.rs:24: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 decrement operator + --> $DIR/issue-dec.rs:29: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 decrement operator + --> $DIR/issue-dec.rs:34: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 decrement operator + --> $DIR/issue-dec.rs:39: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 decrement operator + --> $DIR/issue-dec.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 decrement operator + --> $DIR/issue-dec.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 +