Remove unnecessary call to select_from_obligation

The only regression is one ambiguity in the new trait solver, having to
do with two param-env candidates that may apply. I think this is fine,
since the error message already kinda sucks.
This commit is contained in:
Michael Goulet 2023-06-20 20:00:39 +00:00
parent 46514218f6
commit db235a07f7
2 changed files with 35 additions and 49 deletions

View File

@ -5,7 +5,7 @@ pub mod suggestions;
use super::{ use super::{
FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow, ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, PredicateObligation, SelectionError, TraitNotObjectSafe,
}; };
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@ -2269,55 +2269,40 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) )
}; };
let obligation = obligation.with(self.tcx, trait_ref); let ambiguities = ambiguity::recompute_applicable_impls(
let mut selcx = SelectionContext::new(&self); self.infcx,
match selcx.select_from_obligation(&obligation) { &obligation.with(self.tcx, trait_ref),
Ok(None) => { );
let ambiguities = let has_non_region_infer =
ambiguity::recompute_applicable_impls(self.infcx, &obligation); trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_or_numeric_infer());
let has_non_region_infer = trait_ref // It doesn't make sense to talk about applicable impls if there are more
.skip_binder() // than a handful of them.
.substs if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
.types() if self.tainted_by_errors().is_some() && subst.is_none() {
.any(|t| !t.is_ty_or_numeric_infer()); // If `subst.is_none()`, then this is probably two param-env
// It doesn't make sense to talk about applicable impls if there are more // candidates or impl candidates that are equal modulo lifetimes.
// than a handful of them. // Therefore, if we've already emitted an error, just skip this
if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { // one, since it's not particularly actionable.
if self.tainted_by_errors().is_some() && subst.is_none() { err.cancel();
// If `subst.is_none()`, then this is probably two param-env return;
// candidates or impl candidates that are equal modulo lifetimes.
// Therefore, if we've already emitted an error, just skip this
// one, since it's not particularly actionable.
err.cancel();
return;
}
self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
} else {
if self.tainted_by_errors().is_some() {
err.cancel();
return;
}
err.note(format!("cannot satisfy `{}`", predicate));
let impl_candidates = self.find_similar_impl_candidates(
predicate.to_opt_poly_trait_pred().unwrap(),
);
if impl_candidates.len() < 10 {
self.report_similar_impl_candidates(
impl_candidates.as_slice(),
trait_ref,
obligation.cause.body_id,
&mut err,
false,
);
}
}
} }
_ => { self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
if self.tainted_by_errors().is_some() { } else {
err.cancel(); if self.tainted_by_errors().is_some() {
return; err.cancel();
} return;
err.note(format!("cannot satisfy `{}`", predicate)); }
err.note(format!("cannot satisfy `{}`", predicate));
let impl_candidates = self
.find_similar_impl_candidates(predicate.to_opt_poly_trait_pred().unwrap());
if impl_candidates.len() < 10 {
self.report_similar_impl_candidates(
impl_candidates.as_slice(),
trait_ref,
obligation.cause.body_id,
&mut err,
false,
);
} }
} }

View File

@ -5,6 +5,7 @@ LL | needs_bar::<T>();
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= note: cannot satisfy `T: Bar` = note: cannot satisfy `T: Bar`
= help: the trait `Bar` is implemented for `T`
note: required by a bound in `needs_bar` note: required by a bound in `needs_bar`
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17 --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17
| |