Skip to content

Commit

Permalink
Use more Iterators instead of Vecs
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Apr 19, 2020
1 parent 2cb4b58 commit 6be420b
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 81 deletions.
12 changes: 5 additions & 7 deletions src/librustc_middle/ty/trait_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,13 @@ impl<'tcx> TyCtxt<'tcx> {
}

/// Returns a vector containing all impls
pub fn all_impls(self, def_id: DefId) -> Vec<DefId> {
let impls = self.trait_impls_of(def_id);
pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);

impls
.blanket_impls
.iter()
.chain(impls.non_blanket_impls.values().flatten())
blanket_impls
.into_iter()
.chain(non_blanket_impls.into_iter().map(|(_, v)| v).flatten())
.cloned()
.collect()
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/librustc_trait_selection/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,22 +1208,18 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {

match simp {
Some(simp) => all_impls
.iter()
.filter_map(|&def_id| {
.filter_map(|def_id| {
let imp = self.tcx.impl_trait_ref(def_id).unwrap();
let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true);
if let Some(imp_simp) = imp_simp {
if simp != imp_simp {
return None;
}
}

Some(imp)
})
.collect(),
None => {
all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect()
}
None => all_impls.map(|def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect(),
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trait_selection/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ pub enum TraitQueryMode {
pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: &ty::InstantiatedPredicates<'tcx>,
) -> PredicateObligations<'tcx> {
generic_bounds: ty::InstantiatedPredicates<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
util::predicates_for_generics(cause, 0, param_env, generic_bounds)
}

Expand Down
34 changes: 15 additions & 19 deletions src/librustc_trait_selection/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,26 +189,22 @@ fn fulfill_implication<'a, 'tcx>(

let selcx = &mut SelectionContext::new(&infcx);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let (target_trait_ref, mut obligations) =
let (target_trait_ref, obligations) =
impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs);
debug!(
"fulfill_implication: target_trait_ref={:?}, obligations={:?}",
target_trait_ref, obligations
);

// do the impls unify? If not, no specialization.
match infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref) {
Ok(InferOk { obligations: o, .. }) => {
obligations.extend(o);
}
Err(_) => {
debug!(
"fulfill_implication: {:?} does not unify with {:?}",
source_trait_ref, target_trait_ref
);
return Err(());
}
}
let more_obligations =
match infcx.at(&ObligationCause::dummy(), param_env).eq(source_trait_ref, target_trait_ref)
{
Ok(InferOk { obligations, .. }) => obligations,
Err(_) => {
debug!(
"fulfill_implication: {:?} does not unify with {:?}",
source_trait_ref, target_trait_ref
);
return Err(());
}
};

// attempt to prove all of the predicates for impl2 given those for impl1
// (which are packed up in penv)
Expand All @@ -226,7 +222,7 @@ fn fulfill_implication<'a, 'tcx>(
// we already make a mockery out of the region system, so
// why not ignore them a bit earlier?
let mut fulfill_cx = FulfillmentContext::new_ignoring_regions();
for oblig in obligations.into_iter() {
for oblig in obligations.chain(more_obligations) {
fulfill_cx.register_predicate_obligation(&infcx, oblig);
}
match fulfill_cx.select_all_or_error(infcx) {
Expand Down Expand Up @@ -261,7 +257,7 @@ pub(super) fn specialization_graph_provider(
) -> &specialization_graph::Graph {
let mut sg = specialization_graph::Graph::new();

let mut trait_impls = tcx.all_impls(trait_id);
let mut trait_impls: Vec<_> = tcx.all_impls(trait_id).collect();

// The coherence checking implementation seems to rely on impls being
// iterated over (roughly) in definition order, so we are sorting by
Expand Down
40 changes: 16 additions & 24 deletions src/librustc_trait_selection/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,10 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> {

pub fn expand_trait_aliases<'tcx>(
tcx: TyCtxt<'tcx>,
trait_refs: impl IntoIterator<Item = (ty::PolyTraitRef<'tcx>, Span)>,
trait_refs: impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)>,
) -> TraitAliasExpander<'tcx> {
let items: Vec<_> = trait_refs
.into_iter()
.map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span))
.collect();
let items: Vec<_> =
trait_refs.map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span)).collect();
TraitAliasExpander { tcx, stack: items }
}

Expand Down Expand Up @@ -199,7 +197,7 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
param_env: ty::ParamEnv<'tcx>,
impl_def_id: DefId,
impl_substs: SubstsRef<'tcx>,
) -> (ty::TraitRef<'tcx>, Vec<PredicateObligation<'tcx>>) {
) -> (ty::TraitRef<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
let impl_trait_ref = selcx.tcx().impl_trait_ref(impl_def_id).unwrap();
let impl_trait_ref = impl_trait_ref.subst(selcx.tcx(), impl_substs);
let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } =
Expand All @@ -210,13 +208,11 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
let Normalized { value: predicates, obligations: normalization_obligations2 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), &predicates);
let impl_obligations =
predicates_for_generics(ObligationCause::dummy(), 0, param_env, &predicates);
predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates);

let impl_obligations: Vec<_> = impl_obligations
.into_iter()
.chain(normalization_obligations1)
.chain(normalization_obligations2)
.collect();
let impl_obligations = impl_obligations
.chain(normalization_obligations1.into_iter())
.chain(normalization_obligations2.into_iter());

(impl_trait_ref, impl_obligations)
}
Expand All @@ -226,20 +222,16 @@ pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: &ty::InstantiatedPredicates<'tcx>,
) -> Vec<PredicateObligation<'tcx>> {
generic_bounds: ty::InstantiatedPredicates<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);

generic_bounds
.predicates
.iter()
.map(|&predicate| Obligation {
cause: cause.clone(),
recursion_depth,
param_env,
predicate,
})
.collect()
generic_bounds.predicates.into_iter().map(move |predicate| Obligation {
cause: cause.clone(),
recursion_depth,
param_env,
predicate,
})
}

pub fn predicate_for_trait_ref<'tcx>(
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_typeck/check/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// a custom error in that case.
if illegal_sized_bound.is_none() {
let method_ty = self.tcx.mk_fn_ptr(ty::Binder::bind(method_sig));
self.add_obligations(method_ty, all_substs, &method_predicates);
self.add_obligations(method_ty, all_substs, method_predicates);
}

// Create the final `MethodCallee`.
Expand Down Expand Up @@ -395,7 +395,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
&mut self,
fty: Ty<'tcx>,
all_substs: SubstsRef<'tcx>,
method_predicates: &ty::InstantiatedPredicates<'tcx>,
method_predicates: ty::InstantiatedPredicates<'tcx>,
) {
debug!(
"add_obligations: fty={:?} all_substs={:?} method_predicates={:?}",
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
assert!(!bounds.has_escaping_bound_vars());

let cause = traits::ObligationCause::misc(span, self.body_id);
obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, &bounds));
obligations.extend(traits::predicates_for_generics(cause.clone(), self.param_env, bounds));

// Also add an obligation for the method type being well-formed.
let method_ty = tcx.mk_fn_ptr(ty::Binder::bind(fn_sig));
Expand Down
30 changes: 14 additions & 16 deletions src/librustc_typeck/check/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// clauses) that must be considered. Make sure that those
// match as well (or at least may match, sometimes we
// don't have enough information to fully evaluate).
let candidate_obligations: Vec<_> = match probe.kind {
match probe.kind {
InherentImplCandidate(ref substs, ref ref_obligations) => {
// Check whether the impl imposes obligations we have to worry about.
let impl_def_id = probe.item.container.id();
Expand All @@ -1353,19 +1353,23 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {

// Convert the bounds into obligations.
let impl_obligations =
traits::predicates_for_generics(cause, self.param_env, &impl_bounds);
traits::predicates_for_generics(cause, self.param_env, impl_bounds);

debug!("impl_obligations={:?}", impl_obligations);
impl_obligations
.into_iter()
let candidate_obligations = impl_obligations
.chain(norm_obligations.into_iter())
.chain(ref_obligations.iter().cloned())
.collect()
.chain(ref_obligations.iter().cloned());
// Evaluate those obligations to see if they might possibly hold.
for o in candidate_obligations {
let o = self.resolve_vars_if_possible(&o);
if !self.predicate_may_hold(&o) {
result = ProbeResult::NoMatch;
possibly_unsatisfied_predicates.push((o.predicate, None));
}
}
}

ObjectCandidate | WhereClauseCandidate(..) => {
// These have no additional conditions to check.
vec![]
}

TraitCandidate(trait_ref) => {
Expand Down Expand Up @@ -1412,17 +1416,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
return ProbeResult::NoMatch;
}
}
vec![]
}
};

debug!(
"consider_probe - candidate_obligations={:?} sub_obligations={:?}",
candidate_obligations, sub_obligations
);
}

// Evaluate those obligations to see if they might possibly hold.
for o in candidate_obligations.into_iter().chain(sub_obligations) {
for o in sub_obligations {
let o = self.resolve_vars_if_possible(&o);
if !self.predicate_may_hold(&o) {
result = ProbeResult::NoMatch;
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3434,7 +3434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn add_obligations_for_parameters(
&self,
cause: traits::ObligationCause<'tcx>,
predicates: &ty::InstantiatedPredicates<'tcx>,
predicates: ty::InstantiatedPredicates<'tcx>,
) {
assert!(!predicates.has_escaping_bound_vars());

Expand Down Expand Up @@ -4385,7 +4385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
let cause =
traits::ObligationCause::new(path_span, self.body_id, traits::ItemObligation(did));
self.add_obligations_for_parameters(cause, &bounds);
self.add_obligations_for_parameters(cause, bounds);

Some((variant, ty))
} else {
Expand Down Expand Up @@ -5654,9 +5654,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for (i, mut obligation) in traits::predicates_for_generics(
traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
self.param_env,
&bounds,
bounds,
)
.into_iter()
.enumerate()
{
// This makes the error point at the bound, but we want to point at the argument
Expand Down

0 comments on commit 6be420b

Please sign in to comment.