From dcdf3d62c1bd30e896d54374f49ed80a1a1348e5 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Tue, 29 Mar 2016 20:06:42 -0700 Subject: [PATCH 1/2] Plumb obligations through librustc/infer --- src/librustc/infer/combine.rs | 4 +- src/librustc/infer/equate.rs | 5 ++ src/librustc/infer/glb.rs | 5 ++ src/librustc/infer/lub.rs | 5 ++ src/librustc/infer/mod.rs | 94 +++++++++++++-------- src/librustc/infer/sub.rs | 5 ++ src/librustc/traits/fulfill.rs | 8 +- src/librustc/traits/project.rs | 23 +++-- src/librustc/traits/select.rs | 83 ++++++++++-------- src/librustc_driver/test.rs | 25 ++++-- src/librustc_mir/transform/type_check.rs | 6 +- src/librustc_typeck/check/_match.rs | 9 +- src/librustc_typeck/check/coercion.rs | 34 +++++++- src/librustc_typeck/check/compare_method.rs | 7 +- src/librustc_typeck/check/demand.rs | 22 +++-- src/librustc_typeck/check/method/probe.rs | 5 +- src/librustc_typeck/check/mod.rs | 33 ++++++-- src/librustc_typeck/check/regionck.rs | 8 +- 18 files changed, 274 insertions(+), 107 deletions(-) diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 2b30698882d62..6df8f076f32e8 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, + 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 3c9c9c5788414..5540046c9e363 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 235428a6898a9..37717c2b6bc99 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 00b85929b4b15..32b2fe911e86d 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 725c6d9593cdd..6e97cdef3d7ca 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, TypeError<'tcx>>; + pub type Bound = Option; pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result" pub type FixupResult = Result; // "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) { @@ -661,39 +666,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(&'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(&'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(&'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(&'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 +846,13 @@ 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(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) }) } @@ -843,11 +861,12 @@ 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(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) }) } @@ -856,7 +875,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 +885,8 @@ 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(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) }) } @@ -875,7 +895,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 +905,8 @@ 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(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) }) } @@ -928,20 +949,23 @@ 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)?; + let InferOk { obligations, .. } = mk_eqty(self, false, origin, a, b)?; self.leak_check(&skol_map, snapshot) + .map(|_| InferOk { value: (), obligations: obligations }) }) } 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 0505c9d627b9b..ece8c0c696af8 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 321144126c9f8..68173bc9ea513 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; @@ -526,7 +526,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(#????) 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 3adaf5fa6bb2f..85fe457c75e8c 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(#????) 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(#????) 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(#????) 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(#????) propagate obligations + assert!(obligations.is_empty()); + } Err(e) => { selcx.tcx().sess.span_bug( obligation.cause.span, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e2a48688d4bbc..013c75bf8d2bb 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(#????) 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(#????) propagate obligations + assert!(obligations.is_empty()); + } Err(_) => { return false; } } @@ -2494,13 +2501,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(#????) 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, @@ -2531,9 +2538,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(#????) propagate obligations + assert!(obligations.is_empty()); // Register one obligation for 'a: 'b. let cause = ObligationCause::new(obligation.cause.span, @@ -2596,9 +2605,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(#????) propagate obligations + assert!(obligations.is_empty()); } // Struct -> Struct. @@ -2654,9 +2665,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(#????) propagate obligations + assert!(obligations.is_empty()); // Construct the nested Field: Unsize> predicate. nested.push(util::predicate_for_trait_def(tcx, @@ -2742,13 +2755,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(#????) 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); @@ -2811,13 +2828,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(#????) 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 6ce623a3b2892..00569d50cbb9c 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 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 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 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 6cfde27ac97b6..3f85a3e1d4618 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(#????) 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(#????) 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 f8fa9c8e9b6cb..dcbfa2bb79b6c 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; @@ -532,7 +532,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(#????) 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 e36da1a568a7d..a4d8e2ae04938 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(#????) propagate obligations + assert!(obligations.is_empty()); + value + }) } else { infcx.sub(false, trace, &a, &b) + .map(|InferOk { value, obligations }| { + // FIXME(#????) propagate obligations + assert!(obligations.is_empty()); + value + }) } }) } @@ -656,12 +666,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(#????) 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(#????) propagate obligations + assert!(obligations.is_empty()); + value + }) }).map(|s| fcx.tcx().mk_substs(s)); if let Ok(substs) = substs { @@ -725,6 +745,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(#????) propagate obligations + assert!(obligations.is_empty()); + value + }) }); } } @@ -737,6 +762,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(#????) 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 6d429fa7b73a1..5f49b0335d929 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(#????) 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 d8bdf6c61aad4..75f6b11a22931 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(#????) 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(#????) 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 4b42846297b16..44dbcd051e201 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -20,8 +20,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; @@ -1135,6 +1134,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(#????) 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 107497a2aa367..625e59c6e3c63 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}; @@ -1629,6 +1628,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(#????) propagate obligations + .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) } pub fn mk_eqty(&self, @@ -1638,6 +1639,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(#????) propagate obligations + .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) } pub fn mk_subr(&self, @@ -1916,7 +1919,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(#????) propagate obligations + assert!(obligations.is_empty()) + }, Err(_) => { conflicts.push((*ty, default)); } @@ -2009,7 +2015,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match infer::mk_eqty(self.infcx(), false, TypeOrigin::Misc(default.origin_span), ty, default.ty) { - Ok(()) => {} + // FIXME(#????) propagate obligations + Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()), Err(_) => { result = Some(default); } @@ -2776,8 +2783,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(#????) propagate obligations + Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()), + Err(e) => return Err(e), } // Record all the argument types, with the substitutions @@ -2905,13 +2914,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(#????) 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(#????) 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 533d24686e71f..515a898699e0c 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; @@ -1846,7 +1846,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(#????) propagate obligations + assert!(obligations.is_empty()); + Ok(outlives.1) + } Err(_) => { Err(()) } } }); From 86071aca3dd729c77d238d449d2c61b2de0b8425 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Mon, 4 Apr 2016 12:41:05 -0700 Subject: [PATCH 2/2] Address nits --- src/librustc/infer/mod.rs | 23 +++++++++++---------- src/librustc/traits/fulfill.rs | 2 +- src/librustc/traits/project.rs | 8 +++---- src/librustc/traits/select.rs | 16 +++++++------- src/librustc_driver/test.rs | 6 +++--- src/librustc_mir/transform/type_check.rs | 4 ++-- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/coercion.rs | 12 +++++------ src/librustc_typeck/check/compare_method.rs | 2 +- src/librustc_typeck/check/demand.rs | 4 ++-- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/mod.rs | 14 ++++++------- src/librustc_typeck/check/regionck.rs | 2 +- 13 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 6e97cdef3d7ca..3bf618202e9b4 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -579,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 @@ -851,8 +857,7 @@ impl<'a, 'tcx> InferCtxt<'a, '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(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) + self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit()) }) } @@ -865,8 +870,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { { self.commit_if_ok(|_| { let trace = TypeTrace::types(origin, a_is_expected, a, b); - self.equate(a_is_expected, trace, &a, &b) - .map(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) + self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit()) }) } @@ -885,8 +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(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) + self.equate(a_is_expected, trace, &a, &b).map(|ok| ok.unit()) }) } @@ -905,8 +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(|InferOk { obligations, .. }| InferOk { value: (), obligations: obligations }) + self.sub(a_is_expected, trace, &a, &b).map(|ok| ok.unit()) }) } @@ -955,9 +957,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let (ty::EquatePredicate(a, b), skol_map) = self.skolemize_late_bound_regions(predicate, snapshot); let origin = TypeOrigin::EquatePredicate(span); - let InferOk { obligations, .. } = mk_eqty(self, false, origin, a, b)?; - self.leak_check(&skol_map, snapshot) - .map(|_| InferOk { value: (), obligations: obligations }) + let eqty_ok = mk_eqty(self, false, origin, a, b)?; + self.leak_check(&skol_map, snapshot).map(|_| eqty_ok.unit()) }) } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 68173bc9ea513..46323cdf77ee4 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -527,7 +527,7 @@ 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(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); Ok(Some(Vec::new())) }, diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 85fe457c75e8c..71eb0a227b4ed 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -233,7 +233,7 @@ fn project_and_unify_type<'cx,'tcx>( let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span); match infer::mk_eqty(infcx, true, origin, normalized_ty, obligation.predicate.ty) { Ok(InferOk { obligations: inferred_obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(inferred_obligations.is_empty()); Ok(Some(obligations)) }, @@ -283,7 +283,7 @@ fn consider_unification_despite_ambiguity<'cx,'tcx>(selcx: &mut SelectionContext let obligation_ty = obligation.predicate.ty; match infer::mk_eqty(infcx, true, origin, obligation_ty, ret_type) { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); } Err(_) => { /* ignore errors */ } @@ -837,7 +837,7 @@ fn assemble_candidates_from_predicates<'cx,'tcx,I>( origin, data_poly_trait_ref, obligation_poly_trait_ref) - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) .is_ok() }); @@ -1093,7 +1093,7 @@ fn confirm_param_env_candidate<'cx,'tcx>( obligation.predicate.trait_ref.clone(), projection.projection_ty.trait_ref.clone()) { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); } Err(e) => { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 013c75bf8d2bb..d18f8e9dc53d0 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -485,7 +485,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // does this code ever run? match self.infcx.equality_predicate(obligation.cause.span, p) { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); EvaluatedToOk }, @@ -1190,7 +1190,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { trait_bound.clone(), ty::Binder(skol_trait_ref.clone())) { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); } Err(_) => { return false; } @@ -2505,7 +2505,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { origin, expected_trait_ref.clone(), obligation_trait_ref.clone()) - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e)) } @@ -2541,7 +2541,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self.infcx.sub_types(false, origin, new_trait, target) .map_err(|_| Unimplemented)?; - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); // Register one obligation for 'a: 'b. @@ -2608,7 +2608,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self.infcx.sub_types(false, origin, a, b) .map_err(|_| Unimplemented)?; - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); } @@ -2668,7 +2668,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self.infcx.sub_types(false, origin, new_struct, target) .map_err(|_| Unimplemented)?; - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); // Construct the nested Field: Unsize> predicate. @@ -2764,7 +2764,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("match_impl: failed eq_trait_refs due to `{}`", e); () })?; - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); if let Err(e) = self.infcx.leak_check(&skol_map, snapshot) { @@ -2832,7 +2832,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { origin, poly_trait_ref, obligation.predicate.to_poly_trait_ref()) - // FIXME(#????) propagate obligations + // 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 00569d50cbb9c..ce0d42203b987 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -375,7 +375,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) { match self.sub(&t1, &t2) { Ok(InferOk { obligations, .. }) => { - // FIXME once obligations are being propagated, assert the right thing. + // FIXME(#32730) once obligations are being propagated, assert the right thing. assert!(obligations.is_empty()); } Err(ref e) => { @@ -399,7 +399,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) { match self.lub(&t1, &t2) { Ok(InferOk { obligations, value: t }) => { - // FIXME once obligations are being propagated, assert the right thing. + // FIXME(#32730) once obligations are being propagated, assert the right thing. assert!(obligations.is_empty()); self.assert_eq(t, t_lub); @@ -418,7 +418,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { panic!("unexpected error computing LUB: {:?}", e) } Ok(InferOk { obligations, value: t }) => { - // FIXME once obligations are being propagated, assert the right thing. + // FIXME(#32730) once obligations are being propagated, assert the right thing. assert!(obligations.is_empty()); self.assert_eq(t, t_glb); diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 3f85a3e1d4618..ce8ede7f4b959 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -338,7 +338,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { { infer::mk_subty(self.infcx, false, infer::TypeOrigin::Misc(span), sup, sub) - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) } @@ -347,7 +347,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { { infer::mk_eqty(self.infcx, false, infer::TypeOrigin::Misc(span), a, b) - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index dcbfa2bb79b6c..e359329ebcf7f 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -534,7 +534,7 @@ 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(|InferOk { obligations, .. }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); arm_ty }) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index a4d8e2ae04938..a9849e93578c8 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -119,14 +119,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { if self.use_lub { infcx.lub(false, trace, &a, &b) .map(|InferOk { value, obligations }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); value }) } else { infcx.sub(false, trace, &a, &b) .map(|InferOk { value, obligations }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); value }) @@ -668,7 +668,7 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>, // The signature must always match. let fty = fcx.infcx().lub(true, trace.clone(), a_fty, b_fty) .map(|InferOk { value, obligations }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); value })?; @@ -678,7 +678,7 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>, let substs = fcx.infcx().commit_if_ok(|_| { fcx.infcx().lub(true, trace.clone(), a_substs, b_substs) .map(|InferOk { value, obligations }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); value }) @@ -746,7 +746,7 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>, return fcx.infcx().commit_if_ok(|_| { fcx.infcx().lub(true, trace.clone(), &prev_ty, &new_ty) .map(|InferOk { value, obligations }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); value }) @@ -763,7 +763,7 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>, fcx.infcx().commit_if_ok(|_| { fcx.infcx().lub(true, trace, &prev_ty, &new_ty) .map(|InferOk { value, obligations }| { - // FIXME(#????) propagate 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 5f49b0335d929..3c12ab8d59840 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -476,7 +476,7 @@ pub fn compare_const_impl<'tcx>(tcx: &TyCtxt<'tcx>, match err { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()) } Err(terr) => { diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 75f6b11a22931..bc2ef9aafee59 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -23,7 +23,7 @@ pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, let origin = TypeOrigin::Misc(sp); match fcx.infcx().sub_types(false, origin, actual, expected) { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); }, Err(e) => { @@ -37,7 +37,7 @@ pub fn eqtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, let origin = TypeOrigin::Misc(sp); match fcx.infcx().eq_types(false, origin, actual, expected) { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); }, Err(e) => { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 44dbcd051e201..7e487c1f717f7 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1134,7 +1134,7 @@ 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(#????) propagate obligations + // FIXME(#32730) propagate obligations .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 625e59c6e3c63..da93180c600dd 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1628,7 +1628,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sup: Ty<'tcx>) -> Result<(), TypeError<'tcx>> { infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup) - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) } @@ -1639,7 +1639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sup: Ty<'tcx>) -> Result<(), TypeError<'tcx>> { infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup) - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations .map(|InferOk { obligations, .. }| assert!(obligations.is_empty())) } @@ -1920,7 +1920,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { TypeOrigin::Misc(default.origin_span), ty, default.ty) { Ok(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()) }, Err(_) => { @@ -2015,7 +2015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match infer::mk_eqty(self.infcx(), false, TypeOrigin::Misc(default.origin_span), ty, default.ty) { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()), Err(_) => { result = Some(default); @@ -2784,7 +2784,7 @@ fn expected_types_for_fn_args<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // FIXME(#15760) can't use try! here, FromError doesn't default // to identity so the resulting type is not constrained. match ures { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()), Err(e) => return Err(e), } @@ -2915,7 +2915,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let trace = TypeTrace::types(origin, true, then_ty, else_ty); fcx.infcx().lub(true, trace, &then_ty, &else_ty) .map(|InferOk { value, obligations }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); value }) @@ -2927,7 +2927,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, (origin, unit, then_ty, fcx.infcx().eq_types(true, origin, unit, then_ty) .map(|InferOk { obligations, .. }| { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); unit })) diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 515a898699e0c..dae14c3329689 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1847,7 +1847,7 @@ 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(InferOk { obligations, .. }) => { - // FIXME(#????) propagate obligations + // FIXME(#32730) propagate obligations assert!(obligations.is_empty()); Ok(outlives.1) }