diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 8971e1aa058ff..f599a2b2ece07 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -219,14 +219,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { &self, expected_vid: ty::TyVid, ) -> (Option>, Option) { - 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`. 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))) }); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e8252f55735bc..a8711d73af8ca 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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> + Captures<'gcx> + 'b + -> impl Iterator, 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() }) }