Rollup merge of #130123 - FedericoBruzzone:master, r=compiler-errors

Report the `note` when specified in `diagnostic::on_unimplemented`

Before this PR the `note` field was completely ignored for some reason, now it is shown (I think) correctly during the hir typechecking phase.

1. Report the `note` when specified in `diagnostic::on_unimplemented`
2. Added a test for unimplemented trait diagnostic
3. Added a test for custom unimplemented trait diagnostic

Close #130084

P.S. This is my first PR to rustc.
This commit is contained in:
Matthias Krüger 2024-09-11 20:04:23 +02:00 committed by GitHub
commit 5107ff4322
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 5 deletions

View File

@ -1317,7 +1317,7 @@ fn report_no_match_method_error(
let actual_prefix = rcvr_ty.prefix_string(self.tcx); let actual_prefix = rcvr_ty.prefix_string(self.tcx);
info!("unimplemented_traits.len() == {}", unimplemented_traits.len()); info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
let mut long_ty_file = None; 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_only
{ {
unimplemented_traits unimplemented_traits
@ -1327,16 +1327,16 @@ fn report_no_match_method_error(
if trait_ref.self_ty().references_error() || rcvr_ty.references_error() if trait_ref.self_ty().references_error() || rcvr_ty.references_error()
{ {
// Avoid crashing. // Avoid crashing.
return (None, None); return (None, None, Vec::new());
} }
let OnUnimplementedNote { message, label, .. } = self let OnUnimplementedNote { message, label, notes, .. } = self
.err_ctxt() .err_ctxt()
.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file); .on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
(message, label) (message, label, notes)
}) })
.unwrap() .unwrap()
} else { } else {
(None, None) (None, None, Vec::new())
}; };
let primary_message = primary_message.unwrap_or_else(|| { let primary_message = primary_message.unwrap_or_else(|| {
format!( format!(
@ -1363,6 +1363,10 @@ fn report_no_match_method_error(
"the following trait bounds were not satisfied:\n{bound_list}" "the following trait bounds were not satisfied:\n{bound_list}"
)); ));
} }
for note in notes {
err.note(note);
}
suggested_derive = self.suggest_derive(&mut err, unsatisfied_predicates); suggested_derive = self.suggest_derive(&mut err, unsatisfied_predicates);
unsatisfied_bounds = true; unsatisfied_bounds = true;

View File

@ -11,6 +11,7 @@ note: the method `to_string` exists on the type `&u8`
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`*const u8: std::fmt::Display` `*const u8: std::fmt::Display`
which is required by `*const u8: ToString` 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` error[E0599]: `*mut u8` doesn't implement `std::fmt::Display`
--> $DIR/suggest-convert-ptr-to-ref.rs:8:22 --> $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: = note: the following trait bounds were not satisfied:
`*mut u8: std::fmt::Display` `*mut u8: std::fmt::Display`
which is required by `*mut u8: ToString` 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 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 --> $DIR/suggest-convert-ptr-to-ref.rs:9:7

View File

@ -0,0 +1,19 @@
#[diagnostic::on_unimplemented(message = "my message", label = "my label", note = "my note")]
pub trait ProviderLt {}
pub trait ProviderExt {
fn request<R>(&self) {
todo!()
}
}
impl<T: ?Sized + ProviderLt> ProviderExt for T {}
struct B;
fn main() {
B.request();
//~^ my message [E0599]
//~| my label
//~| my note
}

View File

@ -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<T: ?Sized + ProviderLt> 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`.