Highlight clarifying information in "expected/found" error
When the expected and found types have the same textual representation, we add clarifying in parentheses. We now visually highlight it in the output. Detect a corner case where the clarifying information would be the same for both types and skip it, as it doesn't add anything useful.
This commit is contained in:
parent
7f36543a48
commit
c75e601543
6 changed files with 160 additions and 27 deletions
|
@ -641,7 +641,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
|||
found_label: &dyn fmt::Display,
|
||||
found: DiagStyledString,
|
||||
) -> &mut Self {
|
||||
self.note_expected_found_extra(expected_label, expected, found_label, found, &"", &"")
|
||||
self.note_expected_found_extra(
|
||||
expected_label,
|
||||
expected,
|
||||
found_label,
|
||||
found,
|
||||
DiagStyledString::normal(""),
|
||||
DiagStyledString::normal(""),
|
||||
)
|
||||
}
|
||||
|
||||
#[rustc_lint_diagnostics]
|
||||
|
@ -651,8 +658,8 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
|||
expected: DiagStyledString,
|
||||
found_label: &dyn fmt::Display,
|
||||
found: DiagStyledString,
|
||||
expected_extra: &dyn fmt::Display,
|
||||
found_extra: &dyn fmt::Display,
|
||||
expected_extra: DiagStyledString,
|
||||
found_extra: DiagStyledString,
|
||||
) -> &mut Self {
|
||||
let expected_label = expected_label.to_string();
|
||||
let expected_label = if expected_label.is_empty() {
|
||||
|
@ -677,10 +684,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
|
|||
expected_label
|
||||
))];
|
||||
msg.extend(expected.0);
|
||||
msg.push(StringPart::normal(format!("`{expected_extra}\n")));
|
||||
msg.push(StringPart::normal(format!("`")));
|
||||
msg.extend(expected_extra.0);
|
||||
msg.push(StringPart::normal(format!("\n")));
|
||||
msg.push(StringPart::normal(format!("{}{} `", " ".repeat(found_padding), found_label)));
|
||||
msg.extend(found.0);
|
||||
msg.push(StringPart::normal(format!("`{found_extra}")));
|
||||
msg.push(StringPart::normal(format!("`")));
|
||||
msg.extend(found_extra.0);
|
||||
|
||||
// For now, just attach these as notes.
|
||||
self.highlighted_note(msg);
|
||||
|
|
|
@ -1725,32 +1725,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
TypeError::Sorts(values) => {
|
||||
let extra = expected == found;
|
||||
let extra = expected == found
|
||||
// Ensure that we don't ever say something like
|
||||
// expected `impl Trait` (opaque type `impl Trait`)
|
||||
// found `impl Trait` (opaque type `impl Trait`)
|
||||
&& values.expected.sort_string(self.tcx)
|
||||
!= values.found.sort_string(self.tcx);
|
||||
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
|
||||
(true, ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })) => {
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let pos = sm.lookup_char_pos(self.tcx.def_span(*def_id).lo());
|
||||
format!(
|
||||
DiagStyledString::normal(format!(
|
||||
" (opaque type at <{}:{}:{}>)",
|
||||
sm.filename_for_diagnostics(&pos.file.name),
|
||||
pos.line,
|
||||
pos.col.to_usize() + 1,
|
||||
)
|
||||
))
|
||||
}
|
||||
(true, ty::Alias(ty::Projection, proj))
|
||||
if self.tcx.is_impl_trait_in_trait(proj.def_id) =>
|
||||
{
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo());
|
||||
format!(
|
||||
DiagStyledString::normal(format!(
|
||||
" (trait associated opaque type at <{}:{}:{}>)",
|
||||
sm.filename_for_diagnostics(&pos.file.name),
|
||||
pos.line,
|
||||
pos.col.to_usize() + 1,
|
||||
)
|
||||
))
|
||||
}
|
||||
(true, _) => format!(" ({})", ty.sort_string(self.tcx)),
|
||||
(false, _) => "".to_string(),
|
||||
(true, _) => {
|
||||
let mut s = DiagStyledString::normal(" (");
|
||||
s.push_highlighted(ty.sort_string(self.tcx));
|
||||
s.push_normal(")");
|
||||
s
|
||||
}
|
||||
(false, _) => DiagStyledString::normal(""),
|
||||
};
|
||||
if !(values.expected.is_simple_text() && values.found.is_simple_text())
|
||||
|| (exp_found.is_some_and(|ef| {
|
||||
|
@ -1767,23 +1777,23 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
}
|
||||
}))
|
||||
{
|
||||
if let Some(ExpectedFound { found: found_ty, .. }) = exp_found {
|
||||
if let Some(ExpectedFound { found: found_ty, .. }) = exp_found
|
||||
&& !self.tcx.ty_is_opaque_future(found_ty)
|
||||
{
|
||||
// `Future` is a special opaque type that the compiler
|
||||
// will try to hide in some case such as `async fn`, so
|
||||
// to make an error more use friendly we will
|
||||
// avoid to suggest a mismatch type with a
|
||||
// type that the user usually are not using
|
||||
// directly such as `impl Future<Output = u8>`.
|
||||
if !self.tcx.ty_is_opaque_future(found_ty) {
|
||||
diag.note_expected_found_extra(
|
||||
&expected_label,
|
||||
expected,
|
||||
&found_label,
|
||||
found,
|
||||
&sort_string(values.expected),
|
||||
&sort_string(values.found),
|
||||
);
|
||||
}
|
||||
diag.note_expected_found_extra(
|
||||
&expected_label,
|
||||
expected,
|
||||
&found_label,
|
||||
found,
|
||||
sort_string(values.expected),
|
||||
sort_string(values.found),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue