Skip to content

Commit 77ac329

Browse files
authored
Rollup merge of #88553 - theo-lw:issue-88276, r=estebank
Improve diagnostics for unary plus operators (#88276) This pull request improves the diagnostics emitted on parsing a unary plus operator. See #88276. Before: ``` error: expected expression, found `+` --> src/main.rs:2:13 | 2 | let x = +1; | ^ expected expression ``` After: ``` error: leading `+` is not supported --> main.rs:2:13 | 2 | let x = +1; | ^ | | | unexpected `+` | help: try removing the `+` ```
2 parents 4fb0084 + 20eba43 commit 77ac329

File tree

9 files changed

+105
-6
lines changed

9 files changed

+105
-6
lines changed

compiler/rustc_ast/src/token.rs

+7
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,13 @@ impl Token {
586586
self.is_non_raw_ident_where(|id| id.name.is_bool_lit())
587587
}
588588

589+
pub fn is_numeric_lit(&self) -> bool {
590+
matches!(
591+
self.kind,
592+
Literal(Lit { kind: LitKind::Integer, .. }) | Literal(Lit { kind: LitKind::Float, .. })
593+
)
594+
}
595+
589596
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
590597
pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool {
591598
match self.ident() {

compiler/rustc_parse/src/parser/expr.rs

+20
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,26 @@ impl<'a> Parser<'a> {
516516
token::BinOp(token::And) | token::AndAnd => {
517517
make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo))
518518
}
519+
token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => {
520+
let mut err = this.struct_span_err(lo, "leading `+` is not supported");
521+
err.span_label(lo, "unexpected `+`");
522+
523+
// a block on the LHS might have been intended to be an expression instead
524+
if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
525+
this.sess.expr_parentheses_needed(&mut err, *sp);
526+
} else {
527+
err.span_suggestion_verbose(
528+
lo,
529+
"try removing the `+`",
530+
"".to_string(),
531+
Applicability::MachineApplicable,
532+
);
533+
}
534+
err.emit();
535+
536+
this.bump();
537+
this.parse_prefix_expr(None)
538+
} // `+expr`
519539
token::Ident(..) if this.token.is_keyword(kw::Box) => {
520540
make_it!(this, attrs, |this, _| this.parse_box_expr(lo))
521541
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
error: expected expression, found `+`
1+
error: leading `+` is not supported
22
--> $DIR/issue-36499.rs:4:9
33
|
44
LL | 2 + +2;
5-
| ^ expected expression
5+
| ^ unexpected `+`
6+
|
7+
help: try removing the `+`
8+
|
9+
LL - 2 + +2;
10+
LL + 2 + 2;
11+
|
612

713
error: aborting due to previous error
814

src/test/ui/parser/expr-as-stmt.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn foo() -> i32 {
1010
}
1111

1212
fn bar() -> i32 {
13-
({2}) + 2 //~ ERROR expected expression, found `+`
13+
({2}) + 2 //~ ERROR leading `+` is not supported
1414
//~^ ERROR mismatched types
1515
}
1616

src/test/ui/parser/expr-as-stmt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn foo() -> i32 {
1010
}
1111

1212
fn bar() -> i32 {
13-
{2} + 2 //~ ERROR expected expression, found `+`
13+
{2} + 2 //~ ERROR leading `+` is not supported
1414
//~^ ERROR mismatched types
1515
}
1616

src/test/ui/parser/expr-as-stmt.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ help: parentheses are required to parse this as an expression
99
LL | ({2}) + {2}
1010
| + +
1111

12-
error: expected expression, found `+`
12+
error: leading `+` is not supported
1313
--> $DIR/expr-as-stmt.rs:13:9
1414
|
1515
LL | {2} + 2
16-
| ^ expected expression
16+
| ^ unexpected `+`
1717
|
1818
help: parentheses are required to parse this as an expression
1919
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
#[allow(unused_parens)]
3+
fn main() {
4+
let _ = 1; //~ ERROR leading `+` is not supported
5+
let _ = (1.0 + 2.0) * 3.0; //~ ERROR leading `+` is not supported
6+
//~| ERROR leading `+` is not supported
7+
let _ = [3, 4+6]; //~ ERROR leading `+` is not supported
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
#[allow(unused_parens)]
3+
fn main() {
4+
let _ = +1; //~ ERROR leading `+` is not supported
5+
let _ = (1.0 + +2.0) * +3.0; //~ ERROR leading `+` is not supported
6+
//~| ERROR leading `+` is not supported
7+
let _ = [+3, 4+6]; //~ ERROR leading `+` is not supported
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error: leading `+` is not supported
2+
--> $DIR/issue-88276-unary-plus.rs:4:13
3+
|
4+
LL | let _ = +1;
5+
| ^ unexpected `+`
6+
|
7+
help: try removing the `+`
8+
|
9+
LL - let _ = +1;
10+
LL + let _ = 1;
11+
|
12+
13+
error: leading `+` is not supported
14+
--> $DIR/issue-88276-unary-plus.rs:5:20
15+
|
16+
LL | let _ = (1.0 + +2.0) * +3.0;
17+
| ^ unexpected `+`
18+
|
19+
help: try removing the `+`
20+
|
21+
LL - let _ = (1.0 + +2.0) * +3.0;
22+
LL + let _ = (1.0 + 2.0) * +3.0;
23+
|
24+
25+
error: leading `+` is not supported
26+
--> $DIR/issue-88276-unary-plus.rs:5:28
27+
|
28+
LL | let _ = (1.0 + +2.0) * +3.0;
29+
| ^ unexpected `+`
30+
|
31+
help: try removing the `+`
32+
|
33+
LL - let _ = (1.0 + +2.0) * +3.0;
34+
LL + let _ = (1.0 + +2.0) * 3.0;
35+
|
36+
37+
error: leading `+` is not supported
38+
--> $DIR/issue-88276-unary-plus.rs:7:14
39+
|
40+
LL | let _ = [+3, 4+6];
41+
| ^ unexpected `+`
42+
|
43+
help: try removing the `+`
44+
|
45+
LL - let _ = [+3, 4+6];
46+
LL + let _ = [3, 4+6];
47+
|
48+
49+
error: aborting due to 4 previous errors
50+

0 commit comments

Comments
 (0)