Reorder fullfillment errors to keep more interesting ones first
In `report_fullfillment_errors` push back `T: Sized`, `T: WellFormed` and coercion errors to the end of the list. The pre-existing deduplication logic eliminates redundant errors better that way, keeping the resulting output with fewer errors than before, while also having more detail.
This commit is contained in:
parent
2817ece19c
commit
91b9ffeab0
76 changed files with 337 additions and 431 deletions
|
@ -218,7 +218,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
|
|||
def_id: LocalDefId,
|
||||
) -> Result<FxIndexSet<Ty<'tcx>>, ErrorGuaranteed> {
|
||||
self.assumed_wf_types(param_env, def_id)
|
||||
.map_err(|errors| self.infcx.err_ctxt().report_fulfillment_errors(&errors))
|
||||
.map_err(|errors| self.infcx.err_ctxt().report_fulfillment_errors(errors))
|
||||
}
|
||||
|
||||
pub fn assumed_wf_types(
|
||||
|
|
|
@ -137,7 +137,7 @@ pub trait TypeErrCtxtExt<'tcx> {
|
|||
|
||||
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed;
|
||||
|
||||
fn report_fulfillment_errors(&self, errors: &[FulfillmentError<'tcx>]) -> ErrorGuaranteed;
|
||||
fn report_fulfillment_errors(&self, errors: Vec<FulfillmentError<'tcx>>) -> ErrorGuaranteed;
|
||||
|
||||
fn report_overflow_obligation<T>(
|
||||
&self,
|
||||
|
@ -401,7 +401,10 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
fn report_fulfillment_errors(&self, errors: &[FulfillmentError<'tcx>]) -> ErrorGuaranteed {
|
||||
fn report_fulfillment_errors(
|
||||
&self,
|
||||
mut errors: Vec<FulfillmentError<'tcx>>,
|
||||
) -> ErrorGuaranteed {
|
||||
#[derive(Debug)]
|
||||
struct ErrorDescriptor<'tcx> {
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
|
@ -423,6 +426,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
// Ensure `T: Sized` and `T: WF` obligations come last. This lets us display diagnostics
|
||||
// with more relevant type information and hide redundant E0282 errors.
|
||||
errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))
|
||||
if Some(pred.def_id()) == self.tcx.lang_items().sized_trait() =>
|
||||
{
|
||||
1
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => 3,
|
||||
ty::PredicateKind::Coerce(_) => 2,
|
||||
_ => 0,
|
||||
});
|
||||
|
||||
for (index, error) in errors.iter().enumerate() {
|
||||
// We want to ignore desugarings here: spans are equivalent even
|
||||
// if one is the result of a desugaring and the other is not.
|
||||
|
@ -476,7 +492,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
|
||||
for from_expansion in [false, true] {
|
||||
for (error, suppressed) in iter::zip(errors, &is_suppressed) {
|
||||
for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
|
||||
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
|
||||
self.report_fulfillment_error(error);
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ fn do_normalize_predicates<'tcx>(
|
|||
let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
|
||||
Ok(predicates) => predicates,
|
||||
Err(errors) => {
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(reported);
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue