Skip to content

Commit 6242335

Browse files
committed
Improve diagnostic for E0178 (bad + in type)
Namely, use a more sensical primary span. Don't pretty-print AST nodes for the diagnostic message. Why: * It's lossy (e.g., it doesn't replicate trailing `+`s in trait objects. * It's prone to leak error nodes (printed as `(/*ERROR*/)`) since the LHS can easily represent recovered code (e.g., `fn(i32?) + T`).
1 parent 8887af7 commit 6242335

14 files changed

+51
-52
lines changed

Diff for: compiler/rustc_parse/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ parse_maybe_recover_from_bad_qpath_stage_2 =
543543
.suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
544544
545545
parse_maybe_recover_from_bad_type_plus =
546-
expected a path on the left-hand side of `+`, not `{$ty}`
546+
expected a path on the left-hand side of `+`
547547
548548
parse_maybe_report_ambiguous_plus =
549549
ambiguous `+` in a type

Diff for: compiler/rustc_parse/src/errors.rs

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ pub(crate) struct AmbiguousPlus {
3030
#[derive(Diagnostic)]
3131
#[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)]
3232
pub(crate) struct BadTypePlus {
33-
pub ty: String,
3433
#[primary_span]
3534
pub span: Span,
3635
#[subdiagnostic]

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -1636,19 +1636,19 @@ impl<'a> Parser<'a> {
16361636

16371637
self.bump(); // `+`
16381638
let _bounds = self.parse_generic_bounds()?;
1639-
let sum_span = ty.span.to(self.prev_token.span);
1640-
16411639
let sub = match &ty.kind {
16421640
TyKind::Ref(_lifetime, mut_ty) => {
16431641
let lo = mut_ty.ty.span.shrink_to_lo();
16441642
let hi = self.prev_token.span.shrink_to_hi();
16451643
BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } }
16461644
}
1647-
TyKind::Ptr(..) | TyKind::BareFn(..) => BadTypePlusSub::ForgotParen { span: sum_span },
1648-
_ => BadTypePlusSub::ExpectPath { span: sum_span },
1645+
TyKind::Ptr(..) | TyKind::BareFn(..) => {
1646+
BadTypePlusSub::ForgotParen { span: ty.span.to(self.prev_token.span) }
1647+
}
1648+
_ => BadTypePlusSub::ExpectPath { span: ty.span },
16491649
};
16501650

1651-
self.dcx().emit_err(BadTypePlus { ty: pprust::ty_to_string(ty), span: sum_span, sub });
1651+
self.dcx().emit_err(BadTypePlus { span: ty.span, sub });
16521652

16531653
Ok(())
16541654
}

Diff for: tests/ui/did_you_mean/E0178.stderr

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
1-
error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
1+
error[E0178]: expected a path on the left-hand side of `+`
22
--> $DIR/E0178.rs:6:8
33
|
44
LL | w: &'a Foo + Copy,
5-
| ^^^^^^^^^^^^^^
5+
| ^^^^^^^
66
|
77
help: try adding parentheses
88
|
99
LL | w: &'a (Foo + Copy),
1010
| + +
1111

12-
error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
12+
error[E0178]: expected a path on the left-hand side of `+`
1313
--> $DIR/E0178.rs:7:8
1414
|
1515
LL | x: &'a Foo + 'a,
16-
| ^^^^^^^^^^^^
16+
| ^^^^^^^
1717
|
1818
help: try adding parentheses
1919
|
2020
LL | x: &'a (Foo + 'a),
2121
| + +
2222

23-
error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo`
23+
error[E0178]: expected a path on the left-hand side of `+`
2424
--> $DIR/E0178.rs:8:8
2525
|
2626
LL | y: &'a mut Foo + 'a,
27-
| ^^^^^^^^^^^^^^^^
27+
| ^^^^^^^^^^^
2828
|
2929
help: try adding parentheses
3030
|
3131
LL | y: &'a mut (Foo + 'a),
3232
| + +
3333

34-
error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
34+
error[E0178]: expected a path on the left-hand side of `+`
3535
--> $DIR/E0178.rs:9:8
3636
|
3737
LL | z: fn() -> Foo + 'a,
38-
| ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses?
38+
| ^^^^^^^^^^^-----
39+
| |
40+
| perhaps you forgot parentheses?
3941

4042
error: aborting due to 4 previous errors
4143

Diff for: tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
error[E0178]: expected a path on the left-hand side of `+`, not `&Copy`
1+
error[E0178]: expected a path on the left-hand side of `+`
22
--> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
33
|
44
LL | let _: &Copy + 'static;
5-
| ^^^^^^^^^^^^^^^
5+
| ^^^^^
66
|
77
help: try adding parentheses
88
|
99
LL | let _: &(Copy + 'static);
1010
| + +
1111

12-
error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy`
12+
error[E0178]: expected a path on the left-hand side of `+`
1313
--> $DIR/trait-object-reference-without-parens-suggestion.rs:6:12
1414
|
1515
LL | let _: &'static Copy + 'static;
16-
| ^^^^^^^^^^^^^^^^^^^^^^^
16+
| ^^^^^^^^^^^^^
1717
|
1818
help: try adding parentheses
1919
|

Diff for: tests/ui/impl-trait/impl-trait-plus-priority.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type A = fn() -> impl A + B;
2727
type A = fn() -> dyn A + B;
2828
//~^ ERROR ambiguous `+` in a type
2929
type A = fn() -> A + B;
30-
//~^ ERROR expected a path on the left-hand side of `+`, not `fn() -> A`
30+
//~^ ERROR expected a path on the left-hand side of `+`
3131

3232
type A = Fn() -> impl A +;
3333
//~^ ERROR ambiguous `+` in a type
@@ -44,6 +44,6 @@ type A = &impl A + B;
4444
type A = &dyn A + B;
4545
//~^ ERROR ambiguous `+` in a type
4646
type A = &A + B;
47-
//~^ ERROR expected a path on the left-hand side of `+`, not `&A`
47+
//~^ ERROR expected a path on the left-hand side of `+`
4848

4949
fn main() {}

Diff for: tests/ui/impl-trait/impl-trait-plus-priority.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ help: try adding parentheses
3131
LL | type A = fn() -> (dyn A + B);
3232
| + +
3333

34-
error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> A`
34+
error[E0178]: expected a path on the left-hand side of `+`
3535
--> $DIR/impl-trait-plus-priority.rs:29:10
3636
|
3737
LL | type A = fn() -> A + B;
38-
| ^^^^^^^^^^^^^ perhaps you forgot parentheses?
38+
| ^^^^^^^^^----
39+
| |
40+
| perhaps you forgot parentheses?
3941

4042
error: ambiguous `+` in a type
4143
--> $DIR/impl-trait-plus-priority.rs:32:18
@@ -103,11 +105,11 @@ help: try adding parentheses
103105
LL | type A = &(dyn A + B);
104106
| + +
105107

106-
error[E0178]: expected a path on the left-hand side of `+`, not `&A`
108+
error[E0178]: expected a path on the left-hand side of `+`
107109
--> $DIR/impl-trait-plus-priority.rs:46:10
108110
|
109111
LL | type A = &A + B;
110-
| ^^^^^^
112+
| ^^
111113
|
112114
help: try adding parentheses
113115
|

Diff for: tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ mac!('a);
1212

1313
// avoid false positives
1414
fn y<'a>(y: &mut 'a + Send) {
15-
//~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a`
15+
//~^ ERROR expected a path on the left-hand side of `+`
1616
//~| ERROR at least one trait is required for an object type
1717
let z = y as &mut 'a + Send;
1818
//~^ ERROR expected value, found trait `Send`

Diff for: tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ LL - fn x<'a>(x: &mut 'a i32){}
1010
LL + fn x<'a>(x: &'a mut i32){}
1111
|
1212

13-
error[E0178]: expected a path on the left-hand side of `+`, not `&mut 'a`
13+
error[E0178]: expected a path on the left-hand side of `+`
1414
--> $DIR/issue-73568-lifetime-after-mut.rs:14:13
1515
|
1616
LL | fn y<'a>(y: &mut 'a + Send) {
17-
| ^^^^^^^^^^^^^^
17+
| ^^^^^^^
1818
|
1919
help: try adding parentheses
2020
|

Diff for: tests/ui/parser/trait-object-bad-parens.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@
55
auto trait Auto {}
66

77
fn main() {
8-
let _: Box<((Auto)) + Auto>;
9-
//~^ ERROR expected a path on the left-hand side of `+`, not `((Auto))`
10-
let _: Box<(Auto + Auto) + Auto>;
11-
//~^ ERROR expected a path on the left-hand side of `+`, not `(Auto + Auto)`
12-
let _: Box<(Auto +) + Auto>;
13-
//~^ ERROR expected a path on the left-hand side of `+`, not `(Auto)`
14-
let _: Box<(dyn Auto) + Auto>;
15-
//~^ ERROR expected a path on the left-hand side of `+`, not `(dyn Auto)`
8+
let _: Box<((Auto)) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
9+
let _: Box<(Auto + Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
10+
let _: Box<(Auto +) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
11+
let _: Box<(dyn Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
1612
}

Diff for: tests/ui/parser/trait-object-bad-parens.stderr

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))`
1+
error[E0178]: expected a path on the left-hand side of `+`
22
--> $DIR/trait-object-bad-parens.rs:8:16
33
|
44
LL | let _: Box<((Auto)) + Auto>;
5-
| ^^^^^^^^^^^^^^^ expected a path
5+
| ^^^^^^^^ expected a path
66

7-
error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)`
8-
--> $DIR/trait-object-bad-parens.rs:10:16
7+
error[E0178]: expected a path on the left-hand side of `+`
8+
--> $DIR/trait-object-bad-parens.rs:9:16
99
|
1010
LL | let _: Box<(Auto + Auto) + Auto>;
11-
| ^^^^^^^^^^^^^^^^^^^^ expected a path
11+
| ^^^^^^^^^^^^^ expected a path
1212

13-
error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)`
14-
--> $DIR/trait-object-bad-parens.rs:12:16
13+
error[E0178]: expected a path on the left-hand side of `+`
14+
--> $DIR/trait-object-bad-parens.rs:10:16
1515
|
1616
LL | let _: Box<(Auto +) + Auto>;
17-
| ^^^^^^^^^^^^^^^ expected a path
17+
| ^^^^^^^^ expected a path
1818

19-
error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)`
20-
--> $DIR/trait-object-bad-parens.rs:14:16
19+
error[E0178]: expected a path on the left-hand side of `+`
20+
--> $DIR/trait-object-bad-parens.rs:11:16
2121
|
2222
LL | let _: Box<(dyn Auto) + Auto>;
23-
| ^^^^^^^^^^^^^^^^^ expected a path
23+
| ^^^^^^^^^^ expected a path
2424

2525
error: aborting due to 4 previous errors
2626

Diff for: tests/ui/parser/trait-object-lifetime-parens.e2021.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ error: expected type, found lifetime
2828
LL | let _: Box<('a) + Trait>;
2929
| ^^ expected type
3030

31-
error[E0178]: expected a path on the left-hand side of `+`, not `((/*ERROR*/))`
31+
error[E0178]: expected a path on the left-hand side of `+`
3232
--> $DIR/trait-object-lifetime-parens.rs:16:16
3333
|
3434
LL | let _: Box<('a) + Trait>;
35-
| ^^^^^^^^^^^^ expected a path
35+
| ^^^^ expected a path
3636

3737
error[E0782]: expected a type, found a trait
3838
--> $DIR/trait-object-lifetime-parens.rs:12:16

Diff for: tests/ui/parser/trait-object-polytrait-priority.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ trait Trait<'a> {}
44

55
fn main() {
66
let _: &for<'a> Trait<'a> + 'static;
7-
//~^ ERROR expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
7+
//~^ ERROR expected a path on the left-hand side of `+`
88
//~| HELP try adding parentheses
99
}

Diff for: tests/ui/parser/trait-object-polytrait-priority.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0178]: expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
1+
error[E0178]: expected a path on the left-hand side of `+`
22
--> $DIR/trait-object-polytrait-priority.rs:6:12
33
|
44
LL | let _: &for<'a> Trait<'a> + 'static;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^
66
|
77
help: try adding parentheses
88
|

0 commit comments

Comments
 (0)