Skip to content

Commit dee85a3

Browse files
committed
add start_stmt to handle postfix increment
1 parent 7c11a53 commit dee85a3

10 files changed

+203
-38
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -1259,10 +1259,9 @@ impl<'a> Parser<'a> {
12591259
&mut self,
12601260
operand_expr: P<Expr>,
12611261
op_span: Span,
1262-
prev_is_semi: bool,
1262+
start_stmt: bool,
12631263
) -> PResult<'a, P<Expr>> {
1264-
let standalone =
1265-
if prev_is_semi { IsStandalone::Standalone } else { IsStandalone::Subexpr };
1264+
let standalone = if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr };
12661265
let kind = IncDecRecovery { standalone, op: IncOrDec::Inc, fixity: UnaryFixity::Pre };
12671266
self.recover_from_inc_dec(operand_expr, kind, op_span)
12681267
}
@@ -1271,10 +1270,10 @@ impl<'a> Parser<'a> {
12711270
&mut self,
12721271
operand_expr: P<Expr>,
12731272
op_span: Span,
1274-
prev_is_semi: bool,
1273+
start_stmt: bool,
12751274
) -> PResult<'a, P<Expr>> {
12761275
let kind = IncDecRecovery {
1277-
standalone: if prev_is_semi { IsStandalone::Standalone } else { IsStandalone::Subexpr },
1276+
standalone: if start_stmt { IsStandalone::Standalone } else { IsStandalone::Subexpr },
12781277
op: IncOrDec::Inc,
12791278
fixity: UnaryFixity::Post,
12801279
};
@@ -1305,20 +1304,22 @@ impl<'a> Parser<'a> {
13051304
UnaryFixity::Post => (base.span.shrink_to_lo(), op_span),
13061305
};
13071306

1308-
let Ok(base_src) = self.span_to_snippet(base.span)
1309-
else { return help_base_case(err, base) };
13101307
match kind.standalone {
13111308
IsStandalone::Standalone => {
13121309
self.inc_dec_standalone_suggest(kind, spans).emit_verbose(&mut err)
13131310
}
1314-
IsStandalone::Subexpr => match kind.fixity {
1315-
UnaryFixity::Pre => {
1316-
self.prefix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
1317-
}
1318-
UnaryFixity::Post => {
1319-
self.postfix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
1311+
IsStandalone::Subexpr => {
1312+
let Ok(base_src) = self.span_to_snippet(base.span)
1313+
else { return help_base_case(err, base) };
1314+
match kind.fixity {
1315+
UnaryFixity::Pre => {
1316+
self.prefix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
1317+
}
1318+
UnaryFixity::Post => {
1319+
self.postfix_inc_dec_suggest(base_src, kind, spans).emit(&mut err)
1320+
}
13201321
}
1321-
},
1322+
}
13221323
}
13231324
Err(err)
13241325
}

compiler/rustc_parse/src/parser/expr.rs

+9-14
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ macro_rules! maybe_whole_expr {
8383
pub(super) enum LhsExpr {
8484
NotYetParsed,
8585
AttributesParsed(AttrWrapper),
86-
AlreadyParsed(P<Expr>),
86+
AlreadyParsed(P<Expr>, bool), // (expr, starts_statement)
8787
}
8888

8989
impl From<Option<AttrWrapper>> for LhsExpr {
@@ -101,7 +101,7 @@ impl From<P<Expr>> for LhsExpr {
101101
///
102102
/// This conversion does not allocate.
103103
fn from(expr: P<Expr>) -> Self {
104-
LhsExpr::AlreadyParsed(expr)
104+
LhsExpr::AlreadyParsed(expr, false)
105105
}
106106
}
107107

@@ -173,7 +173,9 @@ impl<'a> Parser<'a> {
173173
min_prec: usize,
174174
lhs: LhsExpr,
175175
) -> PResult<'a, P<Expr>> {
176-
let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
176+
let mut starts_stmt = false;
177+
let mut lhs = if let LhsExpr::AlreadyParsed(expr, starts_statement) = lhs {
178+
starts_stmt = starts_statement;
177179
expr
178180
} else {
179181
let attrs = match lhs {
@@ -292,15 +294,7 @@ impl<'a> Parser<'a> {
292294
let op_span = self.prev_token.span.to(self.token.span);
293295
// Eat the second `+`
294296
self.bump();
295-
let prev_is_semi = {
296-
if let Ok(prev_code) = self.sess.source_map().span_to_prev_source(lhs.span) &&
297-
prev_code.trim_end().ends_with(";") {
298-
true
299-
} else {
300-
false
301-
}
302-
};
303-
lhs = self.recover_from_postfix_increment(lhs, op_span, prev_is_semi)?;
297+
lhs = self.recover_from_postfix_increment(lhs, op_span, starts_stmt)?;
304298
continue;
305299
}
306300

@@ -607,14 +601,15 @@ impl<'a> Parser<'a> {
607601
token::BinOp(token::Plus)
608602
if this.look_ahead(1, |t| *t == token::BinOp(token::Plus)) =>
609603
{
610-
let prev_is_semi = this.prev_token == token::Semi;
604+
let starts_stmt = this.prev_token == token::Semi
605+
|| this.prev_token == token::CloseDelim(Delimiter::Brace);
611606
let pre_span = this.token.span.to(this.look_ahead(1, |t| t.span));
612607
// Eat both `+`s.
613608
this.bump();
614609
this.bump();
615610

616611
let operand_expr = this.parse_dot_or_call_expr(Default::default())?;
617-
this.recover_from_prefix_increment(operand_expr, pre_span, prev_is_semi)
612+
this.recover_from_prefix_increment(operand_expr, pre_span, starts_stmt)
618613
}
619614
token::Ident(..) if this.token.is_keyword(kw::Box) => {
620615
make_it!(this, attrs, |this, _| this.parse_box_expr(lo))

compiler/rustc_parse/src/parser/stmt.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl<'a> Parser<'a> {
156156
// Perform this outside of the `collect_tokens_trailing_token` closure,
157157
// since our outer attributes do not apply to this part of the expression
158158
let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
159-
this.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(expr))
159+
this.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(expr, true))
160160
})?;
161161
Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Expr(expr)))
162162
} else {
@@ -190,7 +190,7 @@ impl<'a> Parser<'a> {
190190
let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
191191
let e = self.maybe_recover_from_bad_qpath(e)?;
192192
let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?;
193-
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
193+
let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e, false))?;
194194
StmtKind::Expr(e)
195195
};
196196
Ok(self.mk_stmt(lo.to(hi), kind))

src/test/ui/parser/increment-notfixed.stderr renamed to src/test/ui/parser/increment-autofix-2.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: Rust has no postfix increment operator
2-
--> $DIR/increment-notfixed.rs:13:6
2+
--> $DIR/increment-autofix-2.rs:13:6
33
|
44
LL | i++;
55
| ^^ not a valid postfix operator
@@ -10,7 +10,7 @@ LL | i += 1;
1010
| ~~~~
1111

1212
error: Rust has no postfix increment operator
13-
--> $DIR/increment-notfixed.rs:19:12
13+
--> $DIR/increment-autofix-2.rs:19:12
1414
|
1515
LL | while i++ < 5 {
1616
| ----- ^^ not a valid postfix operator
@@ -23,7 +23,7 @@ LL | while { let tmp = i; i += 1; tmp } < 5 {
2323
| +++++++++++ ~~~~~~~~~~~~~~~
2424

2525
error: Rust has no postfix increment operator
26-
--> $DIR/increment-notfixed.rs:27:8
26+
--> $DIR/increment-autofix-2.rs:27:8
2727
|
2828
LL | tmp++;
2929
| ^^ not a valid postfix operator
@@ -34,7 +34,7 @@ LL | tmp += 1;
3434
| ~~~~
3535

3636
error: Rust has no postfix increment operator
37-
--> $DIR/increment-notfixed.rs:33:14
37+
--> $DIR/increment-autofix-2.rs:33:14
3838
|
3939
LL | while tmp++ < 5 {
4040
| ----- ^^ not a valid postfix operator
@@ -47,7 +47,7 @@ LL | while { let tmp_ = tmp; tmp += 1; tmp_ } < 5 {
4747
| ++++++++++++ ~~~~~~~~~~~~~~~~~~
4848

4949
error: Rust has no postfix increment operator
50-
--> $DIR/increment-notfixed.rs:41:16
50+
--> $DIR/increment-autofix-2.rs:41:16
5151
|
5252
LL | foo.bar.qux++;
5353
| ^^ not a valid postfix operator
@@ -58,7 +58,7 @@ LL | foo.bar.qux += 1;
5858
| ~~~~
5959

6060
error: Rust has no postfix increment operator
61-
--> $DIR/increment-notfixed.rs:51:10
61+
--> $DIR/increment-autofix-2.rs:51:10
6262
|
6363
LL | s.tmp++;
6464
| ^^ not a valid postfix operator
@@ -69,7 +69,7 @@ LL | s.tmp += 1;
6969
| ~~~~
7070

7171
error: Rust has no prefix increment operator
72-
--> $DIR/increment-notfixed.rs:58:5
72+
--> $DIR/increment-autofix-2.rs:58:5
7373
|
7474
LL | ++foo.bar.qux;
7575
| ^^ not a valid prefix operator
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
fn test1() {
2+
let mut i = 0;
3+
let _ = i + ++i; //~ ERROR Rust has no prefix increment operator
4+
}
5+
6+
fn test2() {
7+
let mut i = 0;
8+
let _ = ++i + i; //~ ERROR Rust has no prefix increment operator
9+
}
10+
11+
fn test3() {
12+
let mut i = 0;
13+
let _ = ++i + ++i; //~ ERROR Rust has no prefix increment operator
14+
}
15+
16+
fn test4() {
17+
let mut i = 0;
18+
let _ = i + i++; //~ ERROR Rust has no postfix increment operator
19+
}
20+
21+
fn test5() {
22+
let mut i = 0;
23+
let _ = i++ + i; //~ ERROR Rust has no postfix increment operator
24+
}
25+
26+
fn test6() {
27+
let mut i = 0;
28+
let _ = i++ + i++; //~ ERROR Rust has no postfix increment operator
29+
}
30+
31+
fn test7() {
32+
let mut i = 0;
33+
let _ = ++i + i++; //~ ERROR Rust has no prefix increment operator
34+
}
35+
36+
fn test8() {
37+
let mut i = 0;
38+
let _ = i++ + ++i; //~ ERROR Rust has no postfix increment operator
39+
}
40+
41+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
error: Rust has no prefix increment operator
2+
--> $DIR/issue-104867-inc-dec-2.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 increment operator
13+
--> $DIR/issue-104867-inc-dec-2.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 increment operator
24+
--> $DIR/issue-104867-inc-dec-2.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 increment operator
35+
--> $DIR/issue-104867-inc-dec-2.rs:18:18
36+
|
37+
LL | let _ = i + i++;
38+
| ^^ not a valid postfix operator
39+
|
40+
help: use `+= 1` instead
41+
|
42+
LL | let _ = { let tmp = i + i; i + i += 1; tmp };
43+
| +++++++++++ ~~~~~~~~~~~~~~~~~~~
44+
45+
error: Rust has no postfix increment operator
46+
--> $DIR/issue-104867-inc-dec-2.rs:23:14
47+
|
48+
LL | let _ = i++ + i;
49+
| ^^ not a valid postfix operator
50+
|
51+
help: use `+= 1` instead
52+
|
53+
LL | let _ = { let tmp = i; i += 1; tmp } + i;
54+
| +++++++++++ ~~~~~~~~~~~~~~~
55+
56+
error: Rust has no postfix increment operator
57+
--> $DIR/issue-104867-inc-dec-2.rs:28:14
58+
|
59+
LL | let _ = i++ + i++;
60+
| ^^ not a valid postfix operator
61+
|
62+
help: use `+= 1` instead
63+
|
64+
LL | let _ = { let tmp = i; i += 1; tmp } + i++;
65+
| +++++++++++ ~~~~~~~~~~~~~~~
66+
67+
error: Rust has no prefix increment operator
68+
--> $DIR/issue-104867-inc-dec-2.rs:33:13
69+
|
70+
LL | let _ = ++i + i++;
71+
| ^^ not a valid prefix operator
72+
|
73+
help: use `+= 1` instead
74+
|
75+
LL | let _ = { i += 1; i } + i++;
76+
| ~ +++++++++
77+
78+
error: Rust has no postfix increment operator
79+
--> $DIR/issue-104867-inc-dec-2.rs:38:14
80+
|
81+
LL | let _ = i++ + ++i;
82+
| ^^ not a valid postfix operator
83+
|
84+
help: use `+= 1` instead
85+
|
86+
LL | let _ = { let tmp = i; i += 1; tmp } + ++i;
87+
| +++++++++++ ~~~~~~~~~~~~~~~
88+
89+
error: aborting due to 8 previous errors
90+

src/test/ui/parser/issue-104867-inc-dec.rs

+15
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,19 @@ fn test5() {
2727
if ++i == 1 { } //~ ERROR Rust has no prefix increment operator
2828
}
2929

30+
fn test6() {
31+
let mut i = 0;
32+
loop { break; }
33+
i++; //~ ERROR Rust has no postfix increment operator
34+
loop { break; }
35+
++i;
36+
}
37+
38+
fn test7() {
39+
let mut i = 0;
40+
loop { break; }
41+
++i; //~ ERROR Rust has no prefix increment operator
42+
}
43+
44+
3045
fn main() {}

src/test/ui/parser/issue-104867-inc-dec.stderr

+24-1
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,28 @@ help: use `+= 1` instead
5454
LL | if { i += 1; i } == 1 { }
5555
| ~ +++++++++
5656

57-
error: aborting due to 5 previous errors
57+
error: Rust has no postfix increment operator
58+
--> $DIR/issue-104867-inc-dec.rs:33:6
59+
|
60+
LL | i++;
61+
| ^^ not a valid postfix operator
62+
|
63+
help: use `+= 1` instead
64+
|
65+
LL | i += 1;
66+
| ~~~~
67+
68+
error: Rust has no prefix increment operator
69+
--> $DIR/issue-104867-inc-dec.rs:41:5
70+
|
71+
LL | ++i;
72+
| ^^ not a valid prefix operator
73+
|
74+
help: use `+= 1` instead
75+
|
76+
LL - ++i;
77+
LL + i += 1;
78+
|
79+
80+
error: aborting due to 7 previous errors
5881

0 commit comments

Comments
 (0)