From 8cd0f0cc3a7a6c0f15a9b214cfa5f0744713c178 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Mon, 28 Mar 2016 21:56:19 -0700 Subject: [PATCH] Refactor s.t. TypeRelation implementors don't escape InferCtxt --- src/librustc/infer/mod.rs | 44 +++++++++++++-------------- src/librustc/ty/relate.rs | 11 +++++++ src/librustc_driver/test.rs | 25 +++++++-------- src/librustc_typeck/check/coercion.rs | 19 +++++++----- src/librustc_typeck/check/mod.rs | 2 +- 5 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 91ad7e86925..725c6d9593c 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -407,7 +407,7 @@ pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, origin: TypeOrigin::Misc(codemap::DUMMY_SP), 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} } - // public so that it can be used from the rustc_driver unit tests - pub fn equate(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>) - -> equate::Equate<'a, 'tcx> + pub fn equate(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) + -> RelateResult<'tcx, T> + 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(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>) - -> sub::Sub<'a, 'tcx> + pub fn sub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) + -> RelateResult<'tcx, T> + 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(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>) - -> lub::Lub<'a, 'tcx> + pub fn lub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) + -> RelateResult<'tcx, T> + 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(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>) - -> glb::Glb<'a, 'tcx> + pub fn glb(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>, a: &T, b: &T) + -> RelateResult<'tcx, T> + 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 { @@ -834,7 +834,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { debug!("sub_types({:?} <: {:?})", a, b); self.commit_if_ok(|_| { let trace = TypeTrace::types(origin, a_is_expected, a, b); - self.sub(a_is_expected, trace).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(|_| { 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, 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, 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), values: Types(expected_found(true, e, e)) }; - self.equate(true, trace).relate(a, b) + self.equate(true, trace, a, b) }).map(|_| ()) } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index bb4f13b13c1..635af0a98e2 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -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(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 { fn relate(relation: &mut R, a: &ty::Region, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 8620d5e1fd0..6ce623a3b28 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -24,11 +24,8 @@ use rustc::ty::subst; use rustc::ty::subst::Subst; use rustc::traits::ProjectionMode; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use rustc::ty::relate::TypeRelation; +use rustc::ty::relate::{TypeRelation, RelateResult}; 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::front::map as hir_map; use rustc::session::{self, config}; @@ -358,25 +355,25 @@ impl<'a, 'tcx> Env<'a, '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(); - 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(); - 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(); - self.infcx.glb(true, trace) + self.infcx.glb(true, trace, t1, t2) } /// Checks that `t1 <: t2` is true (this may register additional /// region checks). pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) { - match self.sub().relate(&t1, &t2) { + match self.sub(&t1, &t2) { Ok(_) => {} Err(ref 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 /// region checks). pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) { - match self.sub().relate(&t1, &t2) { + match self.sub(&t1, &t2) { Err(_) => {} Ok(_) => { panic!("unexpected success computing sub({:?},{:?})", t1, t2); @@ -397,7 +394,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { /// Checks that `LUB(t1,t2) == t_lub` pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) { - match self.lub().relate(&t1, &t2) { + match self.lub(&t1, &t2) { Ok(t) => { self.assert_eq(t, t_lub); } @@ -410,7 +407,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> { /// Checks that `GLB(t1,t2) == t_glb` 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); - match self.glb().relate(&t1, &t2) { + match self.glb(&t1, &t2) { Err(e) => { panic!("unexpected error computing LUB: {:?}", e) } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index dad7d7cd26c..e36da1a568a 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -71,7 +71,7 @@ use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer}; use rustc::ty::{self, LvaluePreference, TypeAndMut, Ty, TyCtxt}; use rustc::ty::fold::TypeFoldable; 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 std::cell::RefCell; @@ -117,9 +117,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { infcx.commit_if_ok(|_| { let trace = TypeTrace::types(self.origin, false, a, b); if self.use_lub { - infcx.lub(false, trace).relate(&a, &b) + infcx.lub(false, trace, &a, &b) } 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); 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: // 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(b_def_id, b_substs, b_fty)) => { // 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 { // Same function, maybe the parameters match. 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)); 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 { - 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 { Err(e) } 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)) => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c5a0657594e..107497a2aa3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2904,7 +2904,7 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } else { fcx.infcx().commit_if_ok(|_| { 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)