about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-08-24 18:09:46 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-11-15 16:12:41 -0500
commit48dc6e26ca2ccb72a241ea42af509c4dcf3636fb (patch)
treec1a736d5f540c0360248c85ffee208bd48c2df92 /src
parent19c1a47713bfba32ded7d8c32ceb36423fe44e35 (diff)
downloadrust-48dc6e26ca2ccb72a241ea42af509c4dcf3636fb.tar.gz
rust-48dc6e26ca2ccb72a241ea42af509c4dcf3636fb.zip
register `infer-ok` obligations properly
Or at least, more properly. I think I left one or two FIXMEs still in
there.

cc #32730
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/sub.rs3
-rw-r--r--src/librustc/traits/fulfill.rs6
-rw-r--r--src/librustc/traits/project.rs17
-rw-r--r--src/librustc/traits/select.rs3
-rw-r--r--src/librustc_mir/transform/type_check.rs37
-rw-r--r--src/librustc_typeck/check/_match.rs7
-rw-r--r--src/librustc_typeck/check/coercion.rs33
-rw-r--r--src/librustc_typeck/check/compare_method.rs9
-rw-r--r--src/librustc_typeck/check/demand.rs10
-rw-r--r--src/librustc_typeck/check/method/confirm.rs5
-rw-r--r--src/librustc_typeck/check/method/probe.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs67
-rw-r--r--src/librustc_typeck/check/regionck.rs7
13 files changed, 89 insertions, 119 deletions
diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs
index 5664777772f..dae30ea97c8 100644
--- a/src/librustc/infer/sub.rs
+++ b/src/librustc/infer/sub.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::combine::CombineFields;
 use super::SubregionOrigin;
+use super::combine::CombineFields;
 use super::type_variable::{SubtypeOf, SupertypeOf};
 
 use ty::{self, Ty, TyCtxt};
@@ -117,6 +117,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
         // error messages.
         let origin = SubregionOrigin::Subtype(self.fields.trace.clone());
         self.fields.infcx.region_vars.make_subregion(origin, a, b);
+
         Ok(a)
     }
 
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 535156e61e9..f406580286d 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -520,10 +520,8 @@ fn process_predicate<'a, 'gcx, 'tcx>(
 
         ty::Predicate::Equate(ref binder) => {
             match selcx.infcx().equality_predicate(&obligation.cause, binder) {
-                Ok(InferOk { obligations, .. }) => {
-                    // FIXME(#32730) propagate obligations
-                    assert!(obligations.is_empty());
-                    Ok(Some(Vec::new()))
+                Ok(InferOk { obligations, value: () }) => {
+                    Ok(Some(obligations))
                 },
                 Err(_) => Err(CodeSelectionError(Unimplemented)),
             }
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 6ab7a1fbfb8..986e4192f88 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -210,9 +210,7 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>(
 
     let infcx = selcx.infcx();
     match infcx.eq_types(true, &obligation.cause, normalized_ty, obligation.predicate.ty) {
-        Ok(InferOk { obligations: inferred_obligations, .. }) => {
-            // FIXME(#32730) once obligations are generated in inference, drop this assertion
-            assert!(inferred_obligations.is_empty());
+        Ok(InferOk { obligations: inferred_obligations, value: () }) => {
             obligations.extend(inferred_obligations);
             Ok(Some(obligations))
         },
@@ -847,9 +845,10 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
                                               obligation.cause.clone(),
                                               data_poly_trait_ref,
                                               obligation_poly_trait_ref)
-                        // FIXME(#32730) once obligations are propagated from unification in
-                        // inference, drop this assertion
-                        .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
+                        .map(|InferOk { obligations: _, value: () }| {
+                            // FIXME(#32730) -- do we need to take obligations
+                            // into account in any way? At the moment, no.
+                        })
                         .is_ok()
                 });
 
@@ -1184,12 +1183,10 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
     fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
     -> Progress<'tcx>
 {
-    // FIXME(#32730) drop this assertion once obligations are propagated from inference (fn pointer
-    // vtable nested obligations ONLY come from unification in inference)
-    assert!(fn_pointer_vtable.nested.is_empty());
     let fn_type = selcx.infcx().shallow_resolve(fn_pointer_vtable.fn_ty);
     let sig = fn_type.fn_sig();
     confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
+        .with_addl_obligations(fn_pointer_vtable.nested)
 }
 
 fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
@@ -1266,8 +1263,6 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>(
     let trait_ref = obligation.predicate.trait_ref;
     match infcx.match_poly_projection_predicate(cause, poly_projection, trait_ref) {
         Ok(InferOk { value: ty_match, obligations }) => {
-            // FIXME(#32730) once obligations are generated in inference, drop this assertion
-            assert!(obligations.is_empty());
             Progress {
                 ty: ty_match.value,
                 obligations: obligations,
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 6c75fb6a246..c25e7ee344f 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -418,9 +418,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             None => Ok(None),
             Some(candidate) => {
                 let mut candidate = self.confirm_candidate(obligation, candidate)?;
-                // FIXME(#32730) remove this assertion once inferred obligations are propagated
-                // from inference
-                assert!(self.inferred_obligations.len() == 0);
                 let inferred_obligations = (*self.inferred_obligations).into_iter().cloned();
                 candidate.nested_obligations_mut().extend(inferred_obligations);
                 Ok(Some(candidate))
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index 78912f607fa..0ceed274b6d 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -324,20 +324,25 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         traits::ObligationCause::misc(span, self.body_id)
     }
 
-    fn sub_types(&self, span: Span, sup: Ty<'tcx>, sub: Ty<'tcx>)
+    pub fn register_infer_ok_obligations<T>(&mut self, infer_ok: InferOk<'tcx, T>) -> T {
+        for obligation in infer_ok.obligations {
+            self.fulfillment_cx.register_predicate_obligation(self.infcx, obligation);
+        }
+        infer_ok.value
+    }
+
+    fn sub_types(&mut self, sup: Ty<'tcx>, sub: Ty<'tcx>)
                  -> infer::UnitResult<'tcx>
     {
-        self.infcx.sub_types(false, &self.misc(span), sup, sub)
-            // FIXME(#32730) propagate obligations
-            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
+        self.infcx.sub_types(false, &self.misc(self.last_span), sup, sub)
+            .map(|ok| self.register_infer_ok_obligations(ok))
     }
 
-    fn eq_types(&self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>)
+    fn eq_types(&mut self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>)
                 -> infer::UnitResult<'tcx>
     {
         self.infcx.eq_types(false, &self.misc(span), a, b)
-            // FIXME(#32730) propagate obligations
-            .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
+            .map(|ok| self.register_infer_ok_obligations(ok))
     }
 
     fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
@@ -352,7 +357,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 let lv_ty = lv.ty(mir, tcx).to_ty(tcx);
                 let rv_ty = rv.ty(mir, tcx);
                 if let Some(rv_ty) = rv_ty {
-                    if let Err(terr) = self.sub_types(self.last_span, rv_ty, lv_ty) {
+                    if let Err(terr) = self.sub_types(rv_ty, lv_ty) {
                         span_mirbug!(self, stmt, "bad assignment ({:?} = {:?}): {:?}",
                                      lv_ty, rv_ty, terr);
                     }
@@ -413,7 +418,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             } => {
                 let lv_ty = location.ty(mir, tcx).to_ty(tcx);
                 let rv_ty = value.ty(mir, tcx);
-                if let Err(terr) = self.sub_types(self.last_span, rv_ty, lv_ty) {
+                if let Err(terr) = self.sub_types(rv_ty, lv_ty) {
                     span_mirbug!(self, term, "bad DropAndReplace ({:?} = {:?}): {:?}",
                                  lv_ty, rv_ty, terr);
                 }
@@ -430,7 +435,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             }
             TerminatorKind::SwitchInt { ref discr, switch_ty, .. } => {
                 let discr_ty = discr.ty(mir, tcx).to_ty(tcx);
-                if let Err(terr) = self.sub_types(self.last_span, discr_ty, switch_ty) {
+                if let Err(terr) = self.sub_types(discr_ty, switch_ty) {
                     span_mirbug!(self, term, "bad SwitchInt ({:?} on {:?}): {:?}",
                                  switch_ty, discr_ty, terr);
                 }
@@ -492,7 +497,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         }
     }
 
-    fn check_call_dest(&self,
+    fn check_call_dest(&mut self,
                        mir: &Mir<'tcx>,
                        term: &Terminator<'tcx>,
                        sig: &ty::FnSig<'tcx>,
@@ -501,7 +506,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         match *destination {
             Some((ref dest, _)) => {
                 let dest_ty = dest.ty(mir, tcx).to_ty(tcx);
-                if let Err(terr) = self.sub_types(self.last_span, sig.output, dest_ty) {
+                if let Err(terr) = self.sub_types(sig.output, dest_ty) {
                     span_mirbug!(self, term,
                                  "call dest mismatch ({:?} <- {:?}): {:?}",
                                  dest_ty, sig.output, terr);
@@ -516,7 +521,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         }
     }
 
-    fn check_call_inputs(&self,
+    fn check_call_inputs(&mut self,
                          mir: &Mir<'tcx>,
                          term: &Terminator<'tcx>,
                          sig: &ty::FnSig<'tcx>,
@@ -529,7 +534,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         }
         for (n, (fn_arg, op_arg)) in sig.inputs.iter().zip(args).enumerate() {
             let op_arg_ty = op_arg.ty(mir, self.tcx());
-            if let Err(terr) = self.sub_types(self.last_span, op_arg_ty, fn_arg) {
+            if let Err(terr) = self.sub_types(op_arg_ty, fn_arg) {
                 span_mirbug!(self, term, "bad arg #{:?} ({:?} <- {:?}): {:?}",
                              n, fn_arg, op_arg_ty, terr);
             }
@@ -547,7 +552,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         }
     }
 
-    fn check_box_free_inputs(&self,
+    fn check_box_free_inputs(&mut self,
                              mir: &Mir<'tcx>,
                              term: &Terminator<'tcx>,
                              sig: &ty::FnSig<'tcx>,
@@ -584,7 +589,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             }
         };
 
-        if let Err(terr) = self.sub_types(self.last_span, arg_ty, pointee_ty) {
+        if let Err(terr) = self.sub_types(arg_ty, pointee_ty) {
             span_mirbug!(self, term, "bad box_free arg ({:?} <- {:?}): {:?}",
                          pointee_ty, arg_ty, terr);
         }
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index d57a27ddc76..556d1f84fcc 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -11,7 +11,7 @@
 use rustc::hir::{self, PatKind};
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
-use rustc::infer::{self, InferOk};
+use rustc::infer;
 use rustc::traits::ObligationCauseCode;
 use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
 use check::{FnCtxt, Expectation, Diverges};
@@ -462,9 +462,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
             let result = if is_if_let_fallback {
                 self.eq_types(true, &cause, arm_ty, result_ty)
-                    .map(|InferOk { obligations, .. }| {
-                        // FIXME(#32730) propagate obligations
-                        assert!(obligations.is_empty());
+                    .map(|infer_ok| {
+                        self.register_infer_ok_obligations(infer_ok);
                         arm_ty
                     })
             } else if i == 0 {
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 7a7ea760c03..718c273785a 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -118,16 +118,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
             let trace = TypeTrace::types(&self.cause, false, a, b);
             if self.use_lub {
                 self.lub(false, trace, &a, &b)
-                    .map(|InferOk { value, obligations }| {
-                        // FIXME(#32730) propagate obligations
-                        assert!(obligations.is_empty());
-                        value
-                    })
+                    .map(|ok| self.register_infer_ok_obligations(ok))
             } else {
                 self.sub(false, trace, &a, &b)
                     .map(|InferOk { value, obligations }| {
-                        // FIXME(#32730) propagate obligations
-                        assert!(obligations.is_empty());
+                        self.fcx.register_predicates(obligations);
                         value
                     })
             }
@@ -678,21 +673,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, '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 = self.lub(true, trace.clone(), &a_fty, &b_fty)
-                    .map(|InferOk { value, obligations }| {
-                        // FIXME(#32730) propagate obligations
-                        assert!(obligations.is_empty());
-                        value
-                    })?;
+                              .map(|ok| self.register_infer_ok_obligations(ok))?;
 
                 if a_def_id == b_def_id {
                     // Same function, maybe the parameters match.
                     let substs = self.commit_if_ok(|_| {
                         self.lub(true, trace.clone(), &a_substs, &b_substs)
-                            .map(|InferOk { value, obligations }| {
-                                // FIXME(#32730) propagate obligations
-                                assert!(obligations.is_empty());
-                                value
-                            })
+                            .map(|ok| self.register_infer_ok_obligations(ok))
                     });
 
                     if let Ok(substs) = substs {
@@ -761,11 +748,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             if !noop {
                 return self.commit_if_ok(|_| {
                     self.lub(true, trace.clone(), &prev_ty, &new_ty)
-                        .map(|InferOk { value, obligations }| {
-                            // FIXME(#32730) propagate obligations
-                            assert!(obligations.is_empty());
-                            value
-                        })
+                        .map(|ok| self.register_infer_ok_obligations(ok))
                 });
             }
         }
@@ -778,11 +761,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 } else {
                     self.commit_if_ok(|_| {
                         self.lub(true, trace, &prev_ty, &new_ty)
-                            .map(|InferOk { value, obligations }| {
-                                // FIXME(#32730) propagate obligations
-                                assert!(obligations.is_empty());
-                                value
-                            })
+                            .map(|ok| self.register_infer_ok_obligations(ok))
                     })
                 }
             }
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 075567c7949..2602ff05bad 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -810,10 +810,11 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             debug!("compare_const_impl: trait_ty={:?}", trait_ty);
 
             infcx.sub_types(false, &cause, impl_ty, trait_ty)
-                .map(|InferOk { obligations, .. }| {
-                    // FIXME(#32730) propagate obligations
-                    assert!(obligations.is_empty())
-                })
+                 .map(|InferOk { obligations, value: () }| {
+                     for obligation in obligations {
+                         fulfillment_cx.register_predicate_obligation(&infcx, obligation);
+                     }
+                 })
         });
 
         if let Err(terr) = err {
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 8a0f1478a73..ef1c08bdab5 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -23,9 +23,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) {
         let cause = self.misc(sp);
         match self.sub_types(false, &cause, actual, expected) {
-            Ok(InferOk { obligations, .. }) => {
-                // FIXME(#32730) propagate obligations
-                assert!(obligations.is_empty());
+            Ok(InferOk { obligations, value: () }) => {
+                self.register_predicates(obligations);
             },
             Err(e) => {
                 self.report_mismatched_types(&cause, expected, actual, e);
@@ -43,9 +42,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                      actual: Ty<'tcx>)
     {
         match self.eq_types(false, cause, actual, expected) {
-            Ok(InferOk { obligations, .. }) => {
-                // FIXME(#32730) propagate obligations
-                assert!(obligations.is_empty());
+            Ok(InferOk { obligations, value: () }) => {
+                self.register_predicates(obligations);
             },
             Err(e) => {
                 self.report_mismatched_types(cause, expected, actual, e);
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index f9e1db141c8..54e93978b79 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -331,9 +331,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
 
     fn unify_receivers(&mut self, self_ty: Ty<'tcx>, method_self_ty: Ty<'tcx>) {
         match self.sub_types(false, &self.misc(self.span), self_ty, method_self_ty) {
-            Ok(InferOk { obligations, .. }) => {
-                // FIXME(#32730) propagate obligations
-                assert!(obligations.is_empty());
+            Ok(InferOk { obligations, value: () }) => {
+                self.register_predicates(obligations);
             }
             Err(_) => {
                 span_bug!(self.span,
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 71696c0abea..545d4e78852 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -16,10 +16,10 @@ use super::suggest;
 use check::FnCtxt;
 use hir::def_id::DefId;
 use hir::def::Def;
+use rustc::infer::InferOk;
 use rustc::ty::subst::{Subst, Substs};
 use rustc::traits::{self, ObligationCause};
 use rustc::ty::{self, Ty, ToPolyTraitRef, TraitRef, TypeFoldable};
-use rustc::infer::InferOk;
 use rustc::util::nodemap::FxHashSet;
 use syntax::ast;
 use syntax_pos::Span;
@@ -1035,7 +1035,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
                                  &ObligationCause::dummy(),
                                  self_ty,
                                  probe.xform_self_ty) {
-                Ok(InferOk { obligations, .. }) => {
+                Ok(InferOk { obligations, value: () }) => {
                     // FIXME(#32730) propagate obligations
                     assert!(obligations.is_empty())
                 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 76cd3c4a1eb..8e9dfe54f01 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1797,6 +1797,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             .register_predicate_obligation(self, obligation);
     }
 
+    pub fn register_predicates(&self,
+                               obligations: Vec<traits::PredicateObligation<'tcx>>)
+    {
+        for obligation in obligations {
+            self.register_predicate(obligation);
+        }
+    }
+
+    pub fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
+        self.register_predicates(infer_ok.obligations);
+        infer_ok.value
+    }
+
     pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
         let t = AstConv::ast_ty_to_ty(self, self, ast_t);
         self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
@@ -2110,13 +2123,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                         &self.misc(default.origin_span),
                                                         ty,
                                                         default.ty) {
-                                        Ok(InferOk { obligations, .. }) => {
-                                            // FIXME(#32730) propagate obligations
-                                            assert!(obligations.is_empty())
-                                        },
-                                        Err(_) => {
-                                            conflicts.push((*ty, default));
-                                        }
+                                        Ok(ok) => self.register_infer_ok_obligations(ok),
+                                        Err(_) => conflicts.push((*ty, default)),
                                     }
                                 }
                             }
@@ -2210,8 +2218,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                 &self.misc(default.origin_span),
                                                 ty,
                                                 default.ty) {
-                                // FIXME(#32730) propagate obligations
-                                Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
+                                Ok(ok) => self.register_infer_ok_obligations(ok),
                                 Err(_) => {
                                     result = Some(default);
                                 }
@@ -2784,8 +2791,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 // FIXME(#15760) can't use try! here, FromError doesn't default
                 // to identity so the resulting type is not constrained.
                 match ures {
-                    // FIXME(#32730) propagate obligations
-                    Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
+                    Ok(ok) => self.register_infer_ok_obligations(ok),
                     Err(e) => return Err(e),
                 }
 
@@ -2894,11 +2900,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 self.commit_if_ok(|_| {
                     let trace = TypeTrace::types(&cause, true, then_ty, else_ty);
                     self.lub(true, trace, &then_ty, &else_ty)
-                        .map(|InferOk { value, obligations }| {
-                            // FIXME(#32730) propagate obligations
-                            assert!(obligations.is_empty());
-                            value
-                        })
+                        .map(|ok| self.register_infer_ok_obligations(ok))
                 })
             };
 
@@ -2912,9 +2914,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             expected_ty = unit;
             found_ty = then_ty;
             result = self.eq_types(true, &cause, unit, then_ty)
-                         .map(|InferOk { obligations, .. }| {
-                             // FIXME(#32730) propagate obligations
-                             assert!(obligations.is_empty());
+                         .map(|ok| {
+                             self.register_infer_ok_obligations(ok);
                              unit
                          });
         }
@@ -3579,17 +3580,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             if let Some(ref e) = *expr_opt {
                 self.check_expr_coercable_to_type(&e, self.ret_ty);
             } else {
-                let eq_result = self.eq_types(false,
-                                              &self.misc(expr.span),
-                                              self.ret_ty,
-                                              tcx.mk_nil())
-                    // FIXME(#32730) propagate obligations
-                    .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()));
-                if eq_result.is_err() {
-                    struct_span_err!(tcx.sess, expr.span, E0069,
-                             "`return;` in a function whose return type is not `()`")
-                        .span_label(expr.span, &format!("return type is not ()"))
-                        .emit();
+                match self.eq_types(false,
+                                    &self.misc(expr.span),
+                                    self.ret_ty,
+                                    tcx.mk_nil())
+                {
+                    Ok(ok) => self.register_infer_ok_obligations(ok),
+                    Err(_) => {
+                        struct_span_err!(tcx.sess, expr.span, E0069,
+                                         "`return;` in a function whose return type is not `()`")
+                            .span_label(expr.span, &format!("return type is not ()"))
+                            .emit();
+                    }
                 }
             }
             tcx.types.never
@@ -4383,10 +4385,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
             let impl_ty = self.instantiate_type_scheme(span, &substs, &ty);
             match self.sub_types(false, &self.misc(span), self_ty, impl_ty) {
-                Ok(InferOk { obligations, .. }) => {
-                    // FIXME(#32730) propagate obligations
-                    assert!(obligations.is_empty());
-                }
+                Ok(ok) => self.register_infer_ok_obligations(ok),
                 Err(_) => {
                     span_bug!(span,
                         "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index e41c149b178..a280001d5e9 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -91,7 +91,7 @@ use middle::region::{self, CodeExtent};
 use rustc::ty::subst::Substs;
 use rustc::traits;
 use rustc::ty::{self, Ty, MethodCall, TypeFoldable};
-use rustc::infer::{self, GenericKind, InferOk, SubregionOrigin, VerifyBound};
+use rustc::infer::{self, GenericKind, SubregionOrigin, VerifyBound};
 use hir::pat_util;
 use rustc::ty::adjustment;
 use rustc::ty::wf::ImpliedBound;
@@ -1764,9 +1764,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
                     // check whether this predicate applies to our current projection
                     let cause = self.fcx.misc(span);
                     match self.eq_types(false, &cause, ty, outlives.0) {
-                        Ok(InferOk { obligations, .. }) => {
-                            // FIXME(#32730) propagate obligations
-                            assert!(obligations.is_empty());
+                        Ok(ok) => {
+                            self.register_infer_ok_obligations(ok);
                             Ok(outlives.1)
                         }
                         Err(_) => { Err(()) }