diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 770d7b6f927..c43bfd16ab1 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -209,9 +209,11 @@ fn compare_method_predicate_entailment<'tcx>( // // We then register the obligations from the impl_m and check to see // if all constraints hold. - hybrid_preds - .predicates - .extend(trait_m_predicates.instantiate_own(tcx, trait_to_placeholder_substs).predicates); + hybrid_preds.predicates.extend( + trait_m_predicates + .instantiate_own(tcx, trait_to_placeholder_substs) + .map(|(predicate, _)| predicate), + ); // Construct trait parameter environment and then shift it into the placeholder viewpoint. // The key step here is to update the caller_bounds's predicates to be @@ -230,7 +232,7 @@ fn compare_method_predicate_entailment<'tcx>( debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds()); let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs); - for (predicate, span) in iter::zip(impl_m_own_bounds.predicates, impl_m_own_bounds.spans) { + for (predicate, span) in impl_m_own_bounds { let normalize_cause = traits::ObligationCause::misc(span, impl_m_hir_id); let predicate = ocx.normalize(&normalize_cause, param_env, predicate); @@ -1828,8 +1830,7 @@ fn compare_type_predicate_entailment<'tcx>( check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?; let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs); - - if impl_ty_own_bounds.is_empty() { + if impl_ty_own_bounds.len() == 0 { // Nothing to check. return Ok(()); } @@ -1844,9 +1845,11 @@ fn compare_type_predicate_entailment<'tcx>( // associated type in the trait are assumed. let impl_predicates = tcx.predicates_of(impl_ty_predicates.parent.unwrap()); let mut hybrid_preds = impl_predicates.instantiate_identity(tcx); - hybrid_preds - .predicates - .extend(trait_ty_predicates.instantiate_own(tcx, trait_to_impl_substs).predicates); + hybrid_preds.predicates.extend( + trait_ty_predicates + .instantiate_own(tcx, trait_to_impl_substs) + .map(|(predicate, _)| predicate), + ); debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); @@ -1862,9 +1865,7 @@ fn compare_type_predicate_entailment<'tcx>( debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds()); - assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len()); - for (span, predicate) in std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates) - { + for (predicate, span) in impl_ty_own_bounds { let cause = ObligationCause::misc(span, impl_ty_hir_id); let predicate = ocx.normalize(&cause, param_env, predicate); diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 8a5e765b9a3..801ca600445 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -341,15 +341,9 @@ impl<'tcx> GenericPredicates<'tcx> { &self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, - ) -> InstantiatedPredicates<'tcx> { - InstantiatedPredicates { - predicates: self - .predicates - .iter() - .map(|(p, _)| EarlyBinder(*p).subst(tcx, substs)) - .collect(), - spans: self.predicates.iter().map(|(_, sp)| *sp).collect(), - } + ) -> impl Iterator, Span)> + DoubleEndedIterator + ExactSizeIterator + { + EarlyBinder(self.predicates).subst_iter_copied(tcx, substs) } #[instrument(level = "debug", skip(self, tcx))] diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 8f764011d0a..5dc9e311bf6 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -639,6 +639,13 @@ where } } +impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I> +where + I::IntoIter: ExactSizeIterator, + I::Item: TypeFoldable<'tcx>, +{ +} + impl<'tcx, 's, I: IntoIterator> EarlyBinder where I::Item: Deref, @@ -686,6 +693,14 @@ where } } +impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I> +where + I::IntoIter: ExactSizeIterator, + I::Item: Deref, + ::Target: Copy + TypeFoldable<'tcx>, +{ +} + pub struct EarlyBinderIter { t: T, } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 81966f3fcb2..15320916fbe 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2303,10 +2303,10 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( nested: &mut Vec>, ) { let tcx = selcx.tcx(); - let own = tcx + let predicates = tcx .predicates_of(obligation.predicate.def_id) .instantiate_own(tcx, obligation.predicate.substs); - for (predicate, span) in std::iter::zip(own.predicates, own.spans) { + for (predicate, span) in predicates { let normalized = normalize_with_depth_to( selcx, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a41d10f1043..d4ac461690c 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -185,9 +185,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { })?); if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() { - let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates; - debug!(?predicates, "projection predicates"); - for predicate in predicates { + let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); + for (predicate, _) in predicates { let normalized = normalize_with_depth_to( self, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 5ec9c2a24cd..64daca714c3 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -261,7 +261,10 @@ fn vtable_entries<'tcx>( // Note that this method could then never be called, so we // do not want to try and codegen it, in that case (see #23435). let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - if impossible_predicates(tcx, predicates.predicates) { + if impossible_predicates( + tcx, + predicates.map(|(predicate, _)| predicate).collect(), + ) { debug!("vtable_entries: predicates do not hold"); return VtblEntry::Vacant; }