Refactor s.t. TypeRelation implementors don't escape InferCtxt
This commit is contained in:
parent
f10a12c49f
commit
8cd0f0cc3a
@ -407,7 +407,7 @@ pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
|
|||||||
origin: TypeOrigin::Misc(codemap::DUMMY_SP),
|
origin: TypeOrigin::Misc(codemap::DUMMY_SP),
|
||||||
values: Types(expected_found(true, a, b))
|
values: Types(expected_found(true, a, b))
|
||||||
};
|
};
|
||||||
cx.sub(true, trace).relate(&a, &b).map(|_| ())
|
cx.sub(true, trace, &a, &b).map(|_| ())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,32 +668,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
cause: None}
|
cause: None}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public so that it can be used from the rustc_driver unit tests
|
pub fn equate<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
|
||||||
pub fn equate(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
|
-> RelateResult<'tcx, T>
|
||||||
-> equate::Equate<'a, 'tcx>
|
where T: Relate<'a, 'tcx>
|
||||||
{
|
{
|
||||||
self.combine_fields(a_is_expected, trace).equate()
|
self.combine_fields(a_is_expected, trace).equate().relate(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// public so that it can be used from the rustc_driver unit tests
|
pub fn sub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
|
||||||
pub fn sub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
|
-> RelateResult<'tcx, T>
|
||||||
-> sub::Sub<'a, 'tcx>
|
where T: Relate<'a, 'tcx>
|
||||||
{
|
{
|
||||||
self.combine_fields(a_is_expected, trace).sub()
|
self.combine_fields(a_is_expected, trace).sub().relate(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// public so that it can be used from the rustc_driver unit tests
|
pub fn lub<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
|
||||||
pub fn lub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
|
-> RelateResult<'tcx, T>
|
||||||
-> lub::Lub<'a, 'tcx>
|
where T: Relate<'a, 'tcx>
|
||||||
{
|
{
|
||||||
self.combine_fields(a_is_expected, trace).lub()
|
self.combine_fields(a_is_expected, trace).lub().relate(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// public so that it can be used from the rustc_driver unit tests
|
pub fn glb<T>(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T)
|
||||||
pub fn glb(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
|
-> RelateResult<'tcx, T>
|
||||||
-> glb::Glb<'a, 'tcx>
|
where T: Relate<'a, 'tcx>
|
||||||
{
|
{
|
||||||
self.combine_fields(a_is_expected, trace).glb()
|
self.combine_fields(a_is_expected, trace).glb().relate(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_snapshot(&self) -> CombinedSnapshot {
|
fn start_snapshot(&self) -> CombinedSnapshot {
|
||||||
@ -834,7 +834,7 @@ impl<'a, 'tcx> InferCtxt<'a, '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).relate(&a, &b).map(|_| ())
|
self.sub(a_is_expected, trace, &a, &b).map(|_| ())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,7 +847,7 @@ impl<'a, 'tcx> InferCtxt<'a, '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).relate(&a, &b).map(|_| ())
|
self.equate(a_is_expected, trace, &a, &b).map(|_| ())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -866,7 +866,7 @@ 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).relate(&a, &b).map(|_| ())
|
self.equate(a_is_expected, trace, &a, &b).map(|_| ())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,7 +885,7 @@ 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).relate(&a, &b).map(|_| ())
|
self.sub(a_is_expected, trace, &a, &b).map(|_| ())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1434,7 +1434,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
origin: TypeOrigin::Misc(codemap::DUMMY_SP),
|
origin: TypeOrigin::Misc(codemap::DUMMY_SP),
|
||||||
values: Types(expected_found(true, e, e))
|
values: Types(expected_found(true, e, e))
|
||||||
};
|
};
|
||||||
self.equate(true, trace).relate(a, b)
|
self.equate(true, trace, a, b)
|
||||||
}).map(|_| ())
|
}).map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,6 +602,17 @@ impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::ClosureSubsts<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a,'tcx:'a> Relate<'a,'tcx> for Substs<'tcx> {
|
||||||
|
fn relate<R>(relation: &mut R,
|
||||||
|
a: &Substs<'tcx>,
|
||||||
|
b: &Substs<'tcx>)
|
||||||
|
-> RelateResult<'tcx, Substs<'tcx>>
|
||||||
|
where R: TypeRelation<'a,'tcx>
|
||||||
|
{
|
||||||
|
relate_substs(relation, None, a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::Region {
|
impl<'a,'tcx:'a> Relate<'a,'tcx> for ty::Region {
|
||||||
fn relate<R>(relation: &mut R,
|
fn relate<R>(relation: &mut R,
|
||||||
a: &ty::Region,
|
a: &ty::Region,
|
||||||
|
@ -24,11 +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;
|
use rustc::ty::relate::{TypeRelation, RelateResult};
|
||||||
use rustc::infer::{self, TypeOrigin};
|
use rustc::infer::{self, TypeOrigin};
|
||||||
use rustc::infer::lub::Lub;
|
|
||||||
use rustc::infer::glb::Glb;
|
|
||||||
use rustc::infer::sub::Sub;
|
|
||||||
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};
|
||||||
@ -358,25 +355,25 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
|||||||
infer::TypeTrace::dummy(self.tcx())
|
infer::TypeTrace::dummy(self.tcx())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sub(&self) -> Sub<'a, 'tcx> {
|
pub fn sub(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||||
let trace = self.dummy_type_trace();
|
let trace = self.dummy_type_trace();
|
||||||
self.infcx.sub(true, trace)
|
self.infcx.sub(true, trace, t1, t2)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lub(&self) -> Lub<'a, 'tcx> {
|
pub fn lub(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||||
let trace = self.dummy_type_trace();
|
let trace = self.dummy_type_trace();
|
||||||
self.infcx.lub(true, trace)
|
self.infcx.lub(true, trace, t1, t2)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn glb(&self) -> Glb<'a, 'tcx> {
|
pub fn glb(&self, t1: &Ty<'tcx>, t2: &Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||||
let trace = self.dummy_type_trace();
|
let trace = self.dummy_type_trace();
|
||||||
self.infcx.glb(true, trace)
|
self.infcx.glb(true, trace, t1, t2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that `t1 <: t2` is true (this may register additional
|
/// Checks that `t1 <: t2` is true (this may register additional
|
||||||
/// 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().relate(&t1, &t2) {
|
match self.sub(&t1, &t2) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(ref e) => {
|
Err(ref e) => {
|
||||||
panic!("unexpected error computing sub({:?},{:?}): {}", t1, t2, e);
|
panic!("unexpected error computing sub({:?},{:?}): {}", t1, t2, e);
|
||||||
@ -387,7 +384,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
|||||||
/// Checks that `t1 <: t2` is false (this may register additional
|
/// Checks that `t1 <: t2` is false (this may register additional
|
||||||
/// region checks).
|
/// region checks).
|
||||||
pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
|
pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
|
||||||
match self.sub().relate(&t1, &t2) {
|
match self.sub(&t1, &t2) {
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
panic!("unexpected success computing sub({:?},{:?})", t1, t2);
|
panic!("unexpected success computing sub({:?},{:?})", t1, t2);
|
||||||
@ -397,7 +394,7 @@ 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().relate(&t1, &t2) {
|
match self.lub(&t1, &t2) {
|
||||||
Ok(t) => {
|
Ok(t) => {
|
||||||
self.assert_eq(t, t_lub);
|
self.assert_eq(t, t_lub);
|
||||||
}
|
}
|
||||||
@ -410,7 +407,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
|||||||
/// Checks that `GLB(t1,t2) == t_glb`
|
/// Checks that `GLB(t1,t2) == t_glb`
|
||||||
pub fn check_glb(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_glb: Ty<'tcx>) {
|
pub fn check_glb(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_glb: Ty<'tcx>) {
|
||||||
debug!("check_glb(t1={}, t2={}, t_glb={})", t1, t2, t_glb);
|
debug!("check_glb(t1={}, t2={}, t_glb={})", t1, t2, t_glb);
|
||||||
match self.glb().relate(&t1, &t2) {
|
match self.glb(&t1, &t2) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
panic!("unexpected error computing LUB: {:?}", e)
|
panic!("unexpected error computing LUB: {:?}", e)
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
|||||||
use rustc::ty::{self, LvaluePreference, TypeAndMut, Ty, TyCtxt};
|
use rustc::ty::{self, LvaluePreference, TypeAndMut, Ty, TyCtxt};
|
||||||
use rustc::ty::fold::TypeFoldable;
|
use rustc::ty::fold::TypeFoldable;
|
||||||
use rustc::ty::error::TypeError;
|
use rustc::ty::error::TypeError;
|
||||||
use rustc::ty::relate::{relate_substs, Relate, RelateResult, TypeRelation};
|
use rustc::ty::relate::{RelateResult, TypeRelation};
|
||||||
use util::common::indent;
|
use util::common::indent;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -117,9 +117,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
infcx.commit_if_ok(|_| {
|
infcx.commit_if_ok(|_| {
|
||||||
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).relate(&a, &b)
|
infcx.lub(false, trace, &a, &b)
|
||||||
} else {
|
} else {
|
||||||
infcx.sub(false, trace).relate(&a, &b)
|
infcx.sub(false, trace, &a, &b)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -649,7 +649,6 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
debug!("coercion::try_find_lub({:?}, {:?})", prev_ty, new_ty);
|
debug!("coercion::try_find_lub({:?}, {:?})", prev_ty, new_ty);
|
||||||
|
|
||||||
let trace = TypeTrace::types(origin, true, prev_ty, new_ty);
|
let trace = TypeTrace::types(origin, true, prev_ty, new_ty);
|
||||||
let mut lub = fcx.infcx().lub(true, trace);
|
|
||||||
|
|
||||||
// Special-case that coercion alone cannot handle:
|
// Special-case that coercion alone cannot handle:
|
||||||
// Two function item types of differing IDs or Substs.
|
// Two function item types of differing IDs or Substs.
|
||||||
@ -657,12 +656,12 @@ 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 = lub.relate(a_fty, b_fty)?;
|
let fty = fcx.infcx().lub(true, trace.clone(), a_fty, b_fty)?;
|
||||||
|
|
||||||
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(|_| {
|
||||||
relate_substs(&mut lub, None, a_substs, b_substs)
|
fcx.infcx().lub(true, trace.clone(), a_substs, b_substs)
|
||||||
}).map(|s| fcx.tcx().mk_substs(s));
|
}).map(|s| fcx.tcx().mk_substs(s));
|
||||||
|
|
||||||
if let Ok(substs) = substs {
|
if let Ok(substs) = substs {
|
||||||
@ -724,7 +723,9 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
};
|
};
|
||||||
|
|
||||||
if !noop {
|
if !noop {
|
||||||
return fcx.infcx().commit_if_ok(|_| lub.relate(&prev_ty, &new_ty));
|
return fcx.infcx().commit_if_ok(|_| {
|
||||||
|
fcx.infcx().lub(true, trace.clone(), &prev_ty, &new_ty)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,7 +735,9 @@ pub fn try_find_lub<'a, 'b, 'tcx, E, I>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
if let Some(e) = first_error {
|
if let Some(e) = first_error {
|
||||||
Err(e)
|
Err(e)
|
||||||
} else {
|
} else {
|
||||||
fcx.infcx().commit_if_ok(|_| lub.relate(&prev_ty, &new_ty))
|
fcx.infcx().commit_if_ok(|_| {
|
||||||
|
fcx.infcx().lub(true, trace, &prev_ty, &new_ty)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((ty, adjustment)) => {
|
Ok((ty, adjustment)) => {
|
||||||
|
@ -2904,7 +2904,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
} else {
|
} else {
|
||||||
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).relate(&then_ty, &else_ty)
|
fcx.infcx().lub(true, trace, &then_ty, &else_ty)
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
(origin, then_ty, else_ty, result)
|
(origin, then_ty, else_ty, result)
|
||||||
|
Loading…
Reference in New Issue
Block a user