Skip to content

Commit 46ea12a

Browse files
committed
fix #108495, postfix decrement and prefix decrement has no warning
1 parent 70fd012 commit 46ea12a

File tree

4 files changed

+214
-7
lines changed

4 files changed

+214
-7
lines changed

Diff for: compiler/rustc_parse/src/parser/diagnostics.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ enum IsStandalone {
166166
enum IncOrDec {
167167
Inc,
168168
// FIXME: `i--` recovery isn't implemented yet
169-
#[allow(dead_code)]
169+
// #[allow(dead_code)]
170170
Dec,
171171
}
172172

@@ -1331,7 +1331,7 @@ impl<'a> Parser<'a> {
13311331

13321332
Ok(())
13331333
}
1334-
1334+
#[allow(dead_code)]
13351335
pub(super) fn recover_from_prefix_increment(
13361336
&mut self,
13371337
operand_expr: P<Expr>,
@@ -1342,7 +1342,7 @@ impl<'a> Parser<'a> {
13421342
let kind = IncDecRecovery { standalone, op: IncOrDec::Inc, fixity: UnaryFixity::Pre };
13431343
self.recover_from_inc_dec(operand_expr, kind, op_span)
13441344
}
1345-
1345+
#[allow(dead_code)]
13461346
pub(super) fn recover_from_postfix_increment(
13471347
&mut self,
13481348
operand_expr: P<Expr>,
@@ -1356,7 +1356,30 @@ impl<'a> Parser<'a> {
13561356
};
13571357
self.recover_from_inc_dec(operand_expr, kind, op_span)
13581358
}
1359+
pub(super) fn recover_from_prefix_decrement(
1360+
&mut self,
1361+
operand_expr: P<Expr>,
1362+
op_span: Span,
1363+
start_stmt: bool,
1364+
) -> PResult<'a, P<Expr>> {
1365+
let standalone = if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr };
1366+
let kind = IncDecRecovery { standalone, op: IncOrDec::Dec, fixity: UnaryFixity::Pre };
1367+
self.recover_from_inc_dec(operand_expr, kind, op_span)
1368+
}
13591369

1370+
pub(super) fn recover_from_postfix_decrement(
1371+
&mut self,
1372+
operand_expr: P<Expr>,
1373+
op_span: Span,
1374+
start_stmt: bool,
1375+
) -> PResult<'a, P<Expr>> {
1376+
let kind = IncDecRecovery {
1377+
standalone: if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr },
1378+
op: IncOrDec::Dec,
1379+
fixity: UnaryFixity::Post,
1380+
};
1381+
self.recover_from_inc_dec(operand_expr, kind, op_span)
1382+
}
13601383
fn recover_from_inc_dec(
13611384
&mut self,
13621385
base: P<Expr>,

Diff for: compiler/rustc_parse/src/parser/expr.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,16 @@ impl<'a> Parser<'a> {
281281
lhs = self.recover_from_postfix_increment(lhs, op_span, starts_stmt)?;
282282
continue;
283283
}
284+
if self.prev_token == token::BinOp(token::Minus)
285+
&& self.token == token::BinOp(token::Minus)
286+
&& self.prev_token.span.between(self.token.span).is_empty()
287+
{
288+
let op_span = self.prev_token.span.to(self.token.span);
289+
// Eat the second `+`
290+
self.bump();
291+
lhs = self.recover_from_postfix_decrement(lhs, op_span, starts_stmt)?;
292+
continue;
293+
}
284294

285295
let op = op.node;
286296
// Special cases:
@@ -550,10 +560,7 @@ impl<'a> Parser<'a> {
550560
token::Not => make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Not)),
551561
// `~expr`
552562
token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)),
553-
// `-expr`
554-
token::BinOp(token::Minus) => {
555-
make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg))
556-
}
563+
557564
// `*expr`
558565
token::BinOp(token::Star) => {
559566
make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Deref))
@@ -595,6 +602,24 @@ impl<'a> Parser<'a> {
595602
let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
596603
this.recover_from_prefix_increment(operand_expr, pre_span, starts_stmt)
597604
}
605+
// Recover from `++x`:
606+
token::BinOp(token::Minus)
607+
if this.look_ahead(1, |t| *t == token::BinOp(token::Minus)) =>
608+
{
609+
let starts_stmt = this.prev_token == token::Semi
610+
|| this.prev_token == token::CloseDelim(Delimiter::Brace);
611+
let pre_span = this.token.span.to(this.look_ahead(1, |t| t.span));
612+
// Eat both `+`s.
613+
this.bump();
614+
this.bump();
615+
616+
let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
617+
this.recover_from_prefix_decrement(operand_expr, pre_span, starts_stmt)
618+
}
619+
// `-expr`
620+
token::BinOp(token::Minus) => {
621+
make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg))
622+
}
598623
token::Ident(..) if this.token.is_keyword(kw::Box) => {
599624
make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
600625
}

Diff for: tests/ui/parser/issue-108495-dec.rs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
fn test1() {
2+
let mut i = 0;
3+
let _ = i + --i; //~ ERROR Rust has no prefix decrement operator
4+
}
5+
6+
fn test2() {
7+
let mut i = 0;
8+
let _ = --i + i; //~ ERROR Rust has no prefix decrement operator
9+
}
10+
11+
fn test3() {
12+
let mut i = 0;
13+
let _ = --i + --i; //~ ERROR Rust has no prefix decrement operator
14+
}
15+
16+
fn test4() {
17+
let mut i = 0;
18+
let _ = i + i--; //~ ERROR Rust has no postfix decrement operator
19+
// won't suggest since we can not handle the precedences
20+
}
21+
22+
fn test5() {
23+
let mut i = 0;
24+
let _ = i-- + i; //~ ERROR Rust has no postfix decrement operator
25+
}
26+
27+
fn test6() {
28+
let mut i = 0;
29+
let _ = i-- + i--; //~ ERROR Rust has no postfix decrement operator
30+
}
31+
32+
fn test7() {
33+
let mut i = 0;
34+
let _ = --i + i--; //~ ERROR Rust has no prefix decrement operator
35+
}
36+
37+
fn test8() {
38+
let mut i = 0;
39+
let _ = i-- + --i; //~ ERROR Rust has no postfix decrement operator
40+
}
41+
42+
fn test9() {
43+
let mut i = 0;
44+
let _ = (1 + 2 + i)--; //~ ERROR Rust has no postfix decrement operator
45+
}
46+
47+
fn test10() {
48+
let mut i = 0;
49+
let _ = (i-- + 1) + 2; //~ ERROR Rust has no postfix decrement operator
50+
}
51+
52+
fn main() { }

Diff for: tests/ui/parser/issue-108495-dec.stderr

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
error: Rust has no prefix decrement operator
2+
--> $DIR/issue-dec.rs:3:17
3+
|
4+
LL | let _ = i + --i;
5+
| ^^ not a valid prefix operator
6+
|
7+
help: use `-= 1` instead
8+
|
9+
LL | let _ = i + { i -= 1; i };
10+
| ~ +++++++++
11+
12+
error: Rust has no prefix decrement operator
13+
--> $DIR/issue-dec.rs:8:13
14+
|
15+
LL | let _ = --i + i;
16+
| ^^ not a valid prefix operator
17+
|
18+
help: use `-= 1` instead
19+
|
20+
LL | let _ = { i -= 1; i } + i;
21+
| ~ +++++++++
22+
23+
error: Rust has no prefix decrement operator
24+
--> $DIR/issue-dec.rs:13:13
25+
|
26+
LL | let _ = --i + --i;
27+
| ^^ not a valid prefix operator
28+
|
29+
help: use `-= 1` instead
30+
|
31+
LL | let _ = { i -= 1; i } + --i;
32+
| ~ +++++++++
33+
34+
error: Rust has no postfix decrement operator
35+
--> $DIR/issue-dec.rs:18:18
36+
|
37+
LL | let _ = i + i--;
38+
| ^^ not a valid postfix operator
39+
40+
error: Rust has no postfix decrement operator
41+
--> $DIR/issue-dec.rs:24:14
42+
|
43+
LL | let _ = i-- + i;
44+
| ^^ not a valid postfix operator
45+
|
46+
help: use `-= 1` instead
47+
|
48+
LL | let _ = { let tmp = i; i -= 1; tmp } + i;
49+
| +++++++++++ ~~~~~~~~~~~~~~~
50+
51+
error: Rust has no postfix decrement operator
52+
--> $DIR/issue-dec.rs:29:14
53+
|
54+
LL | let _ = i-- + i--;
55+
| ^^ not a valid postfix operator
56+
|
57+
help: use `-= 1` instead
58+
|
59+
LL | let _ = { let tmp = i; i -= 1; tmp } + i--;
60+
| +++++++++++ ~~~~~~~~~~~~~~~
61+
62+
error: Rust has no prefix decrement operator
63+
--> $DIR/issue-dec.rs:34:13
64+
|
65+
LL | let _ = --i + i--;
66+
| ^^ not a valid prefix operator
67+
|
68+
help: use `-= 1` instead
69+
|
70+
LL | let _ = { i -= 1; i } + i--;
71+
| ~ +++++++++
72+
73+
error: Rust has no postfix decrement operator
74+
--> $DIR/issue-dec.rs:39:14
75+
|
76+
LL | let _ = i-- + --i;
77+
| ^^ not a valid postfix operator
78+
|
79+
help: use `-= 1` instead
80+
|
81+
LL | let _ = { let tmp = i; i -= 1; tmp } + --i;
82+
| +++++++++++ ~~~~~~~~~~~~~~~
83+
84+
error: Rust has no postfix decrement operator
85+
--> $DIR/issue-dec.rs:44:24
86+
|
87+
LL | let _ = (1 + 2 + i)--;
88+
| ^^ not a valid postfix operator
89+
|
90+
help: use `-= 1` instead
91+
|
92+
LL | let _ = { let tmp = (1 + 2 + i); (1 + 2 + i) -= 1; tmp };
93+
| +++++++++++ ~~~~~~~~~~~~~~~~~~~~~~~~~
94+
95+
error: Rust has no postfix decrement operator
96+
--> $DIR/issue-dec.rs:49:15
97+
|
98+
LL | let _ = (i-- + 1) + 2;
99+
| ^^ not a valid postfix operator
100+
|
101+
help: use `-= 1` instead
102+
|
103+
LL | let _ = ({ let tmp = i; i -= 1; tmp } + 1) + 2;
104+
| +++++++++++ ~~~~~~~~~~~~~~~
105+
106+
error: aborting due to 10 previous errors
107+

0 commit comments

Comments
 (0)