Skip to content

Commit

Permalink
cleanup deduce_expectations_from_obligations
Browse files Browse the repository at this point in the history
  • Loading branch information
arielb1 committed Dec 16, 2018
1 parent f4dc1c5 commit eeb8c8d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 25 deletions.
28 changes: 8 additions & 20 deletions src/librustc_typeck/check/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
&self,
expected_vid: ty::TyVid,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
let fulfillment_cx = self.fulfillment_cx.borrow();
// Here `expected_ty` is known to be a type inference variable.

let expected_vid = self.root_var(expected_vid);
let expected_sig = fulfillment_cx
.pending_obligations()
.iter()
.filter_map(|obligation| {
let expected_sig = self.obligations_for_self_ty(expected_vid)
.find_map(|(_, obligation)| {
debug!(
"deduce_expectations_from_obligations: obligation.predicate={:?}",
obligation.predicate
Expand All @@ -235,27 +229,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if let ty::Predicate::Projection(ref proj_predicate) = obligation.predicate {
// Given a Projection predicate, we can potentially infer
// the complete signature.
let trait_ref = proj_predicate.to_poly_trait_ref(self.tcx);
Some(()).filter(|()| {
self.self_type_matches_expected_vid(trait_ref, expected_vid)
}).and_then(|()| {
self.deduce_sig_from_projection(
Some(obligation.cause.span),
proj_predicate
)
})
self.deduce_sig_from_projection(
Some(obligation.cause.span),
proj_predicate
)
} else {
None
}
})
.next();
});

// Even if we can't infer the full signature, we may be able to
// infer the kind. This can occur if there is a trait-reference
// like `F : Fn<A>`. Note that due to subtyping we could encounter
// many viable options, so pick the most restrictive.
let expected_kind = self.obligations_for_self_ty(expected_vid)
.filter_map(|tr| self.tcx.lang_items().fn_trait_kind(tr.def_id()))
.filter_map(|(tr, _)| self.tcx.lang_items().fn_trait_kind(tr.def_id()))
.fold(None, |best, cur| {
Some(best.map_or(cur, |best| cmp::min(best, cur)))
});
Expand Down
13 changes: 8 additions & 5 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2753,7 +2753,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}

fn obligations_for_self_ty<'b>(&'b self, self_ty: ty::TyVid)
-> impl Iterator<Item=ty::PolyTraitRef<'tcx>> + Captures<'gcx> + 'b
-> impl Iterator<Item=(ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
+ Captures<'gcx> + 'b
{
let ty_var_root = self.root_var(self_ty);
debug!("obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
Expand All @@ -2765,8 +2766,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
.pending_obligations()
.into_iter()
.filter_map(move |obligation| match obligation.predicate {
ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref(self.tcx)),
ty::Predicate::Trait(ref data) => Some(data.to_poly_trait_ref()),
ty::Predicate::Projection(ref data) =>
Some((data.to_poly_trait_ref(self.tcx), obligation)),
ty::Predicate::Trait(ref data) =>
Some((data.to_poly_trait_ref(), obligation)),
ty::Predicate::Subtype(..) => None,
ty::Predicate::RegionOutlives(..) => None,
ty::Predicate::TypeOutlives(..) => None,
Expand All @@ -2782,11 +2785,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// code is looking for a self type of a unresolved
// inference variable.
ty::Predicate::ClosureKind(..) => None,
}).filter(move |tr| self.self_type_matches_expected_vid(*tr, ty_var_root))
}).filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
}

fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
self.obligations_for_self_ty(self_ty).any(|tr| {
self.obligations_for_self_ty(self_ty).any(|(tr, _)| {
Some(tr.def_id()) == self.tcx.lang_items().sized_trait()
})
}
Expand Down

0 comments on commit eeb8c8d

Please sign in to comment.