about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2025-04-15 07:44:24 +0200
committerLeón Orell Valerian Liehr <me@fmease.dev>2025-04-15 10:08:49 +0200
commit6242335fdb7444876abf1c3669b6aab1649a0a64 (patch)
tree4eebc86603d28b2ceba1cfe8abb60c7fad06e802
parent8887af72a0b1f37a34b02d488ca3278576e2d73d (diff)
downloadrust-6242335fdb7444876abf1c3669b6aab1649a0a64.tar.gz
rust-6242335fdb7444876abf1c3669b6aab1649a0a64.zip
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`).
-rw-r--r--compiler/rustc_parse/messages.ftl2
-rw-r--r--compiler/rustc_parse/src/errors.rs1
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs10
-rw-r--r--tests/ui/did_you_mean/E0178.stderr18
-rw-r--r--tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr8
-rw-r--r--tests/ui/impl-trait/impl-trait-plus-priority.rs4
-rw-r--r--tests/ui/impl-trait/impl-trait-plus-priority.stderr10
-rw-r--r--tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs2
-rw-r--r--tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr4
-rw-r--r--tests/ui/parser/trait-object-bad-parens.rs12
-rw-r--r--tests/ui/parser/trait-object-bad-parens.stderr22
-rw-r--r--tests/ui/parser/trait-object-lifetime-parens.e2021.stderr4
-rw-r--r--tests/ui/parser/trait-object-polytrait-priority.rs2
-rw-r--r--tests/ui/parser/trait-object-polytrait-priority.stderr4
14 files changed, 51 insertions, 52 deletions
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index e2b5e1cdd0a..80cd87a69f7 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -543,7 +543,7 @@ parse_maybe_recover_from_bad_qpath_stage_2 =
     .suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
 
 parse_maybe_recover_from_bad_type_plus =
-    expected a path on the left-hand side of `+`, not `{$ty}`
+    expected a path on the left-hand side of `+`
 
 parse_maybe_report_ambiguous_plus =
     ambiguous `+` in a type
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index b28939e062a..aad8a8bc205 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -30,7 +30,6 @@ pub(crate) struct AmbiguousPlus {
 #[derive(Diagnostic)]
 #[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)]
 pub(crate) struct BadTypePlus {
-    pub ty: String,
     #[primary_span]
     pub span: Span,
     #[subdiagnostic]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index ef044fe9d63..40246ed78be 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1636,19 +1636,19 @@ impl<'a> Parser<'a> {
 
         self.bump(); // `+`
         let _bounds = self.parse_generic_bounds()?;
-        let sum_span = ty.span.to(self.prev_token.span);
-
         let sub = match &ty.kind {
             TyKind::Ref(_lifetime, mut_ty) => {
                 let lo = mut_ty.ty.span.shrink_to_lo();
                 let hi = self.prev_token.span.shrink_to_hi();
                 BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } }
             }
-            TyKind::Ptr(..) | TyKind::BareFn(..) => BadTypePlusSub::ForgotParen { span: sum_span },
-            _ => BadTypePlusSub::ExpectPath { span: sum_span },
+            TyKind::Ptr(..) | TyKind::BareFn(..) => {
+                BadTypePlusSub::ForgotParen { span: ty.span.to(self.prev_token.span) }
+            }
+            _ => BadTypePlusSub::ExpectPath { span: ty.span },
         };
 
-        self.dcx().emit_err(BadTypePlus { ty: pprust::ty_to_string(ty), span: sum_span, sub });
+        self.dcx().emit_err(BadTypePlus { span: ty.span, sub });
 
         Ok(())
     }
diff --git a/tests/ui/did_you_mean/E0178.stderr b/tests/ui/did_you_mean/E0178.stderr
index 5f289da8a6c..36e4dbdf7c4 100644
--- a/tests/ui/did_you_mean/E0178.stderr
+++ b/tests/ui/did_you_mean/E0178.stderr
@@ -1,41 +1,43 @@
-error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/E0178.rs:6:8
    |
 LL |     w: &'a Foo + Copy,
-   |        ^^^^^^^^^^^^^^
+   |        ^^^^^^^
    |
 help: try adding parentheses
    |
 LL |     w: &'a (Foo + Copy),
    |            +          +
 
-error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/E0178.rs:7:8
    |
 LL |     x: &'a Foo + 'a,
-   |        ^^^^^^^^^^^^
+   |        ^^^^^^^
    |
 help: try adding parentheses
    |
 LL |     x: &'a (Foo + 'a),
    |            +        +
 
-error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/E0178.rs:8:8
    |
 LL |     y: &'a mut Foo + 'a,
-   |        ^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^
    |
 help: try adding parentheses
    |
 LL |     y: &'a mut (Foo + 'a),
    |                +        +
 
-error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/E0178.rs:9:8
    |
 LL |     z: fn() -> Foo + 'a,
-   |        ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses?
+   |        ^^^^^^^^^^^-----
+   |        |
+   |        perhaps you forgot parentheses?
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
index 4fee6cc9a22..762b37b9e9d 100644
--- a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
+++ b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr
@@ -1,19 +1,19 @@
-error[E0178]: expected a path on the left-hand side of `+`, not `&Copy`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12
    |
 LL |     let _: &Copy + 'static;
-   |            ^^^^^^^^^^^^^^^
+   |            ^^^^^
    |
 help: try adding parentheses
    |
 LL |     let _: &(Copy + 'static);
    |             +              +
 
-error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/trait-object-reference-without-parens-suggestion.rs:6:12
    |
 LL |     let _: &'static Copy + 'static;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^
    |
 help: try adding parentheses
    |
diff --git a/tests/ui/impl-trait/impl-trait-plus-priority.rs b/tests/ui/impl-trait/impl-trait-plus-priority.rs
index 5575493a17d..8f76d412662 100644
--- a/tests/ui/impl-trait/impl-trait-plus-priority.rs
+++ b/tests/ui/impl-trait/impl-trait-plus-priority.rs
@@ -27,7 +27,7 @@ type A = fn() -> impl A + B;
 type A = fn() -> dyn A + B;
 //~^ ERROR ambiguous `+` in a type
 type A = fn() -> A + B;
-//~^ ERROR expected a path on the left-hand side of `+`, not `fn() -> A`
+//~^ ERROR expected a path on the left-hand side of `+`
 
 type A = Fn() -> impl A +;
 //~^ ERROR ambiguous `+` in a type
@@ -44,6 +44,6 @@ type A = &impl A + B;
 type A = &dyn A + B;
 //~^ ERROR ambiguous `+` in a type
 type A = &A + B;
-//~^ ERROR expected a path on the left-hand side of `+`, not `&A`
+//~^ ERROR expected a path on the left-hand side of `+`
 
 fn main() {}
diff --git a/tests/ui/impl-trait/impl-trait-plus-priority.stderr b/tests/ui/impl-trait/impl-trait-plus-priority.stderr
index 03e7910095a..16120657960 100644
--- a/tests/ui/impl-trait/impl-trait-plus-priority.stderr
+++ b/tests/ui/impl-trait/impl-trait-plus-priority.stderr
@@ -31,11 +31,13 @@ help: try adding parentheses
 LL | type A = fn() -> (dyn A + B);
    |                  +         +
 
-error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> A`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/impl-trait-plus-priority.rs:29:10
    |
 LL | type A = fn() -> A + B;
-   |          ^^^^^^^^^^^^^ perhaps you forgot parentheses?
+   |          ^^^^^^^^^----
+   |          |
+   |          perhaps you forgot parentheses?
 
 error: ambiguous `+` in a type
   --> $DIR/impl-trait-plus-priority.rs:32:18
@@ -103,11 +105,11 @@ help: try adding parentheses
 LL | type A = &(dyn A + B);
    |           +         +
 
-error[E0178]: expected a path on the left-hand side of `+`, not `&A`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/impl-trait-plus-priority.rs:46:10
    |
 LL | type A = &A + B;
-   |          ^^^^^^
+   |          ^^
    |
 help: try adding parentheses
    |
diff --git a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs
index cf754a6854e..782a46ab060 100644
--- a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs
+++ b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs
@@ -12,7 +12,7 @@ mac!('a);
 
 // avoid false positives
 fn y<'a>(y: &mut 'a + Send) {
-    //~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a`
+    //~^ ERROR expected a path on the left-hand side of `+`
     //~| ERROR at least one trait is required for an object type
     let z = y as &mut 'a + Send;
     //~^ ERROR expected value, found trait `Send`
diff --git a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr
index 6b8f8e4fe4e..ae1ed72853d 100644
--- a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr
+++ b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr
@@ -10,11 +10,11 @@ LL - fn x<'a>(x: &mut 'a i32){}
 LL + fn x<'a>(x: &'a mut i32){}
    |
 
-error[E0178]: expected a path on the left-hand side of `+`, not `&mut 'a`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/issue-73568-lifetime-after-mut.rs:14:13
    |
 LL | fn y<'a>(y: &mut 'a + Send) {
-   |             ^^^^^^^^^^^^^^
+   |             ^^^^^^^
    |
 help: try adding parentheses
    |
diff --git a/tests/ui/parser/trait-object-bad-parens.rs b/tests/ui/parser/trait-object-bad-parens.rs
index 8e267c7448f..bb047a4b431 100644
--- a/tests/ui/parser/trait-object-bad-parens.rs
+++ b/tests/ui/parser/trait-object-bad-parens.rs
@@ -5,12 +5,8 @@
 auto trait Auto {}
 
 fn main() {
-    let _: Box<((Auto)) + Auto>;
-    //~^ ERROR expected a path on the left-hand side of `+`, not `((Auto))`
-    let _: Box<(Auto + Auto) + Auto>;
-    //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto + Auto)`
-    let _: Box<(Auto +) + Auto>;
-    //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto)`
-    let _: Box<(dyn Auto) + Auto>;
-    //~^ ERROR expected a path on the left-hand side of `+`, not `(dyn Auto)`
+    let _: Box<((Auto)) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
+    let _: Box<(Auto + Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
+    let _: Box<(Auto +) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
+    let _: Box<(dyn Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+`
 }
diff --git a/tests/ui/parser/trait-object-bad-parens.stderr b/tests/ui/parser/trait-object-bad-parens.stderr
index 74e484eebee..7c2559ce89f 100644
--- a/tests/ui/parser/trait-object-bad-parens.stderr
+++ b/tests/ui/parser/trait-object-bad-parens.stderr
@@ -1,26 +1,26 @@
-error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/trait-object-bad-parens.rs:8:16
    |
 LL |     let _: Box<((Auto)) + Auto>;
-   |                ^^^^^^^^^^^^^^^ expected a path
+   |                ^^^^^^^^ expected a path
 
-error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)`
-  --> $DIR/trait-object-bad-parens.rs:10:16
+error[E0178]: expected a path on the left-hand side of `+`
+  --> $DIR/trait-object-bad-parens.rs:9:16
    |
 LL |     let _: Box<(Auto + Auto) + Auto>;
-   |                ^^^^^^^^^^^^^^^^^^^^ expected a path
+   |                ^^^^^^^^^^^^^ expected a path
 
-error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)`
-  --> $DIR/trait-object-bad-parens.rs:12:16
+error[E0178]: expected a path on the left-hand side of `+`
+  --> $DIR/trait-object-bad-parens.rs:10:16
    |
 LL |     let _: Box<(Auto +) + Auto>;
-   |                ^^^^^^^^^^^^^^^ expected a path
+   |                ^^^^^^^^ expected a path
 
-error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)`
-  --> $DIR/trait-object-bad-parens.rs:14:16
+error[E0178]: expected a path on the left-hand side of `+`
+  --> $DIR/trait-object-bad-parens.rs:11:16
    |
 LL |     let _: Box<(dyn Auto) + Auto>;
-   |                ^^^^^^^^^^^^^^^^^ expected a path
+   |                ^^^^^^^^^^ expected a path
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/parser/trait-object-lifetime-parens.e2021.stderr b/tests/ui/parser/trait-object-lifetime-parens.e2021.stderr
index 3518321ea20..b65c079788a 100644
--- a/tests/ui/parser/trait-object-lifetime-parens.e2021.stderr
+++ b/tests/ui/parser/trait-object-lifetime-parens.e2021.stderr
@@ -28,11 +28,11 @@ error: expected type, found lifetime
 LL |     let _: Box<('a) + Trait>;
    |                 ^^ expected type
 
-error[E0178]: expected a path on the left-hand side of `+`, not `((/*ERROR*/))`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/trait-object-lifetime-parens.rs:16:16
    |
 LL |     let _: Box<('a) + Trait>;
-   |                ^^^^^^^^^^^^ expected a path
+   |                ^^^^ expected a path
 
 error[E0782]: expected a type, found a trait
   --> $DIR/trait-object-lifetime-parens.rs:12:16
diff --git a/tests/ui/parser/trait-object-polytrait-priority.rs b/tests/ui/parser/trait-object-polytrait-priority.rs
index e7f085104ae..85568f0fe1b 100644
--- a/tests/ui/parser/trait-object-polytrait-priority.rs
+++ b/tests/ui/parser/trait-object-polytrait-priority.rs
@@ -4,6 +4,6 @@ trait Trait<'a> {}
 
 fn main() {
     let _: &for<'a> Trait<'a> + 'static;
-    //~^ ERROR expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
+    //~^ ERROR expected a path on the left-hand side of `+`
     //~| HELP try adding parentheses
 }
diff --git a/tests/ui/parser/trait-object-polytrait-priority.stderr b/tests/ui/parser/trait-object-polytrait-priority.stderr
index 8cb564e7930..a291a8e229c 100644
--- a/tests/ui/parser/trait-object-polytrait-priority.stderr
+++ b/tests/ui/parser/trait-object-polytrait-priority.stderr
@@ -1,8 +1,8 @@
-error[E0178]: expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>`
+error[E0178]: expected a path on the left-hand side of `+`
   --> $DIR/trait-object-polytrait-priority.rs:6:12
    |
 LL |     let _: &for<'a> Trait<'a> + 'static;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
 help: try adding parentheses
    |