diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 14ad5830111b4..0cf33ef52b60d 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1317,7 +1317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let actual_prefix = rcvr_ty.prefix_string(self.tcx); info!("unimplemented_traits.len() == {}", unimplemented_traits.len()); let mut long_ty_file = None; - let (primary_message, label) = if unimplemented_traits.len() == 1 + let (primary_message, label, notes) = if unimplemented_traits.len() == 1 && unimplemented_traits_only { unimplemented_traits @@ -1327,16 +1327,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if trait_ref.self_ty().references_error() || rcvr_ty.references_error() { // Avoid crashing. - return (None, None); + return (None, None, Vec::new()); } - let OnUnimplementedNote { message, label, .. } = self + let OnUnimplementedNote { message, label, notes, .. } = self .err_ctxt() .on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file); - (message, label) + (message, label, notes) }) .unwrap() } else { - (None, None) + (None, None, Vec::new()) }; let primary_message = primary_message.unwrap_or_else(|| { format!( @@ -1363,6 +1363,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "the following trait bounds were not satisfied:\n{bound_list}" )); } + for note in notes { + debug!("FCB {}", note); + err.note(note); + } + suggested_derive = self.suggest_derive(&mut err, unsatisfied_predicates); unsatisfied_bounds = true; diff --git a/tests/ui/methods/suggest-convert-ptr-to-ref.stderr b/tests/ui/methods/suggest-convert-ptr-to-ref.stderr index 69b20d57be829..0e1565e251adc 100644 --- a/tests/ui/methods/suggest-convert-ptr-to-ref.stderr +++ b/tests/ui/methods/suggest-convert-ptr-to-ref.stderr @@ -11,6 +11,7 @@ note: the method `to_string` exists on the type `&u8` = note: the following trait bounds were not satisfied: `*const u8: std::fmt::Display` which is required by `*const u8: ToString` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead error[E0599]: `*mut u8` doesn't implement `std::fmt::Display` --> $DIR/suggest-convert-ptr-to-ref.rs:8:22 @@ -25,6 +26,7 @@ note: the method `to_string` exists on the type `&&mut u8` = note: the following trait bounds were not satisfied: `*mut u8: std::fmt::Display` which is required by `*mut u8: ToString` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead error[E0599]: no method named `make_ascii_lowercase` found for raw pointer `*mut u8` in the current scope --> $DIR/suggest-convert-ptr-to-ref.rs:9:7 diff --git a/tests/ui/traits/custom-on-unimplemented-diagnostic.rs b/tests/ui/traits/custom-on-unimplemented-diagnostic.rs new file mode 100644 index 0000000000000..4f94cfb7747a5 --- /dev/null +++ b/tests/ui/traits/custom-on-unimplemented-diagnostic.rs @@ -0,0 +1,19 @@ +#[diagnostic::on_unimplemented(message = "my message", label = "my label", note = "my note")] +pub trait ProviderLt {} + +pub trait ProviderExt { + fn request(&self) { + todo!() + } +} + +impl ProviderExt for T {} + +struct B; + +fn main() { + B.request(); +} +//~^^ my message [E0599] +//~| my label +//~| my note diff --git a/tests/ui/traits/custom-on-unimplemented-diagnostic.stderr b/tests/ui/traits/custom-on-unimplemented-diagnostic.stderr new file mode 100644 index 0000000000000..f9788360d06ad --- /dev/null +++ b/tests/ui/traits/custom-on-unimplemented-diagnostic.stderr @@ -0,0 +1,32 @@ +error[E0599]: my message + --> $DIR/custom-on-unimplemented-diagnostic.rs:15:7 + | +LL | struct B; + | -------- method `request` not found for this struct because it doesn't satisfy `B: ProviderExt` or `B: ProviderLt` +... +LL | B.request(); + | ^^^^^^^ my label + | +note: trait bound `B: ProviderLt` was not satisfied + --> $DIR/custom-on-unimplemented-diagnostic.rs:10:18 + | +LL | impl ProviderExt for T {} + | ^^^^^^^^^^ ----------- - + | | + | unsatisfied trait bound introduced here + = note: my note +note: the trait `ProviderLt` must be implemented + --> $DIR/custom-on-unimplemented-diagnostic.rs:2:1 + | +LL | pub trait ProviderLt {} + | ^^^^^^^^^^^^^^^^^^^^ + = help: items from traits can only be used if the trait is implemented and in scope +note: `ProviderExt` defines an item `request`, perhaps you need to implement it + --> $DIR/custom-on-unimplemented-diagnostic.rs:4:1 + | +LL | pub trait ProviderExt { + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/traits/on-unimplemented-diagnostic.rs b/tests/ui/traits/on-unimplemented-diagnostic.rs new file mode 100644 index 0000000000000..7c0e12d43e430 --- /dev/null +++ b/tests/ui/traits/on-unimplemented-diagnostic.rs @@ -0,0 +1,15 @@ +pub trait ProviderLt {} + +pub trait ProviderExt { + fn request(&self) { + todo!() + } +} + +impl ProviderExt for T {} + +struct B; + +fn main() { + B.request(); //~ ERROR 14:7: 14:14: the method `request` exists for struct `B`, but its trait bounds were not satisfied [E0599] +} diff --git a/tests/ui/traits/on-unimplemented-diagnostic.stderr b/tests/ui/traits/on-unimplemented-diagnostic.stderr new file mode 100644 index 0000000000000..e3cec956125d2 --- /dev/null +++ b/tests/ui/traits/on-unimplemented-diagnostic.stderr @@ -0,0 +1,31 @@ +error[E0599]: the method `request` exists for struct `B`, but its trait bounds were not satisfied + --> $DIR/on-unimplemented-diagnostic.rs:14:7 + | +LL | struct B; + | -------- method `request` not found for this struct because it doesn't satisfy `B: ProviderExt` or `B: ProviderLt` +... +LL | B.request(); + | ^^^^^^^ method cannot be called on `B` due to unsatisfied trait bounds + | +note: trait bound `B: ProviderLt` was not satisfied + --> $DIR/on-unimplemented-diagnostic.rs:9:18 + | +LL | impl ProviderExt for T {} + | ^^^^^^^^^^ ----------- - + | | + | unsatisfied trait bound introduced here +note: the trait `ProviderLt` must be implemented + --> $DIR/on-unimplemented-diagnostic.rs:1:1 + | +LL | pub trait ProviderLt {} + | ^^^^^^^^^^^^^^^^^^^^ + = help: items from traits can only be used if the trait is implemented and in scope +note: `ProviderExt` defines an item `request`, perhaps you need to implement it + --> $DIR/on-unimplemented-diagnostic.rs:3:1 + | +LL | pub trait ProviderExt { + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs deleted file mode 100644 index 60c3327902e11..0000000000000 --- a/tests/ui/traits/on_unimplemented_long_types.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes -//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" - -pub fn foo() -> impl std::fmt::Display { - //~^ ERROR doesn't implement `std::fmt::Display` - Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( - Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( - Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( - Some(Some(Some(Some(Some(Some(Some(Some(Some(Some(Some( - Some(Some(Some(Some(Some(Some(Some(Some(())))))))), - ))))))))))), - ))))))))))), - ))))))))))), - ))))))))))) -} - -fn main() {} diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr deleted file mode 100644 index bddc5695696b5..0000000000000 --- a/tests/ui/traits/on_unimplemented_long_types.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error[E0277]: `Option>>` doesn't implement `std::fmt::Display` - --> $DIR/on_unimplemented_long_types.rs:4:17 - | -LL | pub fn foo() -> impl std::fmt::Display { - | ^^^^^^^^^^^^^^^^^^^^^^ `Option>>` cannot be formatted with the default formatter -LL | -LL | / Some(Some(Some(Some(Some(Some(Some(Some(Some(S... -LL | | Some(Some(Some(Some(Some(Some(Some(Some(So... -LL | | Some(Some(Some(Some(Some(Some(Some(Som... -LL | | Some(Some(Some(Some(Some(Some(Some... -... | -LL | | ))))))))))), -LL | | ))))))))))) - | |_______________- return type was inferred to be `Option>>` here - | - = note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt' - = note: consider using `--verbose` to print the full type name to the console - = help: the trait `std::fmt::Display` is not implemented for `Option>>` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt' - = note: consider using `--verbose` to print the full type name to the console - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`.