From 4cc659eb3fc99cd44457616b17d390488e80fcb0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jul 2023 00:48:51 +0000 Subject: [PATCH] short-circuit when proj def ids differ --- .../src/solve/trait_goals.rs | 23 +++++++++++-------- .../src/traits/select/confirmation.rs | 11 +++++---- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 41565fe5dd9..6a23895e1be 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -625,15 +625,20 @@ fn consider_builtin_upcast_to_principal( // in b_ty's bound. Use this to first determine *which* apply without // having any inference side-effects. We process obligations because // unification may initially succeed due to deferred projection equality. - let projection_may_match = |ecx: &mut Self, source_projection, target_projection| { - ecx.probe(|_| CandidateKind::UpcastProbe) - .enter(|ecx| -> Result<(), NoSolution> { - ecx.eq(param_env, source_projection, target_projection)?; - let _ = ecx.try_evaluate_added_goals()?; - Ok(()) - }) - .is_ok() - }; + let projection_may_match = + |ecx: &mut Self, + source_projection: ty::PolyExistentialProjection<'tcx>, + target_projection: ty::PolyExistentialProjection<'tcx>| { + source_projection.item_def_id() == target_projection.item_def_id() + && ecx + .probe(|_| CandidateKind::UpcastProbe) + .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 { match bound.skip_binder() { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 77304984402..3cf2735b46b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -920,11 +920,12 @@ fn confirm_trait_upcasting_unsize_candidate( a_data.projection_bounds().filter(|source_projection| { // Eager normalization means that we can just use can_eq // here instead of equating and processing obligations. - self.infcx.can_eq( - obligation.param_env, - *source_projection, - target_projection, - ) + source_projection.item_def_id() == target_projection.item_def_id() + && self.infcx.can_eq( + obligation.param_env, + *source_projection, + target_projection, + ) }); let Some(source_projection) = matching_projections.next() else { return Err(SelectionError::Unimplemented);