diff options
| author | Michael Goulet <michael@errs.io> | 2023-07-27 00:48:51 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-08-03 18:21:11 +0000 |
| commit | 4cc659eb3fc99cd44457616b17d390488e80fcb0 (patch) | |
| tree | 4f4d14a054753952c9c65b69718be89dd2e7801d | |
| parent | 1bb6ae5874730933188fe4be56b3a2f3d5a66962 (diff) | |
| download | rust-4cc659eb3fc99cd44457616b17d390488e80fcb0.tar.gz rust-4cc659eb3fc99cd44457616b17d390488e80fcb0.zip | |
short-circuit when proj def ids differ
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/trait_goals.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/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 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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); |
