about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-04-05 16:43:21 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-04-05 16:43:21 +0530
commitf6019760f9dfd685d2934871810ac5c5b81ac82e (patch)
treeaa5c48e0c011cd5c9c463258410edc941583f1d0
parentbdd264a0bb48488346be4b5b8bb879530fd186a1 (diff)
parent86071aca3dd729c77d238d449d2c61b2de0b8425 (diff)
downloadrust-f6019760f9dfd685d2934871810ac5c5b81ac82e.tar.gz
rust-f6019760f9dfd685d2934871810ac5c5b81ac82e.zip
Rollup merge of #32596 - soltanmm:lazy, r=nikomatsakis
Plumb obligations through librustc/infer

Like #32542, but more like #31867.

TODO before merge: make an issue for the propagation of obligations through... uh, everywhere... then replace the `#????`s with the actual issue number.

cc @jroesch
r? @nikomatsakis
-rw-r--r--src/librustc/infer/combine.rs4
-rw-r--r--src/librustc/infer/equate.rs5
-rw-r--r--src/librustc/infer/glb.rs5
-rw-r--r--src/librustc/infer/lub.rs5
-rw-r--r--src/librustc/infer/mod.rs97
-rw-r--r--src/librustc/infer/sub.rs5
-rw-r--r--src/librustc/traits/fulfill.rs8
-rw-r--r--src/librustc/traits/project.rs23
-rw-r--r--src/librustc/traits/select.rs83
-rw-r--r--src/librustc_driver/test.rs25
-rw-r--r--src/librustc_mir/transform/type_check.rs6
-rw-r--r--src/librustc_typeck/check/_match.rs9
-rw-r--r--src/librustc_typeck/check/coercion.rs34
-rw-r--r--src/librustc_typeck/check/compare_method.rs7
-rw-r--r--src/librustc_typeck/check/demand.rs22
-rw-r--r--src/librustc_typeck/check/method/probe.rs5
-rw-r--r--src/librustc_typeck/check/mod.rs33
-rw-r--r--src/librustc_typeck/check/regionck.rs8
18 files changed, 276 insertions, 108 deletions
diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs
index 8edf24fbc25..67669c54ac5 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -37,7 +37,7 @@ use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
 use super::sub::Sub;
-use super::{InferCtxt};
+use super::InferCtxt;
 use super::{MiscVariable, TypeTrace};
 use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf};
 
@@ -46,6 +46,7 @@ use ty::{self, Ty, TyCtxt};
 use ty::error::TypeError;
 use ty::fold::{TypeFolder, TypeFoldable};
 use ty::relate::{Relate, RelateResult, TypeRelation};
+use traits::PredicateObligations;
 
 use syntax::ast;
 use syntax::codemap::Span;
@@ -56,6 +57,7 @@ pub struct CombineFields<'a, 'tcx: 'a> {
     pub a_is_expected: bool,
     pub trace: TypeTrace<'tcx>,
     pub cause: Option<ty::relate::Cause>,
+    pub obligations: PredicateObligations<'tcx>,
 }
 
 pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs
index 3c9c9c57884..5540046c9e3 100644
--- a/src/librustc/infer/equate.rs
+++ b/src/librustc/infer/equate.rs
@@ -16,6 +16,7 @@ use super::type_variable::{EqTo};
 use ty::{self, Ty, TyCtxt};
 use ty::TyVar;
 use ty::relate::{Relate, RelateResult, TypeRelation};
+use traits::PredicateObligations;
 
 /// Ensures `a` is made equal to `b`. Returns `a` on success.
 pub struct Equate<'a, 'tcx: 'a> {
@@ -26,6 +27,10 @@ impl<'a, 'tcx> Equate<'a, 'tcx> {
     pub fn new(fields: CombineFields<'a, 'tcx>) -> Equate<'a, 'tcx> {
         Equate { fields: fields }
     }
+
+    pub fn obligations(self) -> PredicateObligations<'tcx> {
+        self.fields.obligations
+    }
 }
 
 impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs
index 235428a6898..37717c2b6bc 100644
--- a/src/librustc/infer/glb.rs
+++ b/src/librustc/infer/glb.rs
@@ -16,6 +16,7 @@ use super::Subtype;
 
 use ty::{self, Ty, TyCtxt};
 use ty::relate::{Relate, RelateResult, TypeRelation};
+use traits::PredicateObligations;
 
 /// "Greatest lower bound" (common subtype)
 pub struct Glb<'a, 'tcx: 'a> {
@@ -26,6 +27,10 @@ impl<'a, 'tcx> Glb<'a, 'tcx> {
     pub fn new(fields: CombineFields<'a, 'tcx>) -> Glb<'a, 'tcx> {
         Glb { fields: fields }
     }
+
+    pub fn obligations(self) -> PredicateObligations<'tcx> {
+        self.fields.obligations
+    }
 }
 
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {
diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs
index 00b85929b4b..32b2fe911e8 100644
--- a/src/librustc/infer/lub.rs
+++ b/src/librustc/infer/lub.rs
@@ -16,6 +16,7 @@ use super::Subtype;
 
 use ty::{self, Ty, TyCtxt};
 use ty::relate::{Relate, RelateResult, TypeRelation};
+use traits::PredicateObligations;
 
 /// "Least upper bound" (common supertype)
 pub struct Lub<'a, 'tcx: 'a> {
@@ -26,6 +27,10 @@ impl<'a, 'tcx> Lub<'a, 'tcx> {
     pub fn new(fields: CombineFields<'a, 'tcx>) -> Lub<'a, 'tcx> {
         Lub { fields: fields }
     }
+
+    pub fn obligations(self) -> PredicateObligations<'tcx> {
+        self.fields.obligations
+    }
 }
 
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 35e1be7e5f4..e22fb988904 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -27,13 +27,13 @@ use middle::region::CodeExtent;
 use ty::subst;
 use ty::subst::Substs;
 use ty::subst::Subst;
-use traits::{self, ProjectionMode};
 use ty::adjustment;
 use ty::{TyVid, IntVid, FloatVid};
 use ty::{self, Ty, TyCtxt};
 use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
 use ty::fold::{TypeFolder, TypeFoldable};
 use ty::relate::{Relate, RelateResult, TypeRelation};
+use traits::{self, PredicateObligations, ProjectionMode};
 use rustc_data_structures::unify::{self, UnificationTable};
 use std::cell::{RefCell, Ref};
 use std::fmt;
@@ -63,6 +63,12 @@ pub mod sub;
 pub mod type_variable;
 pub mod unify_key;
 
+pub struct InferOk<'tcx, T> {
+    pub value: T,
+    pub obligations: PredicateObligations<'tcx>,
+}
+pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
+
 pub type Bound<T> = Option<T>;
 pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
 pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
@@ -391,16 +397,15 @@ pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                           origin: TypeOrigin,
                           a: Ty<'tcx>,
                           b: Ty<'tcx>)
-                          -> UnitResult<'tcx>
+    -> InferResult<'tcx, ()>
 {
     debug!("mk_subty({:?} <: {:?})", a, b);
     cx.sub_types(a_is_expected, origin, a, b)
 }
 
-pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
-                              a: Ty<'tcx>,
-                              b: Ty<'tcx>)
-                              -> UnitResult<'tcx> {
+pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
+    -> UnitResult<'tcx>
+{
     debug!("can_mk_subty({:?} <: {:?})", a, b);
     cx.probe(|_| {
         let trace = TypeTrace {
@@ -412,7 +417,7 @@ pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
 }
 
 pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
-                             -> UnitResult<'tcx>
+    -> UnitResult<'tcx>
 {
     cx.can_equate(&a, &b)
 }
@@ -432,7 +437,7 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                          origin: TypeOrigin,
                          a: Ty<'tcx>,
                          b: Ty<'tcx>)
-                         -> UnitResult<'tcx>
+    -> InferResult<'tcx, ()>
 {
     debug!("mk_eqty({:?} <: {:?})", a, b);
     cx.eq_types(a_is_expected, origin, a, b)
@@ -443,7 +448,7 @@ pub fn mk_eq_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                                   origin: TypeOrigin,
                                   a: ty::TraitRef<'tcx>,
                                   b: ty::TraitRef<'tcx>)
-                                  -> UnitResult<'tcx>
+    -> InferResult<'tcx, ()>
 {
     debug!("mk_eq_trait_refs({:?} = {:?})", a, b);
     cx.eq_trait_refs(a_is_expected, origin, a, b)
@@ -454,7 +459,7 @@ pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                                         origin: TypeOrigin,
                                         a: ty::PolyTraitRef<'tcx>,
                                         b: ty::PolyTraitRef<'tcx>)
-                                        -> UnitResult<'tcx>
+    -> InferResult<'tcx, ()>
 {
     debug!("mk_sub_poly_trait_refs({:?} <: {:?})", a, b);
     cx.sub_poly_trait_refs(a_is_expected, origin, a, b)
@@ -465,7 +470,7 @@ pub fn mk_eq_impl_headers<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                                     origin: TypeOrigin,
                                     a: &ty::ImplHeader<'tcx>,
                                     b: &ty::ImplHeader<'tcx>)
-                                    -> UnitResult<'tcx>
+    -> InferResult<'tcx, ()>
 {
     debug!("mk_eq_impl_header({:?} = {:?})", a, b);
     match (a.trait_ref, b.trait_ref) {
@@ -574,6 +579,12 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
     Ok(infcx.tcx.erase_regions(&result))
 }
 
+impl<'tcx, T> InferOk<'tcx, T> {
+    fn unit(self) -> InferOk<'tcx, ()> {
+        InferOk { value: (), obligations: self.obligations }
+    }
+}
+
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn projection_mode(&self) -> ProjectionMode {
         self.projection_mode
@@ -661,39 +672,51 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 
     fn combine_fields(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-                      -> CombineFields<'a, 'tcx> {
-        CombineFields {infcx: self,
-                       a_is_expected: a_is_expected,
-                       trace: trace,
-                       cause: None}
+        -> CombineFields<'a, 'tcx>
+    {
+        CombineFields {
+            infcx: self,
+            a_is_expected: a_is_expected,
+            trace: trace,
+            cause: None,
+            obligations: PredicateObligations::new(),
+        }
     }
 
     pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-        -> RelateResult<'tcx, T>
+        -> InferResult<'tcx, T>
         where T: Relate<'a, 'tcx>
     {
-        self.combine_fields(a_is_expected, trace).equate().relate(a, b)
+        let mut equate = self.combine_fields(a_is_expected, trace).equate();
+        let result = equate.relate(a, b);
+        result.map(|t| InferOk { value: t, obligations: equate.obligations() })
     }
 
     pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-        -> RelateResult<'tcx, T>
+        -> InferResult<'tcx, T>
         where T: Relate<'a, 'tcx>
     {
-        self.combine_fields(a_is_expected, trace).sub().relate(a, b)
+        let mut sub = self.combine_fields(a_is_expected, trace).sub();
+        let result = sub.relate(a, b);
+        result.map(|t| InferOk { value: t, obligations: sub.obligations() })
     }
 
     pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-        -> RelateResult<'tcx, T>
+        -> InferResult<'tcx, T>
         where T: Relate<'a, 'tcx>
     {
-        self.combine_fields(a_is_expected, trace).lub().relate(a, b)
+        let mut lub = self.combine_fields(a_is_expected, trace).lub();
+        let result = lub.relate(a, b);
+        result.map(|t| InferOk { value: t, obligations: lub.obligations() })
     }
 
     pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-        -> RelateResult<'tcx, T>
+        -> InferResult<'tcx, T>
         where T: Relate<'a, 'tcx>
     {
-        self.combine_fields(a_is_expected, trace).glb().relate(a, b)
+        let mut glb = self.combine_fields(a_is_expected, trace).glb();
+        let result = glb.relate(a, b);
+        result.map(|t| InferOk { value: t, obligations: glb.obligations() })
     }
 
     fn start_snapshot(&self) -> CombinedSnapshot {
@@ -829,12 +852,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                      origin: TypeOrigin,
                      a: Ty<'tcx>,
                      b: Ty<'tcx>)
-                     -> UnitResult<'tcx>
+        -> InferResult<'tcx, ()>
     {
         debug!("sub_types({:?} <: {:?})", a, b);
         self.commit_if_ok(|_| {
             let trace = TypeTrace::types(origin, a_is_expected, a, b);
-            self.sub(a_is_expected, trace, &a, &b).map(|_| ())
+            self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
         })
     }
 
@@ -843,11 +866,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     origin: TypeOrigin,
                     a: Ty<'tcx>,
                     b: Ty<'tcx>)
-                    -> UnitResult<'tcx>
+        -> InferResult<'tcx, ()>
     {
         self.commit_if_ok(|_| {
             let trace = TypeTrace::types(origin, a_is_expected, a, b);
-            self.equate(a_is_expected, trace, &a, &b).map(|_| ())
+            self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
         })
     }
 
@@ -856,7 +879,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                           origin: TypeOrigin,
                           a: ty::TraitRef<'tcx>,
                           b: ty::TraitRef<'tcx>)
-                          -> UnitResult<'tcx>
+        -> InferResult<'tcx, ()>
     {
         debug!("eq_trait_refs({:?} <: {:?})",
                a,
@@ -866,7 +889,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 origin: origin,
                 values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
             };
-            self.equate(a_is_expected, trace, &a, &b).map(|_| ())
+            self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
         })
     }
 
@@ -875,7 +898,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                origin: TypeOrigin,
                                a: ty::PolyTraitRef<'tcx>,
                                b: ty::PolyTraitRef<'tcx>)
-                               -> UnitResult<'tcx>
+        -> InferResult<'tcx, ()>
     {
         debug!("sub_poly_trait_refs({:?} <: {:?})",
                a,
@@ -885,7 +908,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 origin: origin,
                 values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
             };
-            self.sub(a_is_expected, trace, &a, &b).map(|_| ())
+            self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit())
         })
     }
 
@@ -928,20 +951,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn equality_predicate(&self,
                               span: Span,
                               predicate: &ty::PolyEquatePredicate<'tcx>)
-                              -> UnitResult<'tcx> {
+        -> InferResult<'tcx, ()>
+    {
         self.commit_if_ok(|snapshot| {
             let (ty::EquatePredicate(a, b), skol_map) =
                 self.skolemize_late_bound_regions(predicate, snapshot);
             let origin = TypeOrigin::EquatePredicate(span);
-            let () = mk_eqty(self, false, origin, a, b)?;
-            self.leak_check(&skol_map, snapshot)
+            let eqty_ok = mk_eqty(self, false, origin, a, b)?;
+            self.leak_check(&skol_map, snapshot).map(|_| eqty_ok.unit())
         })
     }
 
     pub fn region_outlives_predicate(&self,
                                      span: Span,
                                      predicate: &ty::PolyRegionOutlivesPredicate)
-                                     -> UnitResult<'tcx> {
+        -> UnitResult<'tcx>
+    {
         self.commit_if_ok(|snapshot| {
             let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
                 self.skolemize_late_bound_regions(predicate, snapshot);
diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs
index 0505c9d627b..ece8c0c696a 100644
--- a/src/librustc/infer/sub.rs
+++ b/src/librustc/infer/sub.rs
@@ -16,6 +16,7 @@ use super::type_variable::{SubtypeOf, SupertypeOf};
 use ty::{self, Ty, TyCtxt};
 use ty::TyVar;
 use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
+use traits::PredicateObligations;
 use std::mem;
 
 /// Ensures `a` is made a subtype of `b`. Returns `a` on success.
@@ -27,6 +28,10 @@ impl<'a, 'tcx> Sub<'a, 'tcx> {
     pub fn new(f: CombineFields<'a, 'tcx>) -> Sub<'a, 'tcx> {
         Sub { fields: f }
     }
+
+    pub fn obligations(self) -> PredicateObligations<'tcx> {
+        self.fields.obligations
+    }
 }
 
 impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 810dfb960c6..11e8dae8717 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use dep_graph::DepGraph;
-use infer::InferCtxt;
+use infer::{InferCtxt, InferOk};
 use ty::{self, Ty, TyCtxt, TypeFoldable, ToPolyTraitRef};
 use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error};
 use std::iter;
@@ -580,7 +580,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
 
         ty::Predicate::Equate(ref binder) => {
             match selcx.infcx().equality_predicate(obligation.cause.span, binder) {
-                Ok(()) => Ok(Some(Vec::new())),
+                Ok(InferOk { obligations, .. }) => {
+                    // FIXME(#32730) propagate obligations
+                    assert!(obligations.is_empty());
+                    Ok(Some(Vec::new()))
+                },
                 Err(_) => Err(CodeSelectionError(Unimplemented)),
             }
         }
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index f7b75c2259e..d4d61ec0244 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -24,7 +24,7 @@ use super::VtableImplData;
 use super::util;
 
 use middle::def_id::DefId;
-use infer::{self, TypeOrigin};
+use infer::{self, InferOk, TypeOrigin};
 use ty::subst::Subst;
 use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
 use ty::fold::{TypeFoldable, TypeFolder};
@@ -232,7 +232,11 @@ fn project_and_unify_type<'cx,'tcx>(
     let infcx = selcx.infcx();
     let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
     match infer::mk_eqty(infcx, true, origin, normalized_ty, obligation.predicate.ty) {
-        Ok(()) => Ok(Some(obligations)),
+        Ok(InferOk { obligations: inferred_obligations, .. }) => {
+            // FIXME(#32730) propagate obligations
+            assert!(inferred_obligations.is_empty());
+            Ok(Some(obligations))
+        },
         Err(err) => Err(MismatchedProjectionTypes { err: err }),
     }
 }
@@ -278,7 +282,10 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext
             let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
             let obligation_ty = obligation.predicate.ty;
             match infer::mk_eqty(infcx, true, origin, obligation_ty, ret_type) {
-                Ok(()) => { }
+                Ok(InferOk { obligations, .. }) => {
+                    // FIXME(#32730) propagate obligations
+                    assert!(obligations.is_empty());
+                }
                 Err(_) => { /* ignore errors */ }
             }
         }
@@ -829,7 +836,10 @@ fn assemble_candidates_from_predicates<'cx,'tcx,I>(
                     infcx.sub_poly_trait_refs(false,
                                               origin,
                                               data_poly_trait_ref,
-                                              obligation_poly_trait_ref).is_ok()
+                                              obligation_poly_trait_ref)
+                        // FIXME(#32730) propagate obligations
+                        .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
+                        .is_ok()
                 });
 
                 debug!("assemble_candidates_from_predicates: candidate={:?} \
@@ -1082,7 +1092,10 @@ fn confirm_param_env_candidate<'cx,'tcx>(
                               origin,
                               obligation.predicate.trait_ref.clone(),
                               projection.projection_ty.trait_ref.clone()) {
-        Ok(()) => { }
+        Ok(InferOk { obligations, .. }) => {
+            // FIXME(#32730) propagate obligations
+            assert!(obligations.is_empty());
+        }
         Err(e) => {
             span_bug!(
                 obligation.cause.span,
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 7635ff1eb4c..f68386feddb 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -38,7 +38,7 @@ use super::util;
 
 use middle::def_id::DefId;
 use infer;
-use infer::{InferCtxt, TypeFreshener, TypeOrigin};
+use infer::{InferCtxt, InferOk, TypeFreshener, TypeOrigin};
 use ty::subst::{Subst, Substs, TypeSpace};
 use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
 use traits;
@@ -484,7 +484,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::Predicate::Equate(ref p) => {
                 // does this code ever run?
                 match self.infcx.equality_predicate(obligation.cause.span, p) {
-                    Ok(()) => EvaluatedToOk,
+                    Ok(InferOk { obligations, .. }) => {
+                        // FIXME(#32730) propagate obligations
+                        assert!(obligations.is_empty());
+                        EvaluatedToOk
+                    },
                     Err(_) => EvaluatedToErr
                 }
             }
@@ -1185,7 +1189,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                              origin,
                                              trait_bound.clone(),
                                              ty::Binder(skol_trait_ref.clone())) {
-            Ok(()) => { }
+            Ok(InferOk { obligations, .. }) => {
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
+            }
             Err(_) => { return false; }
         }
 
@@ -2487,13 +2494,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let origin = TypeOrigin::RelateOutputImplTypes(obligation_cause.span);
 
         let obligation_trait_ref = obligation_trait_ref.clone();
-        match self.infcx.sub_poly_trait_refs(false,
-                                             origin,
-                                             expected_trait_ref.clone(),
-                                             obligation_trait_ref.clone()) {
-            Ok(()) => Ok(()),
-            Err(e) => Err(OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
-        }
+        self.infcx.sub_poly_trait_refs(false,
+                                       origin,
+                                       expected_trait_ref.clone(),
+                                       obligation_trait_ref.clone())
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
+            .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
     }
 
     fn confirm_builtin_unsize_candidate(&mut self,
@@ -2524,9 +2531,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                 let new_trait = tcx.mk_trait(data_a.principal.clone(), bounds);
                 let origin = TypeOrigin::Misc(obligation.cause.span);
-                if self.infcx.sub_types(false, origin, new_trait, target).is_err() {
-                    return Err(Unimplemented);
-                }
+                let InferOk { obligations, .. } =
+                    self.infcx.sub_types(false, origin, new_trait, target)
+                    .map_err(|_| Unimplemented)?;
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
 
                 // Register one obligation for 'a: 'b.
                 let cause = ObligationCause::new(obligation.cause.span,
@@ -2589,9 +2598,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // [T; n] -> [T].
             (&ty::TyArray(a, _), &ty::TySlice(b)) => {
                 let origin = TypeOrigin::Misc(obligation.cause.span);
-                if self.infcx.sub_types(false, origin, a, b).is_err() {
-                    return Err(Unimplemented);
-                }
+                let InferOk { obligations, .. } =
+                    self.infcx.sub_types(false, origin, a, b)
+                    .map_err(|_| Unimplemented)?;
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
             }
 
             // Struct<T> -> Struct<U>.
@@ -2647,9 +2658,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
                 let new_struct = tcx.mk_struct(def, tcx.mk_substs(new_substs));
                 let origin = TypeOrigin::Misc(obligation.cause.span);
-                if self.infcx.sub_types(false, origin, new_struct, target).is_err() {
-                    return Err(Unimplemented);
-                }
+                let InferOk { obligations, .. } =
+                    self.infcx.sub_types(false, origin, new_struct, target)
+                    .map_err(|_| Unimplemented)?;
+                // FIXME(#32730) propagate obligations
+                assert!(obligations.is_empty());
 
                 // Construct the nested Field<T>: Unsize<Field<U>> predicate.
                 nested.push(util::predicate_for_trait_def(tcx,
@@ -2734,13 +2747,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                skol_obligation_trait_ref);
 
         let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
-        if let Err(e) = self.infcx.eq_trait_refs(false,
-                                                 origin,
-                                                 impl_trait_ref.value.clone(),
-                                                 skol_obligation_trait_ref) {
-            debug!("match_impl: failed eq_trait_refs due to `{}`", e);
-            return Err(());
-        }
+        let InferOk { obligations, .. } =
+            self.infcx.eq_trait_refs(false,
+                                     origin,
+                                     impl_trait_ref.value.clone(),
+                                     skol_obligation_trait_ref)
+            .map_err(|e| {
+                debug!("match_impl: failed eq_trait_refs due to `{}`", e);
+                ()
+            })?;
+        // FIXME(#32730) propagate obligations
+        assert!(obligations.is_empty());
 
         if let Err(e) = self.infcx.leak_check(&skol_map, snapshot) {
             debug!("match_impl: failed leak check due to `{}`", e);
@@ -2803,13 +2820,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                poly_trait_ref);
 
         let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
-        match self.infcx.sub_poly_trait_refs(false,
-                                             origin,
-                                             poly_trait_ref,
-                                             obligation.predicate.to_poly_trait_ref()) {
-            Ok(()) => Ok(()),
-            Err(_) => Err(()),
-        }
+        self.infcx.sub_poly_trait_refs(false,
+                                       origin,
+                                       poly_trait_ref,
+                                       obligation.predicate.to_poly_trait_ref())
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
+            .map_err(|_| ())
     }
 
     ///////////////////////////////////////////////////////////////////////////
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 6ce623a3b28..ce0d42203b9 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -24,8 +24,8 @@ use rustc::ty::subst;
 use rustc::ty::subst::Subst;
 use rustc::traits::ProjectionMode;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::relate::{TypeRelation, RelateResult};
-use rustc::infer::{self, TypeOrigin};
+use rustc::ty::relate::TypeRelation;
+use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
 use rustc_metadata::cstore::CStore;
 use rustc::front::map as hir_map;
 use rustc::session::{self, config};
@@ -355,17 +355,17 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
         infer::TypeTrace::dummy(self.tcx())
     }
 
-    pub fn sub(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+    pub fn sub(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
         let trace = self.dummy_type_trace();
         self.infcx.sub(true, trace, t1, t2)
     }
 
-    pub fn lub(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+    pub fn lub(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
         let trace = self.dummy_type_trace();
         self.infcx.lub(true, trace, t1, t2)
     }
 
-    pub fn glb(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+    pub fn glb(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
         let trace = self.dummy_type_trace();
         self.infcx.glb(true, trace, t1, t2)
     }
@@ -374,7 +374,10 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
     /// region checks).
     pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
         match self.sub(&t1, &t2) {
-            Ok(_) => {}
+            Ok(InferOk { obligations, .. }) => {
+                // FIXME(#32730) once obligations are being propagated, assert the right thing.
+                assert!(obligations.is_empty());
+            }
             Err(ref e) => {
                 panic!("unexpected error computing sub({:?},{:?}): {}", t1, t2, e);
             }
@@ -395,7 +398,10 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
     /// Checks that `LUB(t1,t2) == t_lub`
     pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
         match self.lub(&t1, &t2) {
-            Ok(t) => {
+            Ok(InferOk { obligations, value: t }) => {
+                // FIXME(#32730) once obligations are being propagated, assert the right thing.
+                assert!(obligations.is_empty());
+
                 self.assert_eq(t, t_lub);
             }
             Err(ref e) => {
@@ -411,7 +417,10 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
             Err(e) => {
                 panic!("unexpected error computing LUB: {:?}", e)
             }
-            Ok(t) => {
+            Ok(InferOk { obligations, value: t }) => {
+                // FIXME(#32730) once obligations are being propagated, assert the right thing.
+                assert!(obligations.is_empty());
+
                 self.assert_eq(t, t_glb);
 
                 // sanity check for good measure:
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index 6cfde27ac97..ce8ede7f4b9 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -12,7 +12,7 @@
 #![allow(unreachable_code)]
 
 use rustc::dep_graph::DepNode;
-use rustc::infer::{self, InferCtxt};
+use rustc::infer::{self, InferCtxt, InferOk};
 use rustc::traits::{self, ProjectionMode};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::{self, Ty, TyCtxt};
@@ -338,6 +338,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     {
         infer::mk_subty(self.infcx, false, infer::TypeOrigin::Misc(span),
                         sup, sub)
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
     }
 
     fn mk_eqty(&self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>)
@@ -345,6 +347,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     {
         infer::mk_eqty(self.infcx, false, infer::TypeOrigin::Misc(span),
                        a, b)
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
     }
 
     fn tcx(&self) -> &'a TyCtxt<'tcx> {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 6dad3ff850b..55c3a5add37 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use middle::def::{self, Def};
-use rustc::infer::{self, TypeOrigin};
+use rustc::infer::{self, InferOk, TypeOrigin};
 use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding};
 use middle::pat_util::pat_is_resolved_const;
 use rustc::ty::subst::Substs;
@@ -531,7 +531,12 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         };
 
         let result = if is_if_let_fallback {
-            fcx.infcx().eq_types(true, origin, arm_ty, result_ty).map(|_| arm_ty)
+            fcx.infcx().eq_types(true, origin, arm_ty, result_ty)
+                .map(|InferOk { obligations, .. }| {
+                    // FIXME(#32730) propagate obligations
+                    assert!(obligations.is_empty());
+                    arm_ty
+                })
         } else if i == 0 {
             // Special-case the first arm, as it has no "previous expressions".
             coercion::try(fcx, &arm.body, coerce_first)
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 70467e2d2dd..cafd0519c28 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -62,7 +62,7 @@
 
 use check::{autoderef, FnCtxt, UnresolvedTypeAction};
 
-use rustc::infer::{Coercion, TypeOrigin, TypeTrace};
+use rustc::infer::{Coercion, InferOk, TypeOrigin, TypeTrace};
 use rustc::traits::{self, ObligationCause};
 use rustc::traits::{predicate_for_trait_def, report_selection_error};
 use rustc::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
@@ -118,8 +118,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             let trace = TypeTrace::types(self.origin, false, a, b);
             if self.use_lub {
                 infcx.lub(false, trace, &a, &b)
+                    .map(|InferOk { value, obligations }| {
+                        // FIXME(#32730) propagate obligations
+                        assert!(obligations.is_empty());
+                        value
+                    })
             } else {
                 infcx.sub(false, trace, &a, &b)
+                    .map(|InferOk { value, obligations }| {
+                        // FIXME(#32730) propagate obligations
+                        assert!(obligations.is_empty());
+                        value
+                    })
             }
         })
     }
@@ -655,12 +665,22 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>,
         (&ty::TyFnDef(a_def_id, a_substs, a_fty),
          &ty::TyFnDef(b_def_id, b_substs, b_fty)) => {
             // The signature must always match.
-            let fty = fcx.infcx().lub(true, trace.clone(), a_fty, b_fty)?;
+            let fty = fcx.infcx().lub(true, trace.clone(), a_fty, b_fty)
+                .map(|InferOk { value, obligations }| {
+                    // FIXME(#32730) propagate obligations
+                    assert!(obligations.is_empty());
+                    value
+                })?;
 
             if a_def_id == b_def_id {
                 // Same function, maybe the parameters match.
                 let substs = fcx.infcx().commit_if_ok(|_| {
                     fcx.infcx().lub(true, trace.clone(), a_substs, b_substs)
+                        .map(|InferOk { value, obligations }| {
+                            // FIXME(#32730) propagate obligations
+                            assert!(obligations.is_empty());
+                            value
+                        })
                 }).map(|s| fcx.tcx().mk_substs(s));
 
                 if let Ok(substs) = substs {
@@ -724,6 +744,11 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>,
         if !noop {
             return fcx.infcx().commit_if_ok(|_| {
                 fcx.infcx().lub(true, trace.clone(), &prev_ty, &new_ty)
+                    .map(|InferOk { value, obligations }| {
+                        // FIXME(#32730) propagate obligations
+                        assert!(obligations.is_empty());
+                        value
+                    })
             });
         }
     }
@@ -736,6 +761,11 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>,
             } else {
                 fcx.infcx().commit_if_ok(|_| {
                     fcx.infcx().lub(true, trace, &prev_ty, &new_ty)
+                        .map(|InferOk { value, obligations }| {
+                            // FIXME(#32730) propagate obligations
+                            assert!(obligations.is_empty());
+                            value
+                        })
                 })
             }
         }
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 6d429fa7b73..3c12ab8d598 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use middle::free_region::FreeRegionMap;
-use rustc::infer::{self, TypeOrigin};
+use rustc::infer::{self, InferOk, TypeOrigin};
 use rustc::ty::{self, TyCtxt};
 use rustc::traits::{self, ProjectionMode};
 use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace};
@@ -475,7 +475,10 @@ pub fn compare_const_impl<'tcx>(tcx: &TyCtxt<'tcx>,
     });
 
     match err {
-        Ok(()) => { }
+        Ok(InferOk { obligations, .. }) => {
+            // FIXME(#32730) propagate obligations
+            assert!(obligations.is_empty())
+        }
         Err(terr) => {
             debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
                    impl_ty,
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index d8bdf6c61aa..bc2ef9aafee 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -11,7 +11,7 @@
 
 use check::{coercion, FnCtxt};
 use rustc::ty::Ty;
-use rustc::infer::TypeOrigin;
+use rustc::infer::{InferOk, TypeOrigin};
 
 use syntax::codemap::Span;
 use rustc_front::hir;
@@ -21,16 +21,28 @@ use rustc_front::hir;
 pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
                          expected: Ty<'tcx>, actual: Ty<'tcx>) {
     let origin = TypeOrigin::Misc(sp);
-    if let Err(e) = fcx.infcx().sub_types(false, origin, actual, expected) {
-        fcx.infcx().report_mismatched_types(origin, expected, actual, e);
+    match fcx.infcx().sub_types(false, origin, actual, expected) {
+        Ok(InferOk { obligations, .. }) => {
+            // FIXME(#32730) propagate obligations
+            assert!(obligations.is_empty());
+        },
+        Err(e) => {
+            fcx.infcx().report_mismatched_types(origin, expected, actual, e);
+        }
     }
 }
 
 pub fn eqtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
                         expected: Ty<'tcx>, actual: Ty<'tcx>) {
     let origin = TypeOrigin::Misc(sp);
-    if let Err(e) = fcx.infcx().eq_types(false, origin, actual, expected) {
-        fcx.infcx().report_mismatched_types(origin, expected, actual, e);
+    match fcx.infcx().eq_types(false, origin, actual, expected) {
+        Ok(InferOk { obligations, .. }) => {
+            // FIXME(#32730) propagate obligations
+            assert!(obligations.is_empty());
+        },
+        Err(e) => {
+            fcx.infcx().report_mismatched_types(origin, expected, actual, e);
+        }
     }
 }
 
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index c4a8022071b..2e15ac0e130 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -21,8 +21,7 @@ use rustc::ty::subst;
 use rustc::ty::subst::Subst;
 use rustc::traits;
 use rustc::ty::{self, NoPreference, Ty, TyCtxt, ToPolyTraitRef, TraitRef, TypeFoldable};
-use rustc::infer;
-use rustc::infer::{InferCtxt, TypeOrigin};
+use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin};
 use syntax::ast;
 use syntax::codemap::{Span, DUMMY_SP};
 use rustc_front::hir;
@@ -1151,6 +1150,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
 
     fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::UnitResult<'tcx> {
         self.infcx().sub_types(false, TypeOrigin::Misc(DUMMY_SP), sub, sup)
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
     }
 
     fn has_applicable_self(&self, item: &ty::ImplOrTraitItem) -> bool {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 6c3469c9d72..e485fbe1621 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -88,8 +88,7 @@ use middle::astconv_util::prohibit_type_params;
 use middle::cstore::LOCAL_CRATE;
 use middle::def::{self, Def};
 use middle::def_id::DefId;
-use rustc::infer;
-use rustc::infer::{TypeOrigin, TypeTrace, type_variable};
+use rustc::infer::{self, InferOk, TypeOrigin, TypeTrace, type_variable};
 use middle::pat_util::{self, pat_id_map};
 use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
 use rustc::traits::{self, report_fulfillment_errors, ProjectionMode};
@@ -1627,6 +1626,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     sup: Ty<'tcx>)
                     -> Result<(), TypeError<'tcx>> {
         infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
     }
 
     pub fn mk_eqty(&self,
@@ -1636,6 +1637,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                    sup: Ty<'tcx>)
                    -> Result<(), TypeError<'tcx>> {
         infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
+            // FIXME(#32730) propagate obligations
+            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
     }
 
     pub fn mk_subr(&self,
@@ -1914,7 +1917,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     match infer::mk_eqty(self.infcx(), false,
                                                          TypeOrigin::Misc(default.origin_span),
                                                          ty, default.ty) {
-                                        Ok(()) => {}
+                                        Ok(InferOk { obligations, .. }) => {
+                                            // FIXME(#32730) propagate obligations
+                                            assert!(obligations.is_empty())
+                                        },
                                         Err(_) => {
                                             conflicts.push((*ty, default));
                                         }
@@ -2007,7 +2013,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             match infer::mk_eqty(self.infcx(), false,
                                                  TypeOrigin::Misc(default.origin_span),
                                                  ty, default.ty) {
-                                Ok(()) => {}
+                                // FIXME(#32730) propagate obligations
+                                Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
                                 Err(_) => {
                                     result = Some(default);
                                 }
@@ -2773,8 +2780,10 @@ fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
                 // FIXME(#15760) can't use try! here, FromError doesn't default
                 // to identity so the resulting type is not constrained.
-                if let Err(e) = ures {
-                    return Err(e);
+                match ures {
+                    // FIXME(#32730) propagate obligations
+                    Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
+                    Err(e) => return Err(e),
                 }
 
                 // Record all the argument types, with the substitutions
@@ -2902,13 +2911,23 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 fcx.infcx().commit_if_ok(|_| {
                     let trace = TypeTrace::types(origin, true, then_ty, else_ty);
                     fcx.infcx().lub(true, trace, &then_ty, &else_ty)
+                        .map(|InferOk { value, obligations }| {
+                            // FIXME(#32730) propagate obligations
+                            assert!(obligations.is_empty());
+                            value
+                        })
                 })
             };
             (origin, then_ty, else_ty, result)
         } else {
             let origin = TypeOrigin::IfExpressionWithNoElse(sp);
             (origin, unit, then_ty,
-             fcx.infcx().eq_types(true, origin, unit, then_ty).map(|_| unit))
+             fcx.infcx().eq_types(true, origin, unit, then_ty)
+                 .map(|InferOk { obligations, .. }| {
+                     // FIXME(#32730) propagate obligations
+                     assert!(obligations.is_empty());
+                     unit
+                 }))
         };
 
         let if_ty = match result {
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 283245bd6f4..15bf6671de5 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -92,7 +92,7 @@ use middle::region::{self, CodeExtent};
 use rustc::ty::subst::Substs;
 use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, MethodCall, TypeFoldable};
-use rustc::infer::{self, GenericKind, InferCtxt, SubregionOrigin, TypeOrigin, VerifyBound};
+use rustc::infer::{self, GenericKind, InferCtxt, InferOk, SubregionOrigin, TypeOrigin, VerifyBound};
 use middle::pat_util;
 use rustc::ty::adjustment;
 use rustc::ty::wf::ImpliedBound;
@@ -1841,7 +1841,11 @@ fn declared_projection_bounds_from_trait<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
 
                 // check whether this predicate applies to our current projection
                 match infer::mk_eqty(infcx, false, TypeOrigin::Misc(span), ty, outlives.0) {
-                    Ok(()) => { Ok(outlives.1) }
+                    Ok(InferOk { obligations, .. }) => {
+                        // FIXME(#32730) propagate obligations
+                        assert!(obligations.is_empty());
+                        Ok(outlives.1)
+                    }
                     Err(_) => { Err(()) }
                 }
             });