提交 2000f91f 编写于 作者: E Esteban Küber

Remove some `Vec` allocations in an effort to improve perf

上级 8ce3f840
......@@ -223,7 +223,7 @@ fn declared_generic_bounds_from_env_with_compare_fn(
// like `T` and `T::Item`. It may not work as well for things
// like `<T as Foo<'a>>::Item`.
let c_b = self.param_env.caller_bounds;
let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b);
let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b.into_iter());
// Next, collect regions we scraped from the well-formedness
// constraints in the fn signature. To do that, we walk the list
......@@ -315,15 +315,12 @@ fn region_bounds_declared_on_associated_item(
let tcx = self.tcx;
let assoc_item = tcx.associated_item(assoc_item_def_id);
let trait_def_id = assoc_item.container.assert_trait();
let trait_predicates =
tcx.predicates_of(trait_def_id).predicates.iter().map(|(p, _)| *p).collect();
let trait_predicates = tcx.predicates_of(trait_def_id).predicates.iter().map(|(p, _)| *p);
let identity_substs = InternalSubsts::identity_for_item(tcx, assoc_item_def_id);
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
self.collect_outlives_from_predicate_list(
move |ty| ty == identity_proj,
traits::elaborate_predicates(tcx, trait_predicates)
.map(|o| o.predicate)
.collect::<Vec<_>>(),
traits::elaborate_predicates(tcx, trait_predicates).map(|o| o.predicate),
)
.map(|b| b.1)
}
......@@ -337,10 +334,9 @@ fn region_bounds_declared_on_associated_item(
fn collect_outlives_from_predicate_list(
&self,
compare_ty: impl Fn(Ty<'tcx>) -> bool,
predicates: impl IntoIterator<Item = impl AsRef<ty::Predicate<'tcx>>>,
predicates: impl Iterator<Item = impl AsRef<ty::Predicate<'tcx>>>,
) -> impl Iterator<Item = ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
predicates
.into_iter()
.filter_map(|p| p.as_ref().to_opt_type_outlives())
.filter_map(|p| p.no_bound_vars())
.filter(move |p| compare_ty(p.0))
......
......@@ -97,24 +97,22 @@ pub fn elaborate_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Elaborator<'tcx> {
elaborate_predicates(tcx, vec![trait_ref.without_const().to_predicate()])
elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate()))
}
pub fn elaborate_trait_refs<'tcx>(
tcx: TyCtxt<'tcx>,
trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
) -> Elaborator<'tcx> {
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate()).collect();
let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate());
elaborate_predicates(tcx, predicates)
}
pub fn elaborate_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
mut predicates: Vec<ty::Predicate<'tcx>>,
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
) -> Elaborator<'tcx> {
let mut visited = PredicateSet::new(tcx);
predicates.retain(|pred| visited.insert(pred));
let obligations: Vec<_> =
let obligations =
predicates.into_iter().map(|predicate| predicate_obligation(predicate, None)).collect();
elaborate_obligations(tcx, obligations)
}
......
......@@ -122,8 +122,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAn
.predicates_of(source.def_id())
.predicates
.iter()
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None })
.collect();
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
if !traits::normalize_and_test_predicates(
tcx,
traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(),
......
......@@ -418,7 +418,7 @@ fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
let opaque_type = tcx.mk_opaque(def_id, opaque_defn.substs);
let required_region_bounds =
required_region_bounds(tcx, opaque_type, bounds.predicates);
required_region_bounds(tcx, opaque_type, bounds.predicates.into_iter());
debug_assert!(!required_region_bounds.is_empty());
for required_region in required_region_bounds {
......@@ -1127,7 +1127,8 @@ fn fold_opaque_ty(
debug!("instantiate_opaque_types: bounds={:?}", bounds);
let required_region_bounds = required_region_bounds(tcx, ty, bounds.predicates.clone());
let required_region_bounds =
required_region_bounds(tcx, ty, bounds.predicates.iter().cloned());
debug!("instantiate_opaque_types: required_region_bounds={:?}", required_region_bounds);
// Make sure that we are in fact defining the *entire* type
......@@ -1245,17 +1246,15 @@ pub fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir
crate fn required_region_bounds(
tcx: TyCtxt<'tcx>,
erased_self_ty: Ty<'tcx>,
predicates: Vec<ty::Predicate<'tcx>>,
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
) -> Vec<ty::Region<'tcx>> {
debug!(
"required_region_bounds(erased_self_ty={:?}, predicates={:?})",
erased_self_ty, predicates
);
debug!("required_region_bounds(erased_self_ty={:?})", erased_self_ty);
assert!(!erased_self_ty.has_escaping_bound_vars());
traits::elaborate_predicates(tcx, predicates)
.filter_map(|obligation| {
debug!("required_region_bounds(obligation={:?})", obligation);
match obligation.predicate {
ty::Predicate::Projection(..)
| ty::Predicate::Trait(..)
......
......@@ -360,8 +360,7 @@ fn evaluate_predicates(
computed_preds.extend(user_computed_preds.iter().cloned());
let normalized_preds =
elaborate_predicates(tcx, computed_preds.iter().cloned().collect())
.map(|o| o.predicate);
elaborate_predicates(tcx, computed_preds.iter().cloned()).map(|o| o.predicate);
new_env =
ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal, None);
}
......
......@@ -1007,7 +1007,7 @@ fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>)
}
};
for obligation in super::elaborate_predicates(self.tcx, vec![*cond]) {
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(*cond)) {
if let ty::Predicate::Trait(implication, _) = obligation.predicate {
let error = error.to_poly_trait_ref();
let implication = implication.to_poly_trait_ref();
......
......@@ -297,7 +297,7 @@ pub fn normalize_param_env_or_error<'tcx>(
);
let mut predicates: Vec<_> =
util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec())
util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.into_iter().cloned())
.map(|obligation| obligation.predicate)
.collect();
......
......@@ -302,7 +302,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
// Search for a predicate like `Self : Sized` amongst the trait bounds.
let predicates = tcx.predicates_of(def_id);
let predicates = predicates.instantiate_identity(tcx).predicates;
elaborate_predicates(tcx, predicates).any(|obligation| match obligation.predicate {
elaborate_predicates(tcx, predicates.into_iter()).any(|obligation| match obligation.predicate {
ty::Predicate::Trait(ref trait_pred, _) => {
trait_pred.def_id() == sized_def_id && trait_pred.skip_binder().self_ty().is_param(0)
}
......
......@@ -900,7 +900,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
// If so, extract what we know from the trait and try to come up with a good answer.
let trait_predicates = tcx.predicates_of(def_id);
let bounds = trait_predicates.instantiate(tcx, substs);
let bounds = elaborate_predicates(tcx, bounds.predicates).map(|o| o.predicate);
let bounds = elaborate_predicates(tcx, bounds.predicates.into_iter()).map(|o| o.predicate);
assemble_candidates_from_predicates(
selcx,
obligation,
......@@ -911,16 +911,14 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
)
}
fn assemble_candidates_from_predicates<'cx, 'tcx, I>(
fn assemble_candidates_from_predicates<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
obligation: &ProjectionTyObligation<'tcx>,
obligation_trait_ref: &ty::TraitRef<'tcx>,
candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionTyCandidate<'tcx>,
env_predicates: I,
) where
I: IntoIterator<Item = ty::Predicate<'tcx>>,
{
env_predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
) {
debug!("assemble_candidates_from_predicates(obligation={:?})", obligation);
let infcx = selcx.infcx();
for predicate in env_predicates {
......@@ -1153,10 +1151,8 @@ fn confirm_object_candidate<'cx, 'tcx>(
object_ty
),
};
let env_predicates = data
.projection_bounds()
.map(|p| p.with_self_ty(selcx.tcx(), object_ty).to_predicate())
.collect();
let env_predicates =
data.projection_bounds().map(|p| p.with_self_ty(selcx.tcx(), object_ty).to_predicate());
let env_predicate = {
let env_predicates = elaborate_predicates(selcx.tcx(), env_predicates);
......
......@@ -1443,7 +1443,8 @@ fn match_projection_obligation_against_definition_bounds(
bounds
);
let elaborated_predicates = util::elaborate_predicates(self.tcx(), bounds.predicates);
let elaborated_predicates =
util::elaborate_predicates(self.tcx(), bounds.predicates.into_iter());
let matching_bound = elaborated_predicates.filter_to_traits().find(|bound| {
self.infcx.probe(|_| {
self.match_projection(
......
......@@ -627,16 +627,13 @@ pub fn object_region_bounds<'tcx>(
// a placeholder type.
let open_ty = tcx.mk_ty_infer(ty::FreshTy(0));
let predicates = existential_predicates
.iter()
.filter_map(|predicate| {
if let ty::ExistentialPredicate::Projection(_) = *predicate.skip_binder() {
None
} else {
Some(predicate.with_self_ty(tcx, open_ty))
}
})
.collect();
let predicates = existential_predicates.iter().filter_map(|predicate| {
if let ty::ExistentialPredicate::Projection(_) = *predicate.skip_binder() {
None
} else {
Some(predicate.with_self_ty(tcx, open_ty))
}
});
required_region_bounds(tcx, open_ty, predicates)
}
......@@ -572,7 +572,7 @@ fn predicates_require_illegal_sized_bound(
None => return None,
};
traits::elaborate_predicates(self.tcx, predicates.predicates.clone())
traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied())
.filter_map(|obligation| match obligation.predicate {
ty::Predicate::Trait(trait_pred, _) if trait_pred.def_id() == sized_def_id => {
let span = predicates
......
......@@ -1225,7 +1225,7 @@ fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
let empty_env = ty::ParamEnv::empty();
let def_id = fcx.tcx.hir().local_def_id(id);
let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p).collect();
let predicates = fcx.tcx.predicates_of(def_id).predicates.iter().map(|(p, _)| *p);
// Check elaborated bounds.
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
......
......@@ -322,7 +322,7 @@ fn check_predicates<'tcx>(
// which is sound because we forbid impls like the following
//
// impl<D: Debug> AlwaysApplicable for D { }
let always_applicable_traits: Vec<_> = impl1_predicates
let always_applicable_traits = impl1_predicates
.predicates
.iter()
.filter(|predicate| {
......@@ -331,8 +331,7 @@ fn check_predicates<'tcx>(
Some(TraitSpecializationKind::AlwaysApplicable)
)
})
.copied()
.collect();
.copied();
// Include the well-formed predicates of the type parameters of the impl.
for ty in tcx.impl_trait_ref(impl1_def_id).unwrap().substs.types() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册