cleanup deduce_expectations_from_obligations

This commit is contained in:
Ariel Ben-Yehuda 2018-12-01 14:27:45 +02:00
parent f4dc1c5d64
commit eeb8c8d59c
2 changed files with 16 additions and 25 deletions

View file

@ -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
@ -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)))
});

View file

@ -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={:?}",
@ -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,
@ -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()
})
}