Skip to content

Commit 8685d8f

Browse files
committed
Avoid redundant note when a #[derive] is already suggested
The `#[rustc_on_unimplemented]` note on `Debug` ("add `#[derive(Debug)]` to `X` or manually `impl Debug for X`") duplicates the `consider annotating X with #[derive(..)]` suggestion emitted by `suggest_derive`. Skip the note when that suggestion will be shown, and keep it otherwise so types whose derive can't be suggested (e.g. a field isn't `Debug`) still get actionable guidance.
1 parent 31a9463 commit 8685d8f

12 files changed

Lines changed: 59 additions & 14 deletions

File tree

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
448448
if let Some((msg, span)) = type_def {
449449
err.span_label(span, msg);
450450
}
451+
// `#[rustc_on_unimplemented]` notes for derivable traits (e.g. `Debug`'s
452+
// "add `#[derive(Debug)]` to `X` or manually `impl Debug for X`") duplicate
453+
// the `consider annotating X with #[derive(..)]` suggestion that
454+
// `suggest_derive` emits below, so skip them when that suggestion will be
455+
// shown. We keep the note otherwise (e.g. when a field isn't `Debug`, so
456+
// the derive can't be suggested) to avoid leaving the diagnostic without
457+
// actionable guidance.
458+
let derive_suggestion_will_be_shown = main_trait_predicate
459+
== leaf_trait_predicate
460+
&& self.can_suggest_derive(&obligation, leaf_trait_predicate);
451461
for note in notes {
452462
// If it has a custom `#[rustc_on_unimplemented]` note, let's display it
463+
if derive_suggestion_will_be_shown {
464+
continue;
465+
}
453466
err.note(note);
454467
}
455468
if let Some(s) = parent_label {

tests/ui/derives/debug/derives-span-Debug.stderr

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ LL | #[derive(Debug)]
77
LL | x: Error,
88
| ^^^^^^^^ the trait `Debug` is not implemented for `Error`
99
|
10-
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
1110
help: consider annotating `Error` with `#[derive(Debug)]`
1211
|
1312
LL + #[derive(Debug)]
@@ -23,7 +22,6 @@ LL | #[derive(Debug)]
2322
LL | Error,
2423
| ^^^^^ the trait `Debug` is not implemented for `Error`
2524
|
26-
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
2725
help: consider annotating `Error` with `#[derive(Debug)]`
2826
|
2927
LL + #[derive(Debug)]
@@ -39,7 +37,6 @@ LL | struct Struct {
3937
LL | x: Error,
4038
| ^^^^^^^^ the trait `Debug` is not implemented for `Error`
4139
|
42-
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
4340
help: consider annotating `Error` with `#[derive(Debug)]`
4441
|
4542
LL + #[derive(Debug)]
@@ -55,7 +52,6 @@ LL | struct TupleStruct(
5552
LL | Error,
5653
| ^^^^^ the trait `Debug` is not implemented for `Error`
5754
|
58-
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
5955
help: consider annotating `Error` with `#[derive(Debug)]`
6056
|
6157
LL + #[derive(Debug)]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Regression test for the redundant `note: add `#[derive(Debug)]` to `X` or manually
2+
// `impl Debug for X`` that was emitted alongside the `consider annotating X with
3+
// `#[derive(Debug)]`` suggestion. When the derive suggestion is shown, the note is
4+
// redundant and should be suppressed.
5+
//
6+
// See https://github.com/rust-lang/rust/issues/157118
7+
8+
#[derive(Debug)]
9+
struct S<T>(T);
10+
11+
struct X;
12+
13+
fn main() {
14+
println!("{:?}", S(X)); //~ ERROR `X` doesn't implement `Debug`
15+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error[E0277]: `X` doesn't implement `Debug`
2+
--> $DIR/redundant-derive-note-on-unimplemented.rs:14:22
3+
|
4+
LL | println!("{:?}", S(X));
5+
| ---- ^^^^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug`
6+
| |
7+
| required by this formatting parameter
8+
|
9+
= help: the trait `Debug` is not implemented for `X`
10+
help: the trait `Debug` is implemented for `S<T>`
11+
--> $DIR/redundant-derive-note-on-unimplemented.rs:8:10
12+
|
13+
LL | #[derive(Debug)]
14+
| ^^^^^
15+
note: required for `S<X>` to implement `Debug`
16+
--> $DIR/redundant-derive-note-on-unimplemented.rs:9:8
17+
|
18+
LL | #[derive(Debug)]
19+
| ----- in this derive macro expansion
20+
LL | struct S<T>(T);
21+
| ^ - type parameter would need to implement `Debug`
22+
= help: consider manually implementing `Debug` to avoid undesired bounds
23+
help: consider annotating `X` with `#[derive(Debug)]`
24+
|
25+
LL + #[derive(Debug)]
26+
LL | struct X;
27+
|
28+
29+
error: aborting due to 1 previous error
30+
31+
For more information about this error, try `rustc --explain E0277`.

tests/ui/fmt/format-args-argument-span.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ LL | println!("{x} {x:?} {x}");
2525
| ^^^^^ `DisplayOnly` cannot be formatted using `{:?}` because it doesn't implement `Debug`
2626
|
2727
= help: the trait `Debug` is not implemented for `DisplayOnly`
28-
= note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly`
2928
help: consider annotating `DisplayOnly` with `#[derive(Debug)]`
3029
|
3130
LL + #[derive(Debug)]
@@ -41,7 +40,6 @@ LL | println!("{x} {x:?} {x}", x = DisplayOnly);
4140
| required by this formatting parameter
4241
|
4342
= help: the trait `Debug` is not implemented for `DisplayOnly`
44-
= note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly`
4543
help: consider annotating `DisplayOnly` with `#[derive(Debug)]`
4644
|
4745
LL + #[derive(Debug)]

tests/ui/fmt/non-source-literals.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ LL | let _ = format!(concat!("{:", "?}"), NonDebug);
3131
| ^^^^^^^^ `NonDebug` cannot be formatted using `{:?}` because it doesn't implement `Debug`
3232
|
3333
= help: the trait `Debug` is not implemented for `NonDebug`
34-
= note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug`
3534
help: consider annotating `NonDebug` with `#[derive(Debug)]`
3635
|
3736
LL + #[derive(Debug)]
@@ -45,7 +44,6 @@ LL | let _ = format!(concat!("{", "0", ":?}"), NonDebug);
4544
| ^^^^^^^^ `NonDebug` cannot be formatted using `{:?}` because it doesn't implement `Debug`
4645
|
4746
= help: the trait `Debug` is not implemented for `NonDebug`
48-
= note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug`
4947
help: consider annotating `NonDebug` with `#[derive(Debug)]`
5048
|
5149
LL + #[derive(Debug)]

tests/ui/mismatched_types/method-help-unsatisfied-bound.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error[E0277]: `Foo` doesn't implement `Debug`
44
LL | a.unwrap();
55
| ^^^^^^ the trait `Debug` is not implemented for `Foo`
66
|
7-
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
87
note: required by a bound in `Result::<T, E>::unwrap`
98
--> $SRC_DIR/core/src/result.rs:LL:COL
109
help: consider annotating `Foo` with `#[derive(Debug)]`

tests/ui/modules/issue-107649.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error[E0277]: `Dummy` doesn't implement `Debug`
44
105 | dbg!(lib::Dummy);
55
| ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `Dummy`
66
|
7-
= note: add `#[derive(Debug)]` to `Dummy` or manually `impl Debug for Dummy`
87
help: consider annotating `Dummy` with `#[derive(Debug)]`
98
--> $DIR/auxiliary/dummy_lib.rs:2:1
109
|

tests/ui/on-unimplemented/no-debug.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ LL | println!("{:?} {:?}", Foo, Bar);
77
| required by this formatting parameter
88
|
99
= help: the trait `Debug` is not implemented for `Foo`
10-
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
1110
help: consider annotating `Foo` with `#[derive(Debug)]`
1211
|
1312
LL + #[derive(Debug)]

tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error[E0277]: `NotDebug` doesn't implement `Debug`
44
LL | let _: NotDebug = dbg!(NotDebug);
55
| ^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `NotDebug`
66
|
7-
= note: add `#[derive(Debug)]` to `NotDebug` or manually `impl Debug for NotDebug`
87
help: consider annotating `NotDebug` with `#[derive(Debug)]`
98
|
109
LL + #[derive(Debug)]

0 commit comments

Comments
 (0)