1
Fork 0

Plumb obligations through librustc/infer

This commit is contained in:
Masood Malekghassemi 2016-03-29 20:06:42 -07:00
parent 0c07a3cc59
commit dcdf3d62c1
18 changed files with 274 additions and 107 deletions

View file

@ -37,7 +37,7 @@ use super::equate::Equate;
use super::glb::Glb; use super::glb::Glb;
use super::lub::Lub; use super::lub::Lub;
use super::sub::Sub; use super::sub::Sub;
use super::{InferCtxt}; use super::InferCtxt;
use super::{MiscVariable, TypeTrace}; use super::{MiscVariable, TypeTrace};
use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf}; use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf};
@ -46,6 +46,7 @@ use ty::{self, Ty, TyCtxt};
use ty::error::TypeError; use ty::error::TypeError;
use ty::fold::{TypeFolder, TypeFoldable}; use ty::fold::{TypeFolder, TypeFoldable};
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
use syntax::ast; use syntax::ast;
use syntax::codemap::Span; use syntax::codemap::Span;
@ -56,6 +57,7 @@ pub struct CombineFields<'a, 'tcx: 'a> {
pub a_is_expected: bool, pub a_is_expected: bool,
pub trace: TypeTrace<'tcx>, pub trace: TypeTrace<'tcx>,
pub cause: Option<ty::relate::Cause>, pub cause: Option<ty::relate::Cause>,
pub obligations: PredicateObligations<'tcx>,
} }
pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>, pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,

View file

@ -16,6 +16,7 @@ use super::type_variable::{EqTo};
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::TyVar; use ty::TyVar;
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
/// Ensures `a` is made equal to `b`. Returns `a` on success. /// Ensures `a` is made equal to `b`. Returns `a` on success.
pub struct Equate<'a, 'tcx: 'a> { 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> { pub fn new(fields: CombineFields<'a, 'tcx>) -> Equate<'a, 'tcx> {
Equate { fields: fields } Equate { fields: fields }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
} }
impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> { impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {

View file

@ -16,6 +16,7 @@ use super::Subtype;
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
/// "Greatest lower bound" (common subtype) /// "Greatest lower bound" (common subtype)
pub struct Glb<'a, 'tcx: 'a> { 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> { pub fn new(fields: CombineFields<'a, 'tcx>) -> Glb<'a, 'tcx> {
Glb { fields: fields } Glb { fields: fields }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
} }
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> { impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {

View file

@ -16,6 +16,7 @@ use super::Subtype;
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
/// "Least upper bound" (common supertype) /// "Least upper bound" (common supertype)
pub struct Lub<'a, 'tcx: 'a> { 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> { pub fn new(fields: CombineFields<'a, 'tcx>) -> Lub<'a, 'tcx> {
Lub { fields: fields } Lub { fields: fields }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
} }
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> { impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {

View file

@ -27,13 +27,13 @@ use middle::region::CodeExtent;
use ty::subst; use ty::subst;
use ty::subst::Substs; use ty::subst::Substs;
use ty::subst::Subst; use ty::subst::Subst;
use traits::{self, ProjectionMode};
use ty::adjustment; use ty::adjustment;
use ty::{TyVid, IntVid, FloatVid}; use ty::{TyVid, IntVid, FloatVid};
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
use ty::fold::{TypeFolder, TypeFoldable}; use ty::fold::{TypeFolder, TypeFoldable};
use ty::relate::{Relate, RelateResult, TypeRelation}; use ty::relate::{Relate, RelateResult, TypeRelation};
use traits::{self, PredicateObligations, ProjectionMode};
use rustc_data_structures::unify::{self, UnificationTable}; use rustc_data_structures::unify::{self, UnificationTable};
use std::cell::{RefCell, Ref}; use std::cell::{RefCell, Ref};
use std::fmt; use std::fmt;
@ -63,6 +63,12 @@ pub mod sub;
pub mod type_variable; pub mod type_variable;
pub mod unify_key; pub mod unify_key;
pub struct InferOk<'tcx, T> {
pub value: T,
pub obligations: PredicateObligations<'tcx>,
}
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
pub type Bound<T> = Option<T>; pub type Bound<T> = Option<T>;
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result" pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
pub type FixupResult<T> = Result<T, FixupError>; // "fixup result" pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
@ -391,16 +397,15 @@ pub fn mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
origin: TypeOrigin, origin: TypeOrigin,
a: Ty<'tcx>, a: Ty<'tcx>,
b: Ty<'tcx>) b: Ty<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("mk_subty({:?} <: {:?})", a, b); debug!("mk_subty({:?} <: {:?})", a, b);
cx.sub_types(a_is_expected, origin, a, b) cx.sub_types(a_is_expected, origin, a, b)
} }
pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
a: Ty<'tcx>, -> UnitResult<'tcx>
b: Ty<'tcx>) {
-> UnitResult<'tcx> {
debug!("can_mk_subty({:?} <: {:?})", a, b); debug!("can_mk_subty({:?} <: {:?})", a, b);
cx.probe(|_| { cx.probe(|_| {
let trace = TypeTrace { 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>) 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) cx.can_equate(&a, &b)
} }
@ -432,7 +437,7 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
origin: TypeOrigin, origin: TypeOrigin,
a: Ty<'tcx>, a: Ty<'tcx>,
b: Ty<'tcx>) b: Ty<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("mk_eqty({:?} <: {:?})", a, b); debug!("mk_eqty({:?} <: {:?})", a, b);
cx.eq_types(a_is_expected, origin, 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, origin: TypeOrigin,
a: ty::TraitRef<'tcx>, a: ty::TraitRef<'tcx>,
b: ty::TraitRef<'tcx>) b: ty::TraitRef<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("mk_eq_trait_refs({:?} = {:?})", a, b); debug!("mk_eq_trait_refs({:?} = {:?})", a, b);
cx.eq_trait_refs(a_is_expected, origin, 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, origin: TypeOrigin,
a: ty::PolyTraitRef<'tcx>, a: ty::PolyTraitRef<'tcx>,
b: ty::PolyTraitRef<'tcx>) b: ty::PolyTraitRef<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("mk_sub_poly_trait_refs({:?} <: {:?})", a, b); debug!("mk_sub_poly_trait_refs({:?} <: {:?})", a, b);
cx.sub_poly_trait_refs(a_is_expected, origin, 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, origin: TypeOrigin,
a: &ty::ImplHeader<'tcx>, a: &ty::ImplHeader<'tcx>,
b: &ty::ImplHeader<'tcx>) b: &ty::ImplHeader<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("mk_eq_impl_header({:?} = {:?})", a, b); debug!("mk_eq_impl_header({:?} = {:?})", a, b);
match (a.trait_ref, b.trait_ref) { 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>) fn combine_fields(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
-> CombineFields<'a, 'tcx> { -> CombineFields<'a, 'tcx>
CombineFields {infcx: self, {
a_is_expected: a_is_expected, CombineFields {
trace: trace, infcx: self,
cause: None} a_is_expected: a_is_expected,
trace: trace,
cause: None,
obligations: PredicateObligations::new(),
}
} }
pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-> RelateResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'a, 'tcx> where T: Relate<'a, 'tcx>
{ {
self.combine_fields(a_is_expected, trace).equate().relate(a, b) let mut equate = self.combine_fields(a_is_expected, trace).equate();
let result = equate.relate(a, b);
result.map(|t| InferOk { value: t, obligations: equate.obligations() })
} }
pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-> RelateResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'a, 'tcx> where T: Relate<'a, 'tcx>
{ {
self.combine_fields(a_is_expected, trace).sub().relate(a, b) let mut sub = self.combine_fields(a_is_expected, trace).sub();
let result = sub.relate(a, b);
result.map(|t| InferOk { value: t, obligations: sub.obligations() })
} }
pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-> RelateResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'a, 'tcx> where T: Relate<'a, 'tcx>
{ {
self.combine_fields(a_is_expected, trace).lub().relate(a, b) let mut lub = self.combine_fields(a_is_expected, trace).lub();
let result = lub.relate(a, b);
result.map(|t| InferOk { value: t, obligations: lub.obligations() })
} }
pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
-> RelateResult<'tcx, T> -> InferResult<'tcx, T>
where T: Relate<'a, 'tcx> 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 { fn start_snapshot(&self) -> CombinedSnapshot {
@ -829,12 +846,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
origin: TypeOrigin, origin: TypeOrigin,
a: Ty<'tcx>, a: Ty<'tcx>,
b: Ty<'tcx>) b: Ty<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("sub_types({:?} <: {:?})", a, b); debug!("sub_types({:?} <: {:?})", a, b);
self.commit_if_ok(|_| { self.commit_if_ok(|_| {
let trace = TypeTrace::types(origin, a_is_expected, a, b); 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, origin: TypeOrigin,
a: Ty<'tcx>, a: Ty<'tcx>,
b: Ty<'tcx>) b: Ty<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
self.commit_if_ok(|_| { self.commit_if_ok(|_| {
let trace = TypeTrace::types(origin, a_is_expected, a, b); 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, origin: TypeOrigin,
a: ty::TraitRef<'tcx>, a: ty::TraitRef<'tcx>,
b: ty::TraitRef<'tcx>) b: ty::TraitRef<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("eq_trait_refs({:?} <: {:?})", debug!("eq_trait_refs({:?} <: {:?})",
a, a,
@ -866,7 +885,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
origin: origin, origin: origin,
values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone())) 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, origin: TypeOrigin,
a: ty::PolyTraitRef<'tcx>, a: ty::PolyTraitRef<'tcx>,
b: ty::PolyTraitRef<'tcx>) b: ty::PolyTraitRef<'tcx>)
-> UnitResult<'tcx> -> InferResult<'tcx, ()>
{ {
debug!("sub_poly_trait_refs({:?} <: {:?})", debug!("sub_poly_trait_refs({:?} <: {:?})",
a, a,
@ -885,7 +905,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
origin: origin, origin: origin,
values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone())) 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, pub fn equality_predicate(&self,
span: Span, span: Span,
predicate: &ty::PolyEquatePredicate<'tcx>) predicate: &ty::PolyEquatePredicate<'tcx>)
-> UnitResult<'tcx> { -> InferResult<'tcx, ()>
{
self.commit_if_ok(|snapshot| { self.commit_if_ok(|snapshot| {
let (ty::EquatePredicate(a, b), skol_map) = let (ty::EquatePredicate(a, b), skol_map) =
self.skolemize_late_bound_regions(predicate, snapshot); self.skolemize_late_bound_regions(predicate, snapshot);
let origin = TypeOrigin::EquatePredicate(span); 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) self.leak_check(&skol_map, snapshot)
.map(|_| InferOk { value: (), obligations: obligations })
}) })
} }
pub fn region_outlives_predicate(&self, pub fn region_outlives_predicate(&self,
span: Span, span: Span,
predicate: &ty::PolyRegionOutlivesPredicate) predicate: &ty::PolyRegionOutlivesPredicate)
-> UnitResult<'tcx> { -> UnitResult<'tcx>
{
self.commit_if_ok(|snapshot| { self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), skol_map) = let (ty::OutlivesPredicate(r_a, r_b), skol_map) =
self.skolemize_late_bound_regions(predicate, snapshot); self.skolemize_late_bound_regions(predicate, snapshot);

View file

@ -16,6 +16,7 @@ use super::type_variable::{SubtypeOf, SupertypeOf};
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
use ty::TyVar; use ty::TyVar;
use ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
use traits::PredicateObligations;
use std::mem; use std::mem;
/// Ensures `a` is made a subtype of `b`. Returns `a` on success. /// 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> { pub fn new(f: CombineFields<'a, 'tcx>) -> Sub<'a, 'tcx> {
Sub { fields: f } Sub { fields: f }
} }
pub fn obligations(self) -> PredicateObligations<'tcx> {
self.fields.obligations
}
} }
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> { impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use dep_graph::DepGraph; use dep_graph::DepGraph;
use infer::InferCtxt; use infer::{InferCtxt, InferOk};
use ty::{self, Ty, TyCtxt, TypeFoldable, ToPolyTraitRef}; use ty::{self, Ty, TyCtxt, TypeFoldable, ToPolyTraitRef};
use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error}; use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error};
use std::iter; use std::iter;
@ -526,7 +526,11 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
ty::Predicate::Equate(ref binder) => { ty::Predicate::Equate(ref binder) => {
match selcx.infcx().equality_predicate(obligation.cause.span, 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)), Err(_) => Err(CodeSelectionError(Unimplemented)),
} }
} }

View file

@ -24,7 +24,7 @@ use super::VtableImplData;
use super::util; use super::util;
use middle::def_id::DefId; use middle::def_id::DefId;
use infer::{self, TypeOrigin}; use infer::{self, InferOk, TypeOrigin};
use ty::subst::Subst; use ty::subst::Subst;
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder}; use ty::fold::{TypeFoldable, TypeFolder};
@ -232,7 +232,11 @@ fn project_and_unify_type<'cx,'tcx>(
let infcx = selcx.infcx(); let infcx = selcx.infcx();
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span); let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
match infer::mk_eqty(infcx, true, origin, normalized_ty, obligation.predicate.ty) { 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 }), 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 origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
let obligation_ty = obligation.predicate.ty; let obligation_ty = obligation.predicate.ty;
match infer::mk_eqty(infcx, true, origin, obligation_ty, ret_type) { 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 */ } Err(_) => { /* ignore errors */ }
} }
} }
@ -829,7 +836,10 @@ fn assemble_candidates_from_predicates<'cx,'tcx,I>(
infcx.sub_poly_trait_refs(false, infcx.sub_poly_trait_refs(false,
origin, origin,
data_poly_trait_ref, 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={:?} \ debug!("assemble_candidates_from_predicates: candidate={:?} \
@ -1082,7 +1092,10 @@ fn confirm_param_env_candidate<'cx,'tcx>(
origin, origin,
obligation.predicate.trait_ref.clone(), obligation.predicate.trait_ref.clone(),
projection.projection_ty.trait_ref.clone()) { projection.projection_ty.trait_ref.clone()) {
Ok(()) => { } Ok(InferOk { obligations, .. }) => {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
}
Err(e) => { Err(e) => {
selcx.tcx().sess.span_bug( selcx.tcx().sess.span_bug(
obligation.cause.span, obligation.cause.span,

View file

@ -38,7 +38,7 @@ use super::util;
use middle::def_id::DefId; use middle::def_id::DefId;
use infer; use infer;
use infer::{InferCtxt, TypeFreshener, TypeOrigin}; use infer::{InferCtxt, InferOk, TypeFreshener, TypeOrigin};
use ty::subst::{Subst, Substs, TypeSpace}; use ty::subst::{Subst, Substs, TypeSpace};
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use traits; use traits;
@ -484,7 +484,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Predicate::Equate(ref p) => { ty::Predicate::Equate(ref p) => {
// does this code ever run? // does this code ever run?
match self.infcx.equality_predicate(obligation.cause.span, p) { match self.infcx.equality_predicate(obligation.cause.span, p) {
Ok(()) => EvaluatedToOk, Ok(InferOk { obligations, .. }) => {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
EvaluatedToOk
},
Err(_) => EvaluatedToErr Err(_) => EvaluatedToErr
} }
} }
@ -1185,7 +1189,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
origin, origin,
trait_bound.clone(), trait_bound.clone(),
ty::Binder(skol_trait_ref.clone())) { ty::Binder(skol_trait_ref.clone())) {
Ok(()) => { } Ok(InferOk { obligations, .. }) => {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
}
Err(_) => { return false; } Err(_) => { return false; }
} }
@ -2494,13 +2501,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let origin = TypeOrigin::RelateOutputImplTypes(obligation_cause.span); let origin = TypeOrigin::RelateOutputImplTypes(obligation_cause.span);
let obligation_trait_ref = obligation_trait_ref.clone(); let obligation_trait_ref = obligation_trait_ref.clone();
match self.infcx.sub_poly_trait_refs(false, self.infcx.sub_poly_trait_refs(false,
origin, origin,
expected_trait_ref.clone(), expected_trait_ref.clone(),
obligation_trait_ref.clone()) { obligation_trait_ref.clone())
Ok(()) => Ok(()), // FIXME(#????) propagate obligations
Err(e) => Err(OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e)) .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, 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 new_trait = tcx.mk_trait(data_a.principal.clone(), bounds);
let origin = TypeOrigin::Misc(obligation.cause.span); let origin = TypeOrigin::Misc(obligation.cause.span);
if self.infcx.sub_types(false, origin, new_trait, target).is_err() { let InferOk { obligations, .. } =
return Err(Unimplemented); 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. // Register one obligation for 'a: 'b.
let cause = ObligationCause::new(obligation.cause.span, let cause = ObligationCause::new(obligation.cause.span,
@ -2596,9 +2605,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// [T; n] -> [T]. // [T; n] -> [T].
(&ty::TyArray(a, _), &ty::TySlice(b)) => { (&ty::TyArray(a, _), &ty::TySlice(b)) => {
let origin = TypeOrigin::Misc(obligation.cause.span); let origin = TypeOrigin::Misc(obligation.cause.span);
if self.infcx.sub_types(false, origin, a, b).is_err() { let InferOk { obligations, .. } =
return Err(Unimplemented); self.infcx.sub_types(false, origin, a, b)
} .map_err(|_| Unimplemented)?;
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
} }
// Struct<T> -> Struct<U>. // Struct<T> -> Struct<U>.
@ -2654,9 +2665,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
let new_struct = tcx.mk_struct(def, tcx.mk_substs(new_substs)); let new_struct = tcx.mk_struct(def, tcx.mk_substs(new_substs));
let origin = TypeOrigin::Misc(obligation.cause.span); let origin = TypeOrigin::Misc(obligation.cause.span);
if self.infcx.sub_types(false, origin, new_struct, target).is_err() { let InferOk { obligations, .. } =
return Err(Unimplemented); self.infcx.sub_types(false, origin, new_struct, target)
} .map_err(|_| Unimplemented)?;
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
// Construct the nested Field<T>: Unsize<Field<U>> predicate. // Construct the nested Field<T>: Unsize<Field<U>> predicate.
nested.push(util::predicate_for_trait_def(tcx, nested.push(util::predicate_for_trait_def(tcx,
@ -2742,13 +2755,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
skol_obligation_trait_ref); skol_obligation_trait_ref);
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span); let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
if let Err(e) = self.infcx.eq_trait_refs(false, let InferOk { obligations, .. } =
origin, self.infcx.eq_trait_refs(false,
impl_trait_ref.value.clone(), origin,
skol_obligation_trait_ref) { impl_trait_ref.value.clone(),
debug!("match_impl: failed eq_trait_refs due to `{}`", e); skol_obligation_trait_ref)
return Err(()); .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) { if let Err(e) = self.infcx.leak_check(&skol_map, snapshot) {
debug!("match_impl: failed leak check due to `{}`", e); debug!("match_impl: failed leak check due to `{}`", e);
@ -2811,13 +2828,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
poly_trait_ref); poly_trait_ref);
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span); let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
match self.infcx.sub_poly_trait_refs(false, self.infcx.sub_poly_trait_refs(false,
origin, origin,
poly_trait_ref, poly_trait_ref,
obligation.predicate.to_poly_trait_ref()) { obligation.predicate.to_poly_trait_ref())
Ok(()) => Ok(()), // FIXME(#????) propagate obligations
Err(_) => Err(()), .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
} .map_err(|_| ())
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////

View file

@ -24,8 +24,8 @@ use rustc::ty::subst;
use rustc::ty::subst::Subst; use rustc::ty::subst::Subst;
use rustc::traits::ProjectionMode; use rustc::traits::ProjectionMode;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::relate::{TypeRelation, RelateResult}; use rustc::ty::relate::TypeRelation;
use rustc::infer::{self, TypeOrigin}; use rustc::infer::{self, InferOk, InferResult, TypeOrigin};
use rustc_metadata::cstore::CStore; use rustc_metadata::cstore::CStore;
use rustc::front::map as hir_map; use rustc::front::map as hir_map;
use rustc::session::{self, config}; use rustc::session::{self, config};
@ -355,17 +355,17 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
infer::TypeTrace::dummy(self.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(); let trace = self.dummy_type_trace();
self.infcx.sub(true, trace, t1, t2) 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(); let trace = self.dummy_type_trace();
self.infcx.lub(true, trace, t1, t2) 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(); let trace = self.dummy_type_trace();
self.infcx.glb(true, trace, t1, t2) self.infcx.glb(true, trace, t1, t2)
} }
@ -374,7 +374,10 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
/// region checks). /// region checks).
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) { pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
match self.sub(&t1, &t2) { 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) => { Err(ref e) => {
panic!("unexpected error computing sub({:?},{:?}): {}", t1, t2, 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` /// Checks that `LUB(t1,t2) == t_lub`
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) { pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
match self.lub(&t1, &t2) { 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); self.assert_eq(t, t_lub);
} }
Err(ref e) => { Err(ref e) => {
@ -411,7 +417,10 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
Err(e) => { Err(e) => {
panic!("unexpected error computing LUB: {:?}", 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); self.assert_eq(t, t_glb);
// sanity check for good measure: // sanity check for good measure:

View file

@ -12,7 +12,7 @@
#![allow(unreachable_code)] #![allow(unreachable_code)]
use rustc::dep_graph::DepNode; use rustc::dep_graph::DepNode;
use rustc::infer::{self, InferCtxt}; use rustc::infer::{self, InferCtxt, InferOk};
use rustc::traits::{self, ProjectionMode}; use rustc::traits::{self, ProjectionMode};
use rustc::ty::fold::TypeFoldable; use rustc::ty::fold::TypeFoldable;
use rustc::ty::{self, Ty, TyCtxt}; 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), infer::mk_subty(self.infcx, false, infer::TypeOrigin::Misc(span),
sup, sub) sup, sub)
// FIXME(#????) propagate obligations
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
} }
fn mk_eqty(&self, span: Span, a: Ty<'tcx>, b: Ty<'tcx>) 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), infer::mk_eqty(self.infcx, false, infer::TypeOrigin::Misc(span),
a, b) a, b)
// FIXME(#????) propagate obligations
.map(|InferOk { obligations, .. }| assert!(obligations.is_empty()))
} }
fn tcx(&self) -> &'a TyCtxt<'tcx> { fn tcx(&self) -> &'a TyCtxt<'tcx> {

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use middle::def::{self, Def}; 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::{PatIdMap, pat_id_map, pat_is_binding};
use middle::pat_util::pat_is_resolved_const; use middle::pat_util::pat_is_resolved_const;
use rustc::ty::subst::Substs; 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 { 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 { } else if i == 0 {
// Special-case the first arm, as it has no "previous expressions". // Special-case the first arm, as it has no "previous expressions".
coercion::try(fcx, &arm.body, coerce_first) coercion::try(fcx, &arm.body, coerce_first)

View file

@ -62,7 +62,7 @@
use check::{autoderef, FnCtxt, UnresolvedTypeAction}; 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::{self, ObligationCause};
use rustc::traits::{predicate_for_trait_def, report_selection_error}; use rustc::traits::{predicate_for_trait_def, report_selection_error};
use rustc::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef}; 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); let trace = TypeTrace::types(self.origin, false, a, b);
if self.use_lub { if self.use_lub {
infcx.lub(false, trace, &a, &b) infcx.lub(false, trace, &a, &b)
.map(|InferOk { value, obligations }| {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
value
})
} else { } else {
infcx.sub(false, trace, &a, &b) 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(a_def_id, a_substs, a_fty),
&ty::TyFnDef(b_def_id, b_substs, b_fty)) => { &ty::TyFnDef(b_def_id, b_substs, b_fty)) => {
// The signature must always match. // 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 { if a_def_id == b_def_id {
// Same function, maybe the parameters match. // Same function, maybe the parameters match.
let substs = fcx.infcx().commit_if_ok(|_| { let substs = fcx.infcx().commit_if_ok(|_| {
fcx.infcx().lub(true, trace.clone(), a_substs, b_substs) 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)); }).map(|s| fcx.tcx().mk_substs(s));
if let Ok(substs) = substs { 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 { if !noop {
return fcx.infcx().commit_if_ok(|_| { return fcx.infcx().commit_if_ok(|_| {
fcx.infcx().lub(true, trace.clone(), &prev_ty, &new_ty) 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 { } else {
fcx.infcx().commit_if_ok(|_| { fcx.infcx().commit_if_ok(|_| {
fcx.infcx().lub(true, trace, &prev_ty, &new_ty) fcx.infcx().lub(true, trace, &prev_ty, &new_ty)
.map(|InferOk { value, obligations }| {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
value
})
}) })
} }
} }

View file

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
use middle::free_region::FreeRegionMap; use middle::free_region::FreeRegionMap;
use rustc::infer::{self, TypeOrigin}; use rustc::infer::{self, InferOk, TypeOrigin};
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use rustc::traits::{self, ProjectionMode}; use rustc::traits::{self, ProjectionMode};
use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace}; use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace};
@ -475,7 +475,10 @@ pub fn compare_const_impl<'tcx>(tcx: &TyCtxt<'tcx>,
}); });
match err { match err {
Ok(()) => { } Ok(InferOk { obligations, .. }) => {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty())
}
Err(terr) => { Err(terr) => {
debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}", debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
impl_ty, impl_ty,

View file

@ -11,7 +11,7 @@
use check::{coercion, FnCtxt}; use check::{coercion, FnCtxt};
use rustc::ty::Ty; use rustc::ty::Ty;
use rustc::infer::TypeOrigin; use rustc::infer::{InferOk, TypeOrigin};
use syntax::codemap::Span; use syntax::codemap::Span;
use rustc_front::hir; use rustc_front::hir;
@ -21,16 +21,28 @@ use rustc_front::hir;
pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
expected: Ty<'tcx>, actual: Ty<'tcx>) { expected: Ty<'tcx>, actual: Ty<'tcx>) {
let origin = TypeOrigin::Misc(sp); let origin = TypeOrigin::Misc(sp);
if let Err(e) = fcx.infcx().sub_types(false, origin, actual, expected) { match fcx.infcx().sub_types(false, origin, actual, expected) {
fcx.infcx().report_mismatched_types(origin, expected, actual, e); 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, pub fn eqtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
expected: Ty<'tcx>, actual: Ty<'tcx>) { expected: Ty<'tcx>, actual: Ty<'tcx>) {
let origin = TypeOrigin::Misc(sp); let origin = TypeOrigin::Misc(sp);
if let Err(e) = fcx.infcx().eq_types(false, origin, actual, expected) { match fcx.infcx().eq_types(false, origin, actual, expected) {
fcx.infcx().report_mismatched_types(origin, expected, actual, e); Ok(InferOk { obligations, .. }) => {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty());
},
Err(e) => {
fcx.infcx().report_mismatched_types(origin, expected, actual, e);
}
} }
} }

View file

@ -20,8 +20,7 @@ use rustc::ty::subst;
use rustc::ty::subst::Subst; use rustc::ty::subst::Subst;
use rustc::traits; use rustc::traits;
use rustc::ty::{self, NoPreference, Ty, TyCtxt, ToPolyTraitRef, TraitRef, TypeFoldable}; use rustc::ty::{self, NoPreference, Ty, TyCtxt, ToPolyTraitRef, TraitRef, TypeFoldable};
use rustc::infer; use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin};
use rustc::infer::{InferCtxt, TypeOrigin};
use syntax::ast; use syntax::ast;
use syntax::codemap::{Span, DUMMY_SP}; use syntax::codemap::{Span, DUMMY_SP};
use rustc_front::hir; 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> { 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) 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 { fn has_applicable_self(&self, item: &ty::ImplOrTraitItem) -> bool {

View file

@ -88,8 +88,7 @@ use middle::astconv_util::prohibit_type_params;
use middle::cstore::LOCAL_CRATE; use middle::cstore::LOCAL_CRATE;
use middle::def::{self, Def}; use middle::def::{self, Def};
use middle::def_id::DefId; use middle::def_id::DefId;
use rustc::infer; use rustc::infer::{self, InferOk, TypeOrigin, TypeTrace, type_variable};
use rustc::infer::{TypeOrigin, TypeTrace, type_variable};
use middle::pat_util::{self, pat_id_map}; use middle::pat_util::{self, pat_id_map};
use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace}; use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
use rustc::traits::{self, report_fulfillment_errors, ProjectionMode}; use rustc::traits::{self, report_fulfillment_errors, ProjectionMode};
@ -1629,6 +1628,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sup: Ty<'tcx>) sup: Ty<'tcx>)
-> Result<(), TypeError<'tcx>> { -> Result<(), TypeError<'tcx>> {
infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup) 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, pub fn mk_eqty(&self,
@ -1638,6 +1639,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sup: Ty<'tcx>) sup: Ty<'tcx>)
-> Result<(), TypeError<'tcx>> { -> Result<(), TypeError<'tcx>> {
infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup) 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, pub fn mk_subr(&self,
@ -1916,7 +1919,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match infer::mk_eqty(self.infcx(), false, match infer::mk_eqty(self.infcx(), false,
TypeOrigin::Misc(default.origin_span), TypeOrigin::Misc(default.origin_span),
ty, default.ty) { ty, default.ty) {
Ok(()) => {} Ok(InferOk { obligations, .. }) => {
// FIXME(#????) propagate obligations
assert!(obligations.is_empty())
},
Err(_) => { Err(_) => {
conflicts.push((*ty, default)); conflicts.push((*ty, default));
} }
@ -2009,7 +2015,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match infer::mk_eqty(self.infcx(), false, match infer::mk_eqty(self.infcx(), false,
TypeOrigin::Misc(default.origin_span), TypeOrigin::Misc(default.origin_span),
ty, default.ty) { ty, default.ty) {
Ok(()) => {} // FIXME(#????) propagate obligations
Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
Err(_) => { Err(_) => {
result = Some(default); 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); let ures = fcx.infcx().sub_types(false, origin, formal_ret_ty, ret_ty);
// FIXME(#15760) can't use try! here, FromError doesn't default // FIXME(#15760) can't use try! here, FromError doesn't default
// to identity so the resulting type is not constrained. // to identity so the resulting type is not constrained.
if let Err(e) = ures { match ures {
return Err(e); // FIXME(#????) propagate obligations
Ok(InferOk { obligations, .. }) => assert!(obligations.is_empty()),
Err(e) => return Err(e),
} }
// Record all the argument types, with the substitutions // 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(|_| { fcx.infcx().commit_if_ok(|_| {
let trace = TypeTrace::types(origin, true, then_ty, else_ty); let trace = TypeTrace::types(origin, true, then_ty, else_ty);
fcx.infcx().lub(true, trace, &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) (origin, then_ty, else_ty, result)
} else { } else {
let origin = TypeOrigin::IfExpressionWithNoElse(sp); let origin = TypeOrigin::IfExpressionWithNoElse(sp);
(origin, unit, then_ty, (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 { let if_ty = match result {

View file

@ -92,7 +92,7 @@ use middle::region::{self, CodeExtent};
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::traits; use rustc::traits;
use rustc::ty::{self, Ty, TyCtxt, MethodCall, TypeFoldable}; 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 middle::pat_util;
use rustc::ty::adjustment; use rustc::ty::adjustment;
use rustc::ty::wf::ImpliedBound; 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 // check whether this predicate applies to our current projection
match infer::mk_eqty(infcx, false, TypeOrigin::Misc(span), ty, outlives.0) { 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(()) } Err(_) => { Err(()) }
} }
}); });