Plumb obligations through librustc/infer
This commit is contained in:
parent
0c07a3cc59
commit
dcdf3d62c1
18 changed files with 274 additions and 107 deletions
|
@ -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>,
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(()) }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue