diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index 5664777772f7..dae30ea97c80 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 535156e61e94..f406580286da 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 6ab7a1fbfb8a..986e4192f889 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 6c75fb6a246e..c25e7ee344f6 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 78912f607faa..0ceed274b6da 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>) - -> infer::UnitResult<'tcx> - { - self.infcx.sub_types(false, &self.misc(span), sup, sub) - // FIXME(#32730) propagate obligations - .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) + pub fn register_infer_ok_obligations(&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 eq_types(&self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>) + fn sub_types(&mut self, sup: Ty<'tcx>, sub: Ty<'tcx>) + -> infer::UnitResult<'tcx> + { + self.infcx.sub_types(false, &self.misc(self.last_span), sup, sub) + .map(|ok| self.register_infer_ok_obligations(ok)) + } + + 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 d57a27ddc761..556d1f84fccd 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 7a7ea760c038..718c273785ae 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 075567c79492..2602ff05badd 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 8a0f1478a736..ef1c08bdab54 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 f9e1db141c8b..54e93978b798 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 71696c0abea9..545d4e788524 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 76cd3c4a1eb7..8e9dfe54f013 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>) + { + for obligation in obligations { + self.register_predicate(obligation); + } + } + + pub fn register_infer_ok_obligations(&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 e41c149b178c..a280001d5e99 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(()) }