1
Fork 0

short-circuit when proj def ids differ

This commit is contained in:
Michael Goulet 2023-07-27 00:48:51 +00:00
parent 1bb6ae5874
commit 4cc659eb3f
2 changed files with 20 additions and 14 deletions

View file

@ -625,15 +625,20 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
// in b_ty's bound. Use this to first determine *which* apply without // in b_ty's bound. Use this to first determine *which* apply without
// having any inference side-effects. We process obligations because // having any inference side-effects. We process obligations because
// unification may initially succeed due to deferred projection equality. // unification may initially succeed due to deferred projection equality.
let projection_may_match = |ecx: &mut Self, source_projection, target_projection| { let projection_may_match =
ecx.probe(|_| CandidateKind::UpcastProbe) |ecx: &mut Self,
.enter(|ecx| -> Result<(), NoSolution> { source_projection: ty::PolyExistentialProjection<'tcx>,
ecx.eq(param_env, source_projection, target_projection)?; target_projection: ty::PolyExistentialProjection<'tcx>| {
let _ = ecx.try_evaluate_added_goals()?; source_projection.item_def_id() == target_projection.item_def_id()
Ok(()) && ecx
}) .probe(|_| CandidateKind::UpcastProbe)
.is_ok() .enter(|ecx| -> Result<(), NoSolution> {
}; ecx.eq(param_env, source_projection, target_projection)?;
let _ = ecx.try_evaluate_added_goals()?;
Ok(())
})
.is_ok()
};
for bound in b_data { for bound in b_data {
match bound.skip_binder() { match bound.skip_binder() {

View file

@ -920,11 +920,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
a_data.projection_bounds().filter(|source_projection| { a_data.projection_bounds().filter(|source_projection| {
// Eager normalization means that we can just use can_eq // Eager normalization means that we can just use can_eq
// here instead of equating and processing obligations. // here instead of equating and processing obligations.
self.infcx.can_eq( source_projection.item_def_id() == target_projection.item_def_id()
obligation.param_env, && self.infcx.can_eq(
*source_projection, obligation.param_env,
target_projection, *source_projection,
) target_projection,
)
}); });
let Some(source_projection) = matching_projections.next() else { let Some(source_projection) = matching_projections.next() else {
return Err(SelectionError::Unimplemented); return Err(SelectionError::Unimplemented);