diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index ffb631e105b3a..917727907ba88 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -503,7 +503,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T { debug!("normalize_associated_type(t={:?})", value); - let value = erase_regions(tcx, value); + let value = tcx.erase_regions(value); if !value.has_projection_types() { return value; @@ -525,9 +525,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T fulfill_cx.register_predicate_obligation(&infcx, obligation); } - let result = drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result); - - result + drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result) } pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span, @@ -535,7 +533,7 @@ pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span, fulfill_cx: &mut traits::FulfillmentContext<'tcx>, result: &T) -> T - where T : TypeFoldable<'tcx> + where T : TypeFoldable<'tcx> + HasTypeFlags { match drain_fulfillment_cx(infcx, fulfill_cx, result) { Ok(v) => v, @@ -559,7 +557,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, fulfill_cx: &mut traits::FulfillmentContext<'tcx>, result: &T) -> Result>> - where T : TypeFoldable<'tcx> + where T : TypeFoldable<'tcx> + HasTypeFlags { debug!("drain_fulfillment_cx(result={:?})", result); @@ -574,71 +572,8 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, } } - // Use freshen to simultaneously replace all type variables with - // their bindings and replace all regions with 'static. This is - // sort of overkill because we do not expect there to be any - // unbound type variables, hence no `TyFresh` types should ever be - // inserted. - Ok(result.fold_with(&mut infcx.freshener())) -} - -/// Returns an equivalent value with all free regions removed (note -/// that late-bound regions remain, because they are important for -/// subtyping, but they are anonymized and normalized as well). This -/// is a stronger, caching version of `ty::fold::erase_regions`. -pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> -{ - let value1 = value.fold_with(&mut RegionEraser(cx)); - debug!("erase_regions({:?}) = {:?}", - value, value1); - return value1; - - struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>); - - impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> { - fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - match self.tcx().normalized_cache.borrow().get(&ty).cloned() { - None => {} - Some(u) => return u - } - - let t_norm = ty::fold::super_fold_ty(self, ty); - self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm); - return t_norm; - } - - fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder - where T : TypeFoldable<'tcx> - { - let u = self.tcx().anonymize_late_bound_regions(t); - ty::fold::super_fold_binder(self, &u) - } - - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - // because late-bound regions affect subtyping, we can't - // erase the bound/free distinction, but we can replace - // all free regions with 'static. - // - // Note that we *CAN* replace early-bound regions -- the - // type system never "sees" those, they get substituted - // away. In trans, they will always be erased to 'static - // whenever a substitution occurs. - match r { - ty::ReLateBound(..) => r, - _ => ty::ReStatic - } - } - - fn fold_substs(&mut self, - substs: &subst::Substs<'tcx>) - -> subst::Substs<'tcx> { - subst::Substs { regions: subst::ErasedRegions, - types: substs.types.fold_with(self) } - } - } + let result = infcx.resolve_type_vars_if_possible(result); + Ok(infcx.tcx.erase_regions(&result)) } impl<'a, 'tcx> InferCtxt<'a, 'tcx> { diff --git a/src/librustc/middle/traits/structural_impls.rs b/src/librustc/middle/traits/structural_impls.rs index 88c219a7c7ace..8ce211120019d 100644 --- a/src/librustc/middle/traits/structural_impls.rs +++ b/src/librustc/middle/traits/structural_impls.rs @@ -150,6 +150,52 @@ impl<'tcx, T: HasTypeFlags> HasTypeFlags for Normalized<'tcx, T> { } } +impl<'tcx, N: HasTypeFlags> HasTypeFlags for traits::VtableImplData<'tcx, N> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.substs.has_type_flags(flags) || + self.nested.has_type_flags(flags) + } +} + +impl<'tcx, N: HasTypeFlags> HasTypeFlags for traits::VtableClosureData<'tcx, N> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.substs.has_type_flags(flags) || + self.nested.has_type_flags(flags) + } +} + +impl<'tcx, N: HasTypeFlags> HasTypeFlags for traits::VtableDefaultImplData { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.nested.has_type_flags(flags) + } +} + +impl<'tcx, N: HasTypeFlags> HasTypeFlags for traits::VtableBuiltinData { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.nested.has_type_flags(flags) + } +} + +impl<'tcx> HasTypeFlags for traits::VtableObjectData<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.upcast_trait_ref.has_type_flags(flags) + } +} + +impl<'tcx, N: HasTypeFlags> HasTypeFlags for traits::Vtable<'tcx, N> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + match *self { + traits::VtableImpl(ref v) => v.has_type_flags(flags), + traits::VtableDefaultImpl(ref t) => t.has_type_flags(flags), + traits::VtableClosure(ref d) => d.has_type_flags(flags), + traits::VtableFnPointer(ref d) => d.has_type_flags(flags), + traits::VtableParam(ref n) => n.has_type_flags(flags), + traits::VtableBuiltin(ref d) => d.has_type_flags(flags), + traits::VtableObject(ref d) => d.has_type_flags(flags) + } + } +} + impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> { fn fold_with>(&self, folder: &mut F) -> traits::Obligation<'tcx, O> { @@ -198,6 +244,15 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinDa } } +impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> { + fn fold_with>(&self, folder: &mut F) -> traits::VtableObjectData<'tcx> { + traits::VtableObjectData { + upcast_trait_ref: self.upcast_trait_ref.fold_with(folder), + vtable_base: self.vtable_base + } + } +} + impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> { fn fold_with>(&self, folder: &mut F) -> traits::Vtable<'tcx, N> { match *self { @@ -216,15 +271,6 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> } } -impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> { - fn fold_with>(&self, folder: &mut F) -> traits::VtableObjectData<'tcx> { - traits::VtableObjectData { - upcast_trait_ref: self.upcast_trait_ref.fold_with(folder), - vtable_base: self.vtable_base - } - } -} - impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> { fn fold_with>(&self, folder: &mut F) -> Normalized<'tcx, T> { Normalized { diff --git a/src/librustc/middle/ty/fold.rs b/src/librustc/middle/ty/fold.rs index 751bac28ce4c2..605e78e928115 100644 --- a/src/librustc/middle/ty/fold.rs +++ b/src/librustc/middle/ty/fold.rs @@ -37,7 +37,7 @@ use middle::region; use middle::subst; use middle::ty::adjustment; -use middle::ty::{self, Binder, Ty, HasTypeFlags, RegionEscape}; +use middle::ty::{self, Binder, Ty, RegionEscape}; use std::fmt; use util::nodemap::{FnvHashMap, FnvHashSet}; @@ -588,39 +588,63 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> /////////////////////////////////////////////////////////////////////////// // Region eraser -// -// Replaces all free regions with 'static. Useful in contexts, such as -// method probing, where precise region relationships are not -// important. Note that in trans you should use -// `common::erase_regions` instead. -pub struct RegionEraser<'a, 'tcx: 'a> { - tcx: &'a ty::ctxt<'tcx>, -} +impl<'tcx> ty::ctxt<'tcx> { + /// Returns an equivalent value with all free regions removed (note + /// that late-bound regions remain, because they are important for + /// subtyping, but they are anonymized and normalized as well).. + pub fn erase_regions(&self, value: &T) -> T + where T : TypeFoldable<'tcx> + { + let value1 = value.fold_with(&mut RegionEraser(self)); + debug!("erase_regions({:?}) = {:?}", + value, value1); + return value1; -pub fn erase_regions<'tcx, T: TypeFoldable<'tcx>>(tcx: &ty::ctxt<'tcx>, t: T) -> T { - let mut eraser = RegionEraser { tcx: tcx }; - t.fold_with(&mut eraser) -} + struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>); -impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> { - fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx } + impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> { + fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !t.has_erasable_regions() { - return t; - } + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match self.tcx().normalized_cache.borrow().get(&ty).cloned() { + None => {} + Some(u) => return u + } - super_fold_ty(self, t) - } + let t_norm = ty::fold::super_fold_ty(self, ty); + self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm); + return t_norm; + } - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - // because whether or not a region is bound affects subtyping, - // we can't erase the bound/free distinction, but we can - // replace all free regions with 'static - match r { - ty::ReLateBound(..) | ty::ReEarlyBound(..) => r, - _ => ty::ReStatic + fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder + where T : TypeFoldable<'tcx> + { + let u = self.tcx().anonymize_late_bound_regions(t); + ty::fold::super_fold_binder(self, &u) + } + + fn fold_region(&mut self, r: ty::Region) -> ty::Region { + // because late-bound regions affect subtyping, we can't + // erase the bound/free distinction, but we can replace + // all free regions with 'static. + // + // Note that we *CAN* replace early-bound regions -- the + // type system never "sees" those, they get substituted + // away. In trans, they will always be erased to 'static + // whenever a substitution occurs. + match r { + ty::ReLateBound(..) => r, + _ => ty::ReStatic + } + } + + fn fold_substs(&mut self, + substs: &subst::Substs<'tcx>) + -> subst::Substs<'tcx> { + subst::Substs { regions: subst::ErasedRegions, + types: substs.types.fold_with(self) } + } } } } diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index dff423b35dd0a..a8adb38864424 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -979,18 +979,6 @@ impl<'tcx> Predicate<'tcx> { vec.into_iter() } - pub fn has_escaping_regions(&self) -> bool { - match *self { - Predicate::Trait(ref trait_ref) => trait_ref.has_escaping_regions(), - Predicate::Equate(ref p) => p.has_escaping_regions(), - Predicate::RegionOutlives(ref p) => p.has_escaping_regions(), - Predicate::TypeOutlives(ref p) => p.has_escaping_regions(), - Predicate::Projection(ref p) => p.has_escaping_regions(), - Predicate::WellFormed(p) => p.has_escaping_regions(), - Predicate::ObjectSafe(_trait_def_id) => false, - } - } - pub fn to_opt_poly_trait_ref(&self) -> Option> { match *self { Predicate::Trait(ref t) => { @@ -1037,10 +1025,6 @@ impl<'tcx> InstantiatedPredicates<'tcx> { InstantiatedPredicates { predicates: VecPerParamSpace::empty() } } - pub fn has_escaping_regions(&self) -> bool { - self.predicates.any(|p| p.has_escaping_regions()) - } - pub fn is_empty(&self) -> bool { self.predicates.is_empty() } diff --git a/src/librustc/middle/ty/structural_impls.rs b/src/librustc/middle/ty/structural_impls.rs index 0058ccbce3b19..4ed87e673d996 100644 --- a/src/librustc/middle/ty/structural_impls.rs +++ b/src/librustc/middle/ty/structural_impls.rs @@ -45,6 +45,12 @@ impl<'tcx> RegionEscape for ty::ExistentialBounds<'tcx> { } } +impl<'tcx> RegionEscape for ty::InstantiatedPredicates<'tcx> { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + self.predicates.has_regions_escaping_depth(depth) + } +} + impl<'tcx> RegionEscape for subst::Substs<'tcx> { fn has_regions_escaping_depth(&self, depth: u32) -> bool { self.types.has_regions_escaping_depth(depth) || @@ -179,6 +185,13 @@ impl<'tcx> RegionEscape for ty::ProjectionTy<'tcx> { self.trait_ref.has_regions_escaping_depth(depth) } } + +impl HasTypeFlags for () { + fn has_type_flags(&self, _flags: TypeFlags) -> bool { + false + } +} + impl<'tcx,T:HasTypeFlags> HasTypeFlags for Vec { fn has_type_flags(&self, flags: TypeFlags) -> bool { self[..].has_type_flags(flags) diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index eba82047bd921..124f50d660329 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -24,6 +24,7 @@ use session; use llvm::{self, ValueRef, get_params}; use middle::def; use middle::def_id::{DefId, LOCAL_CRATE}; +use middle::infer::normalize_associated_type; use middle::subst; use middle::subst::{Subst, Substs}; use rustc::front::map as hir_map; @@ -260,7 +261,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( let tcx = ccx.tcx(); // Normalize the type for better caching. - let bare_fn_ty = common::erase_regions(tcx, &bare_fn_ty); + let bare_fn_ty = tcx.erase_regions(&bare_fn_ty); // If this is an impl of `Fn` or `FnMut` trait, the receiver is `&self`. let is_by_ref = match closure_kind { @@ -521,7 +522,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>( // Type scheme of the function item (may have type params) let fn_type_scheme = tcx.lookup_item_type(def_id); - let fn_type = monomorphize::normalize_associated_type(tcx, &fn_type_scheme.ty); + let fn_type = normalize_associated_type(tcx, &fn_type_scheme.ty); // Find the actual function pointer. let mut val = { diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index 5877c81923bfa..dc9ea62e9d11a 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -135,7 +135,7 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, -> ValueRef { // Normalize type so differences in regions and typedefs don't cause // duplicate declarations - let substs = erase_regions(ccx.tcx(), substs); + let substs = ccx.tcx().erase_regions(substs); let mono_id = MonoId { def: closure_id, params: &substs.func_substs.types diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 044e96db04de5..ec34d0dd59257 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -47,7 +47,6 @@ use arena::TypedArena; use libc::{c_uint, c_char}; use std::ffi::CString; use std::cell::{Cell, RefCell}; -use std::result::Result as StdResult; use std::vec::Vec; use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; @@ -56,65 +55,6 @@ use syntax::parse::token; pub use trans::context::CrateContext; -/// Returns an equivalent value with all free regions removed (note -/// that late-bound regions remain, because they are important for -/// subtyping, but they are anonymized and normalized as well). This -/// is a stronger, caching version of `ty::fold::erase_regions`. -pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> -{ - let value1 = value.fold_with(&mut RegionEraser(cx)); - debug!("erase_regions({:?}) = {:?}", - value, value1); - return value1; - - struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>); - - impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> { - fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - match self.tcx().normalized_cache.borrow().get(&ty).cloned() { - None => {} - Some(u) => return u - } - - let t_norm = ty::fold::super_fold_ty(self, ty); - self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm); - return t_norm; - } - - fn fold_binder(&mut self, t: &ty::Binder) -> ty::Binder - where T : TypeFoldable<'tcx> - { - let u = self.tcx().anonymize_late_bound_regions(t); - ty::fold::super_fold_binder(self, &u) - } - - fn fold_region(&mut self, r: ty::Region) -> ty::Region { - // because late-bound regions affect subtyping, we can't - // erase the bound/free distinction, but we can replace - // all free regions with 'static. - // - // Note that we *CAN* replace early-bound regions -- the - // type system never "sees" those, they get substituted - // away. In trans, they will always be erased to 'static - // whenever a substitution occurs. - match r { - ty::ReLateBound(..) => r, - _ => ty::ReStatic - } - } - - fn fold_substs(&mut self, - substs: &subst::Substs<'tcx>) - -> subst::Substs<'tcx> { - subst::Substs { regions: subst::ErasedRegions, - types: substs.types.fold_with(self) } - } - } -} - /// Is the type's representation size known at compile time? pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool { ty.is_sized(&tcx.empty_parameter_environment(), DUMMY_SP) @@ -1043,7 +983,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let tcx = ccx.tcx(); // Remove any references to regions; this helps improve caching. - let trait_ref = erase_regions(tcx, &trait_ref); + let trait_ref = tcx.erase_regions(&trait_ref); // First check the cache. match ccx.trait_cache().borrow().get(&trait_ref) { @@ -1098,8 +1038,8 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let vtable = selection.map(|predicate| { fulfill_cx.register_predicate_obligation(&infcx, predicate); }); - let vtable = erase_regions(tcx, - &drain_fulfillment_cx_or_panic(span, &infcx, &mut fulfill_cx, &vtable) + let vtable = infer::drain_fulfillment_cx_or_panic( + span, &infcx, &mut fulfill_cx, &vtable ); info!("Cache miss: {:?} => {:?}", trait_ref, vtable); @@ -1134,59 +1074,8 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let obligation = traits::Obligation::new(cause.clone(), predicate); fulfill_cx.register_predicate_obligation(&infcx, obligation); } - drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok() -} - -pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span, - infcx: &infer::InferCtxt<'a,'tcx>, - fulfill_cx: &mut traits::FulfillmentContext<'tcx>, - result: &T) - -> T - where T : TypeFoldable<'tcx> -{ - match drain_fulfillment_cx(infcx, fulfill_cx, result) { - Ok(v) => v, - Err(errors) => { - infcx.tcx.sess.span_bug( - span, - &format!("Encountered errors `{:?}` fulfilling during trans", - errors)); - } - } -} - -/// Finishes processes any obligations that remain in the fulfillment -/// context, and then "freshens" and returns `result`. This is -/// primarily used during normalization and other cases where -/// processing the obligations in `fulfill_cx` may cause type -/// inference variables that appear in `result` to be unified, and -/// hence we need to process those obligations to get the complete -/// picture of the type. -pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>, - fulfill_cx: &mut traits::FulfillmentContext<'tcx>, - result: &T) - -> StdResult>> - where T : TypeFoldable<'tcx> -{ - debug!("drain_fulfillment_cx(result={:?})", - result); - - // In principle, we only need to do this so long as `result` - // contains unbound type parameters. It could be a slight - // optimization to stop iterating early. - match fulfill_cx.select_all_or_error(infcx) { - Ok(()) => { } - Err(errors) => { - return Err(errors); - } - } - // Use freshen to simultaneously replace all type variables with - // their bindings and replace all regions with 'static. This is - // sort of overkill because we do not expect there to be any - // unbound type variables, hence no `TyFresh` types should ever be - // inserted. - Ok(result.fold_with(&mut infcx.freshener())) + infer::drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok() } // Key used to lookup values supplied for type parameters in an expr. diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index 869dff724fb72..dbb1355c9e612 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -27,6 +27,7 @@ use llvm::{ModuleRef, ContextRef, ValueRef}; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIDescriptor, FlagPrototyped}; use middle::def_id::DefId; +use middle::infer::normalize_associated_type; use middle::subst::{self, Substs}; use rustc_front; use rustc_front::hir; @@ -463,7 +464,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, -> DIArray { let self_type = param_substs.self_ty(); - let self_type = monomorphize::normalize_associated_type(cx.tcx(), &self_type); + let self_type = normalize_associated_type(cx.tcx(), &self_type); // Only true for static default methods: let has_self_type = self_type.is_some(); diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs index ee1d4ed47d7c1..ce9f3b4b05da1 100644 --- a/src/librustc_trans/trans/declare.rs +++ b/src/librustc_trans/trans/declare.rs @@ -26,7 +26,6 @@ use syntax::abi; use trans::attributes; use trans::base; use trans::context::CrateContext; -use trans::monomorphize; use trans::type_::Type; use trans::type_of; @@ -104,7 +103,7 @@ pub fn declare_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, fn_type: ty::Ty<'tcx>) -> ValueRef { debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type); - let fn_type = monomorphize::normalize_associated_type(ccx.tcx(), &fn_type); + let fn_type = infer::normalize_associated_type(ccx.tcx(), &fn_type); debug!("declare_rust_fn (after normalised associated types) fn_type={:?}", fn_type); diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 1ef9981a0a46a..20c3f356b1122 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -13,10 +13,9 @@ use session; use llvm::ValueRef; use llvm; use middle::def_id::DefId; -use middle::infer; +use middle::infer::normalize_associated_type; use middle::subst; use middle::subst::{Subst, Substs}; -use middle::traits; use middle::ty::fold::{TypeFolder, TypeFoldable}; use trans::attributes; use trans::base::{trans_enum_variant, push_ctxt, get_item_val}; @@ -33,7 +32,6 @@ use rustc_front::attr; use syntax::abi; use syntax::ast; -use syntax::codemap::DUMMY_SP; use std::hash::{Hasher, Hash, SipHasher}; pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, @@ -300,39 +298,3 @@ pub fn field_ty<'tcx>(tcx: &ty::ctxt<'tcx>, { normalize_associated_type(tcx, &f.ty(tcx, param_substs)) } - -/// Removes associated types, if any. Since this during -/// monomorphization, we know that only concrete types are involved, -/// and hence we can be sure that all associated types will be -/// completely normalized away. -pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags -{ - debug!("normalize_associated_type(t={:?})", value); - - let value = erase_regions(tcx, value); - - if !value.has_projection_types() { - return value; - } - - // FIXME(#20304) -- cache - let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables); - let mut selcx = traits::SelectionContext::new(&infcx); - let cause = traits::ObligationCause::dummy(); - let traits::Normalized { value: result, obligations } = - traits::normalize(&mut selcx, cause, &value); - - debug!("normalize_associated_type: result={:?} obligations={:?}", - result, - obligations); - - let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut(); - - for obligation in obligations { - fulfill_cx.register_predicate_obligation(&infcx, obligation); - } - let result = drain_fulfillment_cx_or_panic(DUMMY_SP, &infcx, &mut fulfill_cx, &result); - - result -} diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 127140691f05f..43e1ad8115bed 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -325,7 +325,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> // Rust types are defined as the same LLVM types. If we don't do // this then, e.g. `Option<{myfield: bool}>` would be a different // type than `Option`. - let t_norm = erase_regions(cx.tcx(), &t); + let t_norm = cx.tcx().erase_regions(&t); if t != t_norm { let llty = in_memory_type_of(cx, t_norm); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 1cfb495b36ed7..edf1cc9b7ef38 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -17,7 +17,7 @@ use middle::def_id::DefId; use middle::privacy::{AllPublic, DependsOn, LastPrivate, LastMod}; use middle::subst; use middle::traits; -use middle::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef}; +use middle::ty::{self, RegionEscape, ToPredicate, ToPolyTraitRef, TraitRef}; use middle::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr}; use middle::infer;