Rollup merge of #132086 - estebank:long-types, r=jieyouxu

Tweak E0277 highlighting and "long type" path printing

Partially address #132013.

![Output from this PR for the repro case in #132013](https://github.com/user-attachments/assets/a073ba37-4adc-411e-81f7-6cb9a945ce3d)
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-10-28 13:36:18 +08:00 committed by GitHub
commit 20d2a546fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 145 additions and 25 deletions

View File

@ -1835,6 +1835,7 @@ pub(super) fn report_similar_impl_candidates(
if impl_trait_ref.references_error() {
return false;
}
let self_ty = impl_trait_ref.self_ty().to_string();
err.highlighted_help(vec![
StringPart::normal(format!(
"the trait `{}` ",
@ -1842,16 +1843,24 @@ pub(super) fn report_similar_impl_candidates(
)),
StringPart::highlighted("is"),
StringPart::normal(" implemented for `"),
StringPart::highlighted(impl_trait_ref.self_ty().to_string()),
if let [TypeError::Sorts(_)] = &terrs[..] {
StringPart::normal(self_ty)
} else {
StringPart::highlighted(self_ty)
},
StringPart::normal("`"),
]);
if let [TypeError::Sorts(exp_found)] = &terrs[..] {
let exp_found = self.resolve_vars_if_possible(*exp_found);
err.help(format!(
"for that trait implementation, expected `{}`, found `{}`",
exp_found.expected, exp_found.found
));
err.highlighted_help(vec![
StringPart::normal("for that trait implementation, "),
StringPart::normal("expected `"),
StringPart::highlighted(exp_found.expected.to_string()),
StringPart::normal("`, found `"),
StringPart::highlighted(exp_found.found.to_string()),
StringPart::normal("`"),
]);
}
true
@ -2160,6 +2169,7 @@ pub fn note_obligation_cause(
// First, attempt to add note to this error with an async-await-specific
// message, and fall back to regular note otherwise.
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
let mut long_ty_file = None;
self.note_obligation_cause_code(
obligation.cause.body_id,
err,
@ -2168,7 +2178,15 @@ pub fn note_obligation_cause(
obligation.cause.code(),
&mut vec![],
&mut Default::default(),
&mut long_ty_file,
);
if let Some(file) = long_ty_file {
err.note(format!(
"the full name for the type has been written to '{}'",
file.display(),
));
err.note("consider using `--verbose` to print the full type name to the console");
}
self.suggest_unsized_bound_if_applicable(err, obligation);
if let Some(span) = err.span.primary_span()
&& let Some(mut diag) =

View File

@ -305,6 +305,7 @@ fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuara
if let ObligationCauseCode::WhereClause(..)
| ObligationCauseCode::WhereClauseInExpr(..) = code
{
let mut long_ty_file = None;
self.note_obligation_cause_code(
error.obligation.cause.body_id,
&mut diag,
@ -313,7 +314,17 @@ fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuara
code,
&mut vec![],
&mut Default::default(),
&mut long_ty_file,
);
if let Some(file) = long_ty_file {
diag.note(format!(
"the full name for the type has been written to '{}'",
file.display(),
));
diag.note(
"consider using `--verbose` to print the full type name to the console",
);
}
}
diag.emit()
}

View File

@ -144,6 +144,7 @@ pub fn report_overflow_obligation<T>(
obligation.cause.span,
suggest_increasing_limit,
|err| {
let mut long_ty_file = None;
self.note_obligation_cause_code(
obligation.cause.body_id,
err,
@ -152,7 +153,17 @@ pub fn report_overflow_obligation<T>(
obligation.cause.code(),
&mut vec![],
&mut Default::default(),
&mut long_ty_file,
);
if let Some(file) = long_ty_file {
err.note(format!(
"the full name for the type has been written to '{}'",
file.display(),
));
err.note(
"consider using `--verbose` to print the full type name to the console",
);
}
},
);
}

View File

@ -3,6 +3,7 @@
use std::assert_matches::debug_assert_matches;
use std::borrow::Cow;
use std::iter;
use std::path::PathBuf;
use itertools::{EitherOrBoth, Itertools};
use rustc_data_structures::fx::FxHashSet;
@ -2703,6 +2704,7 @@ fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
// Add a note for the item obligation that remains - normally a note pointing to the
// bound that introduced the obligation (e.g. `T: Send`).
debug!(?next_code);
let mut long_ty_file = None;
self.note_obligation_cause_code(
obligation.cause.body_id,
err,
@ -2711,6 +2713,7 @@ fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
next_code.unwrap(),
&mut Vec::new(),
&mut Default::default(),
&mut long_ty_file,
);
}
@ -2723,11 +2726,10 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
cause_code: &ObligationCauseCode<'tcx>,
obligated_types: &mut Vec<Ty<'tcx>>,
seen_requirements: &mut FxHashSet<DefId>,
long_ty_file: &mut Option<PathBuf>,
) where
T: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>,
{
let mut long_ty_file = None;
let tcx = self.tcx;
let predicate = predicate.upcast(tcx);
let suggest_remove_deref = |err: &mut Diag<'_, G>, expr: &hir::Expr<'_>| {
@ -2957,9 +2959,9 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
}
ObligationCauseCode::Coercion { source, target } => {
let source =
tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file);
tcx.short_ty_string(self.resolve_vars_if_possible(source), long_ty_file);
let target =
tcx.short_ty_string(self.resolve_vars_if_possible(target), &mut long_ty_file);
tcx.short_ty_string(self.resolve_vars_if_possible(target), long_ty_file);
err.note(with_forced_trimmed_paths!(format!(
"required for the cast from `{source}` to `{target}`",
)));
@ -3249,7 +3251,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
};
if !is_upvar_tys_infer_tuple {
let ty_str = tcx.short_ty_string(ty, &mut long_ty_file);
let ty_str = tcx.short_ty_string(ty, long_ty_file);
let msg = format!("required because it appears within the type `{ty_str}`");
match ty.kind() {
ty::Adt(def, _) => match tcx.opt_item_ident(def.did()) {
@ -3327,6 +3329,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
&data.parent_code,
obligated_types,
seen_requirements,
long_ty_file,
)
});
} else {
@ -3339,6 +3342,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
cause_code.peel_derives(),
obligated_types,
seen_requirements,
long_ty_file,
)
});
}
@ -3347,8 +3351,8 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
let mut parent_trait_pred =
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
let parent_def_id = parent_trait_pred.def_id();
let self_ty_str = tcx
.short_ty_string(parent_trait_pred.skip_binder().self_ty(), &mut long_ty_file);
let self_ty_str =
tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file);
let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string();
let msg = format!("required for `{self_ty_str}` to implement `{trait_name}`");
let mut is_auto_trait = false;
@ -3444,10 +3448,8 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
count,
pluralize!(count)
));
let self_ty = tcx.short_ty_string(
parent_trait_pred.skip_binder().self_ty(),
&mut long_ty_file,
);
let self_ty = tcx
.short_ty_string(parent_trait_pred.skip_binder().self_ty(), long_ty_file);
err.note(format!(
"required for `{self_ty}` to implement `{}`",
parent_trait_pred.print_modifiers_and_trait_path()
@ -3463,6 +3465,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
&data.parent_code,
obligated_types,
seen_requirements,
long_ty_file,
)
});
}
@ -3479,6 +3482,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
&data.parent_code,
obligated_types,
seen_requirements,
long_ty_file,
)
});
}
@ -3493,6 +3497,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
nested,
obligated_types,
seen_requirements,
long_ty_file,
)
});
let mut multispan = MultiSpan::from(span);
@ -3523,6 +3528,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
parent_code,
obligated_types,
seen_requirements,
long_ty_file,
)
});
}
@ -3562,7 +3568,7 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
}
ObligationCauseCode::OpaqueReturnType(expr_info) => {
if let Some((expr_ty, hir_id)) = expr_info {
let expr_ty = self.tcx.short_ty_string(expr_ty, &mut long_ty_file);
let expr_ty = self.tcx.short_ty_string(expr_ty, long_ty_file);
let expr = self.infcx.tcx.hir().expect_expr(hir_id);
err.span_label(
expr.span,
@ -3574,14 +3580,6 @@ pub(super) fn note_obligation_cause_code<G: EmissionGuarantee, T>(
}
}
}
if let Some(file) = long_ty_file {
err.note(format!(
"the full name for the type has been written to '{}'",
file.display(),
));
err.note("consider using `--verbose` to print the full type name to the console");
}
}
#[instrument(

View File

@ -0,0 +1,20 @@
//@ only-linux
//@ compile-flags: --error-format=human --color=always
//@ error-pattern: the trait bound
trait Foo<T>: Bar<T> {}
trait Bar<T> {}
struct Struct;
impl<T, K> Foo<K> for T where T: Bar<K>
{}
impl<'a> Bar<()> for Struct {}
fn foo() -> impl Foo<i32> {
Struct
}
fn main() {}

View File

@ -0,0 +1,62 @@
<svg width="1104px" height="344px" xmlns="http://www.w3.org/2000/svg">
<style>
.fg { fill: #AAAAAA }
.bg { background: #000000 }
.fg-ansi256-009 { fill: #FF5555 }
.fg-ansi256-010 { fill: #55FF55 }
.fg-ansi256-012 { fill: #5555FF }
.fg-magenta { fill: #AA00AA }
.container {
padding: 0 10px;
line-height: 18px;
}
.bold { font-weight: bold; }
tspan {
font: 14px SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
white-space: pre;
line-height: 18px;
}
</style>
<rect width="100%" height="100%" y="0" rx="4.5" class="bg" />
<text xml:space="preserve" class="container fg">
<tspan x="10px" y="28px"><tspan class="fg-ansi256-009 bold">error[E0277]</tspan><tspan class="bold">: the trait bound `Struct: Foo&lt;i32&gt;` is not satisfied</tspan>
</tspan>
<tspan x="10px" y="46px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlight-difference-between-expected-trait-and-found-trait.rs:16:13</tspan>
</tspan>
<tspan x="10px" y="64px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
</tspan>
<tspan x="10px" y="82px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> fn foo() -&gt; impl Foo&lt;i32&gt; {</tspan>
</tspan>
<tspan x="10px" y="100px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">^^^^^^^^^^^^^</tspan><tspan> </tspan><tspan class="fg-ansi256-009 bold">the trait `Bar&lt;i32&gt;` is not implemented for `Struct`, which is required by `Struct: Foo&lt;i32&gt;`</tspan>
</tspan>
<tspan x="10px" y="118px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
</tspan>
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">= </tspan><tspan class="bold">help</tspan><tspan>: the trait `Bar&lt;()&gt;` </tspan><tspan class="fg-magenta bold">is</tspan><tspan> implemented for `Struct`</tspan>
</tspan>
<tspan x="10px" y="154px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">= </tspan><tspan class="bold">help</tspan><tspan>: for that trait implementation, expected `</tspan><tspan class="fg-magenta bold">()</tspan><tspan>`, found `</tspan><tspan class="fg-magenta bold">i32</tspan><tspan>`</tspan>
</tspan>
<tspan x="10px" y="172px"><tspan class="fg-ansi256-010 bold">note</tspan><tspan>: required for `Struct` to implement `Foo&lt;i32&gt;`</tspan>
</tspan>
<tspan x="10px" y="190px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">--&gt; </tspan><tspan>$DIR/highlight-difference-between-expected-trait-and-found-trait.rs:11:12</tspan>
</tspan>
<tspan x="10px" y="208px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan>
</tspan>
<tspan x="10px" y="226px"><tspan class="fg-ansi256-012 bold">LL</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> impl&lt;T, K&gt; Foo&lt;K&gt; for T where T: Bar&lt;K&gt;</tspan>
</tspan>
<tspan x="10px" y="244px"><tspan> </tspan><tspan class="fg-ansi256-012 bold">|</tspan><tspan> </tspan><tspan class="fg-ansi256-010 bold">^^^^^^</tspan><tspan> </tspan><tspan class="fg-ansi256-010 bold">^</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">------</tspan><tspan> </tspan><tspan class="fg-ansi256-012 bold">unsatisfied trait bound introduced here</tspan>
</tspan>
<tspan x="10px" y="262px">
</tspan>
<tspan x="10px" y="280px"><tspan class="fg-ansi256-009 bold">error</tspan><tspan class="bold">: aborting due to 1 previous error</tspan>
</tspan>
<tspan x="10px" y="298px">
</tspan>
<tspan x="10px" y="316px"><tspan class="bold">For more information about this error, try `rustc --explain E0277`.</tspan>
</tspan>
<tspan x="10px" y="334px">
</tspan>
</text>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB