From f9808ea4b463a9e7905576dc222af0851c4e6e77 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 18 Nov 2015 09:38:57 +0000 Subject: [PATCH 1/3] Create a visitor for `TypeFoldable`s and use it to implement RegionEscape and HasTypeFlags (fixes #20298) --- src/librustc/middle/implicator.rs | 2 +- src/librustc/middle/infer/combine.rs | 2 +- src/librustc/middle/infer/freshen.rs | 2 +- src/librustc/middle/infer/mod.rs | 10 +- src/librustc/middle/infer/resolve.rs | 6 +- src/librustc/middle/subst.rs | 2 +- src/librustc/middle/traits/error_reporting.rs | 2 +- src/librustc/middle/traits/mod.rs | 2 +- src/librustc/middle/traits/project.rs | 8 +- src/librustc/middle/traits/select.rs | 2 +- .../middle/traits/structural_impls.rs | 108 +-- src/librustc/middle/ty/fold.rs | 317 +++----- src/librustc/middle/ty/relate.rs | 4 +- src/librustc/middle/ty/structural_impls.rs | 738 +++++++++--------- src/librustc/util/ppaux.rs | 4 + src/librustc_trans/trans/common.rs | 4 +- src/librustc_trans/trans/monomorphize.rs | 2 +- src/librustc_typeck/check/assoc.rs | 3 +- src/librustc_typeck/check/mod.rs | 6 +- 19 files changed, 534 insertions(+), 690 deletions(-) diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index 9f33c4df03d41..a16e1c4833086 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx> Implicator<'a, 'tcx> { } fn fully_normalize(&self, value: &T) -> Result - where T : TypeFoldable<'tcx> + ty::HasTypeFlags + where T : TypeFoldable<'tcx> { let value = traits::fully_normalize(self.infcx, diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 2a25ed2c6e144..a526586802cac 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -318,7 +318,7 @@ impl<'cx, 'tcx> ty::fold::TypeFolder<'tcx> for Generalizer<'cx, 'tcx> { } } _ => { - ty::fold::super_fold_ty(self, t) + t.fold_subitems_with(self) } } } diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs index 0bae3cd2d8690..7202c0a8052ed 100644 --- a/src/librustc/middle/infer/freshen.rs +++ b/src/librustc/middle/infer/freshen.rs @@ -169,7 +169,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { ty::TyTuple(..) | ty::TyProjection(..) | ty::TyParam(..) => { - ty::fold::super_fold_ty(self, t) + t.fold_subitems_with(self) } } } diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 21a1ee37b7f43..941fb05c3d01d 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -512,7 +512,7 @@ pub struct CombinedSnapshot { } pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { debug!("normalize_associated_type(t={:?})", value); @@ -546,7 +546,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> + HasTypeFlags + where T : TypeFoldable<'tcx> { match drain_fulfillment_cx(infcx, fulfill_cx, result) { Ok(v) => v, @@ -570,7 +570,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> + HasTypeFlags + where T : TypeFoldable<'tcx> { debug!("drain_fulfillment_cx(result={:?})", result); @@ -929,7 +929,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { snapshot: &CombinedSnapshot, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { /*! See `higher_ranked::plug_leaks` */ @@ -1201,7 +1201,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub fn resolve_type_vars_if_possible(&self, value: &T) -> T - where T: TypeFoldable<'tcx> + HasTypeFlags + where T: TypeFoldable<'tcx> { /*! * Where possible, replaces type/int/float variables in diff --git a/src/librustc/middle/infer/resolve.rs b/src/librustc/middle/infer/resolve.rs index 5190c658194f7..d89036faef945 100644 --- a/src/librustc/middle/infer/resolve.rs +++ b/src/librustc/middle/infer/resolve.rs @@ -40,7 +40,7 @@ impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for OpportunisticTypeResolver<'a, 'tcx t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t0 = self.infcx.shallow_resolve(t); - ty::fold::super_fold_ty(self, t0) + t0.fold_subitems_with(self) } } } @@ -68,7 +68,7 @@ impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for OpportunisticTypeAndRegionResolver t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t0 = self.infcx.shallow_resolve(t); - ty::fold::super_fold_ty(self, t0) + t0.fold_subitems_with(self) } } @@ -133,7 +133,7 @@ impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { t)); } _ => { - ty::fold::super_fold_ty(self, t) + t.fold_subitems_with(self) } } } diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index aa47b32dc3e4d..d935b51813a5b 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -674,7 +674,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { self.ty_for_param(p, t) } _ => { - ty::fold::super_fold_ty(self, t) + t.fold_subitems_with(self) } }; diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 038c414662a8a..464b4dfb83bdd 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -185,7 +185,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, obligation: &Obligation<'tcx, T>) -> ! - where T: fmt::Display + TypeFoldable<'tcx> + HasTypeFlags + where T: fmt::Display + TypeFoldable<'tcx> { let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate); diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index dddd6f8bc85d7..01c2f56123501 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -470,7 +470,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, cause: ObligationCause<'tcx>, value: &T) -> Result>> - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { debug!("normalize_param_env(value={:?})", value); diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 8fbfd513c78d6..9c317895c3665 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -202,7 +202,7 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>, cause: ObligationCause<'tcx>, value: &T) -> Normalized<'tcx, T> - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { normalize_with_depth(selcx, cause, 0, value) } @@ -213,7 +213,7 @@ pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tc depth: usize, value: &T) -> Normalized<'tcx, T> - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth); let result = normalizer.fold(value); @@ -245,7 +245,7 @@ impl<'a,'b,'tcx> AssociatedTypeNormalizer<'a,'b,'tcx> { } } - fn fold + HasTypeFlags>(&mut self, value: &T) -> T { + fn fold>(&mut self, value: &T) -> T { let value = self.selcx.infcx().resolve_type_vars_if_possible(value); if !value.has_projection_types() { @@ -273,7 +273,7 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> { // normalize it when we instantiate those bound regions (which // should occur eventually). - let ty = ty::fold::super_fold_ty(self, ty); + let ty = ty.fold_subitems_with(self); match ty.sty { ty::TyProjection(ref data) if !data.has_escaping_regions() => { // (*) diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index bd92f9748669f..a31fccbb3f71e 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -965,7 +965,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match *candidate { Ok(Some(_)) | Err(_) => true, Ok(None) => { - cache_fresh_trait_pred.0.input_types().has_infer_types() + cache_fresh_trait_pred.0.trait_ref.substs.types.has_infer_types() } } } diff --git a/src/librustc/middle/traits/structural_impls.rs b/src/librustc/middle/traits/structural_impls.rs index 8ce211120019d..ea1657180657b 100644 --- a/src/librustc/middle/traits/structural_impls.rs +++ b/src/librustc/middle/traits/structural_impls.rs @@ -10,8 +10,7 @@ use middle::traits; use middle::traits::project::Normalized; -use middle::ty::{HasTypeFlags, TypeFlags, RegionEscape}; -use middle::ty::fold::{TypeFoldable, TypeFolder}; +use middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use std::fmt; @@ -131,71 +130,6 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { } } -impl<'tcx, P: RegionEscape> RegionEscape for traits::Obligation<'tcx,P> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.predicate.has_regions_escaping_depth(depth) - } -} - -impl<'tcx, T: HasTypeFlags> HasTypeFlags for traits::Obligation<'tcx, T> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.predicate.has_type_flags(flags) - } -} - -impl<'tcx, T: HasTypeFlags> HasTypeFlags for Normalized<'tcx, T> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.value.has_type_flags(flags) || - self.obligations.has_type_flags(flags) - } -} - -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> { @@ -205,6 +139,10 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx predicate: self.predicate.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.predicate.visit_with(visitor) + } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> { @@ -215,6 +153,10 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData< nested: self.nested.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.substs.visit_with(visitor) || self.nested.visit_with(visitor) + } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> { @@ -225,6 +167,10 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureDa nested: self.nested.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.substs.visit_with(visitor) || self.nested.visit_with(visitor) + } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultImplData { @@ -234,6 +180,10 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultIm nested: self.nested.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.nested.visit_with(visitor) + } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData { @@ -242,6 +192,10 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinDa nested: self.nested.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.nested.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> { @@ -251,6 +205,10 @@ impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> { vtable_base: self.vtable_base } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.upcast_trait_ref.visit_with(visitor) + } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> { @@ -269,6 +227,18 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + match *self { + traits::VtableImpl(ref v) => v.visit_with(visitor), + traits::VtableDefaultImpl(ref t) => t.visit_with(visitor), + traits::VtableClosure(ref d) => d.visit_with(visitor), + traits::VtableFnPointer(ref d) => d.visit_with(visitor), + traits::VtableParam(ref n) => n.visit_with(visitor), + traits::VtableBuiltin(ref d) => d.visit_with(visitor), + traits::VtableObject(ref d) => d.visit_with(visitor), + } + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> { @@ -278,4 +248,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> { obligations: self.obligations.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.value.visit_with(visitor) || self.obligations.visit_with(visitor) + } } diff --git a/src/librustc/middle/ty/fold.rs b/src/librustc/middle/ty/fold.rs index 605e78e928115..8d68c1da7f84e 100644 --- a/src/librustc/middle/ty/fold.rs +++ b/src/librustc/middle/ty/fold.rs @@ -14,41 +14,51 @@ //! instance of a "folder" (a type which implements `TypeFolder`). Then //! the setup is intended to be: //! -//! T.fold_with(F) --calls--> F.fold_T(T) --calls--> super_fold_T(F, T) +//! T.fold_with(F) --calls--> F.fold_T(T) --calls--> T.fold_subitems_with(F) //! //! This way, when you define a new folder F, you can override -//! `fold_T()` to customize the behavior, and invoke `super_fold_T()` +//! `fold_T()` to customize the behavior, and invoke `T.fold_subitems_with()` //! to get the original behavior. Meanwhile, to actually fold //! something, you can just write `T.fold_with(F)`, which is //! convenient. (Note that `fold_with` will also transparently handle //! things like a `Vec` where T is foldable and so on.) //! //! In this ideal setup, the only function that actually *does* -//! anything is `super_fold_T`, which traverses the type `T`. Moreover, -//! `super_fold_T` should only ever call `T.fold_with()`. +//! anything is `T.fold_subitems_with()`, which traverses the type `T`. +//! Moreover, `T.fold_subitems_with()` should only ever call `T.fold_with()`. //! //! In some cases, we follow a degenerate pattern where we do not have -//! a `fold_T` nor `super_fold_T` method. Instead, `T.fold_with` -//! traverses the structure directly. This is suboptimal because the -//! behavior cannot be overridden, but it's much less work to implement. -//! If you ever *do* need an override that doesn't exist, it's not hard -//! to convert the degenerate pattern into the proper thing. +//! a `fold_T` method. Instead, `T.fold_with` traverses the structure directly. +//! This is suboptimal because the behavior cannot be overridden, but it's +//! much less work to implement. If you ever *do* need an override that +//! doesn't exist, it's not hard to convert the degenerate pattern into the +//! proper thing. +//! +//! A `TypeFoldable` T can also be visited by a `TypeVisitor` V using similar setup: +//! T.visit_with(V) --calls--> V.visit_T(T) --calls--> T.visit_subitems_with(V). +//! These methods return true to indicate that the visitor has found what it is looking for +//! and does not need to visit anything else. use middle::region; use middle::subst; use middle::ty::adjustment; -use middle::ty::{self, Binder, Ty, RegionEscape}; +use middle::ty::{self, Binder, Ty, RegionEscape, HasTypeFlags}; use std::fmt; use util::nodemap::{FnvHashMap, FnvHashSet}; -/////////////////////////////////////////////////////////////////////////// -// Two generic traits - /// The TypeFoldable trait is implemented for every type that can be folded. /// Basically, every type that has a corresponding method in TypeFolder. pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn fold_with>(&self, folder: &mut F) -> Self; + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + self.fold_with(folder) + } + + fn visit_with>(&self, visitor: &mut V) -> bool; + fn visit_subitems_with>(&self, visitor: &mut V) -> bool { + self.visit_with(visitor) + } } /// The TypeFolder trait defines the actual *folding*. There is a @@ -74,248 +84,77 @@ pub trait TypeFolder<'tcx> : Sized { where T : TypeFoldable<'tcx> { // FIXME(#20526) this should replace `enter_region_binder`/`exit_region_binder`. - super_fold_binder(self, t) + t.fold_subitems_with(self) } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - super_fold_ty(self, t) + t.fold_subitems_with(self) } fn fold_mt(&mut self, t: &ty::TypeAndMut<'tcx>) -> ty::TypeAndMut<'tcx> { - super_fold_mt(self, t) + t.fold_subitems_with(self) } fn fold_trait_ref(&mut self, t: &ty::TraitRef<'tcx>) -> ty::TraitRef<'tcx> { - super_fold_trait_ref(self, t) + t.fold_subitems_with(self) } fn fold_substs(&mut self, substs: &subst::Substs<'tcx>) -> subst::Substs<'tcx> { - super_fold_substs(self, substs) + substs.fold_subitems_with(self) } fn fold_fn_sig(&mut self, sig: &ty::FnSig<'tcx>) -> ty::FnSig<'tcx> { - super_fold_fn_sig(self, sig) + sig.fold_subitems_with(self) } fn fold_output(&mut self, output: &ty::FnOutput<'tcx>) -> ty::FnOutput<'tcx> { - super_fold_output(self, output) + output.fold_subitems_with(self) } fn fold_bare_fn_ty(&mut self, fty: &ty::BareFnTy<'tcx>) -> ty::BareFnTy<'tcx> { - super_fold_bare_fn_ty(self, fty) + fty.fold_subitems_with(self) } fn fold_closure_ty(&mut self, fty: &ty::ClosureTy<'tcx>) -> ty::ClosureTy<'tcx> { - super_fold_closure_ty(self, fty) + fty.fold_subitems_with(self) } fn fold_region(&mut self, r: ty::Region) -> ty::Region { - r + r.fold_subitems_with(self) } fn fold_existential_bounds(&mut self, s: &ty::ExistentialBounds<'tcx>) -> ty::ExistentialBounds<'tcx> { - super_fold_existential_bounds(self, s) + s.fold_subitems_with(self) } fn fold_autoref(&mut self, ar: &adjustment::AutoRef<'tcx>) -> adjustment::AutoRef<'tcx> { - super_fold_autoref(self, ar) - } - - fn fold_item_substs(&mut self, i: ty::ItemSubsts<'tcx>) -> ty::ItemSubsts<'tcx> { - super_fold_item_substs(self, i) + ar.fold_subitems_with(self) } } -/////////////////////////////////////////////////////////////////////////// -// "super" routines: these are the default implementations for TypeFolder. -// -// They should invoke `foo.fold_with()` to do recursive folding. - -pub fn super_fold_binder<'tcx, T, U>(this: &mut T, - binder: &Binder) - -> Binder - where T : TypeFolder<'tcx>, U : TypeFoldable<'tcx> -{ - this.enter_region_binder(); - let result = Binder(binder.0.fold_with(this)); - this.exit_region_binder(); - result -} - -pub fn super_fold_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - ty: Ty<'tcx>) - -> Ty<'tcx> { - let sty = match ty.sty { - ty::TyBox(typ) => { - ty::TyBox(typ.fold_with(this)) - } - ty::TyRawPtr(ref tm) => { - ty::TyRawPtr(tm.fold_with(this)) - } - ty::TyArray(typ, sz) => { - ty::TyArray(typ.fold_with(this), sz) - } - ty::TySlice(typ) => { - ty::TySlice(typ.fold_with(this)) - } - ty::TyEnum(tid, ref substs) => { - let substs = substs.fold_with(this); - ty::TyEnum(tid, this.tcx().mk_substs(substs)) - } - ty::TyTrait(box ty::TraitTy { ref principal, ref bounds }) => { - ty::TyTrait(box ty::TraitTy { - principal: principal.fold_with(this), - bounds: bounds.fold_with(this), - }) - } - ty::TyTuple(ref ts) => { - ty::TyTuple(ts.fold_with(this)) - } - ty::TyBareFn(opt_def_id, ref f) => { - let bfn = f.fold_with(this); - ty::TyBareFn(opt_def_id, this.tcx().mk_bare_fn(bfn)) - } - ty::TyRef(r, ref tm) => { - let r = r.fold_with(this); - ty::TyRef(this.tcx().mk_region(r), tm.fold_with(this)) - } - ty::TyStruct(did, ref substs) => { - let substs = substs.fold_with(this); - ty::TyStruct(did, this.tcx().mk_substs(substs)) - } - ty::TyClosure(did, ref substs) => { - let s = substs.fold_with(this); - ty::TyClosure(did, s) - } - ty::TyProjection(ref data) => { - ty::TyProjection(data.fold_with(this)) - } - ty::TyBool | ty::TyChar | ty::TyStr | - ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | - ty::TyError | ty::TyInfer(_) | - ty::TyParam(..) => { - ty.sty.clone() - } - }; - this.tcx().mk_ty(sty) -} - -pub fn super_fold_substs<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - substs: &subst::Substs<'tcx>) - -> subst::Substs<'tcx> { - let regions = match substs.regions { - subst::ErasedRegions => { - subst::ErasedRegions - } - subst::NonerasedRegions(ref regions) => { - subst::NonerasedRegions(regions.fold_with(this)) - } - }; - - subst::Substs { regions: regions, - types: substs.types.fold_with(this) } -} - -pub fn super_fold_fn_sig<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - sig: &ty::FnSig<'tcx>) - -> ty::FnSig<'tcx> -{ - ty::FnSig { inputs: sig.inputs.fold_with(this), - output: sig.output.fold_with(this), - variadic: sig.variadic } -} - -pub fn super_fold_output<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - output: &ty::FnOutput<'tcx>) - -> ty::FnOutput<'tcx> { - match *output { - ty::FnConverging(ref ty) => ty::FnConverging(ty.fold_with(this)), - ty::FnDiverging => ty::FnDiverging - } -} - -pub fn super_fold_bare_fn_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - fty: &ty::BareFnTy<'tcx>) - -> ty::BareFnTy<'tcx> -{ - ty::BareFnTy { sig: fty.sig.fold_with(this), - abi: fty.abi, - unsafety: fty.unsafety } -} - -pub fn super_fold_closure_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - fty: &ty::ClosureTy<'tcx>) - -> ty::ClosureTy<'tcx> -{ - ty::ClosureTy { - sig: fty.sig.fold_with(this), - unsafety: fty.unsafety, - abi: fty.abi, - } -} - -pub fn super_fold_trait_ref<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - t: &ty::TraitRef<'tcx>) - -> ty::TraitRef<'tcx> -{ - let substs = t.substs.fold_with(this); - ty::TraitRef { - def_id: t.def_id, - substs: this.tcx().mk_substs(substs), - } -} - -pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - mt: &ty::TypeAndMut<'tcx>) - -> ty::TypeAndMut<'tcx> { - ty::TypeAndMut {ty: mt.ty.fold_with(this), - mutbl: mt.mutbl} -} - -pub fn super_fold_existential_bounds<'tcx, T: TypeFolder<'tcx>>( - this: &mut T, - bounds: &ty::ExistentialBounds<'tcx>) - -> ty::ExistentialBounds<'tcx> -{ - ty::ExistentialBounds { - region_bound: bounds.region_bound.fold_with(this), - builtin_bounds: bounds.builtin_bounds, - projection_bounds: bounds.projection_bounds.fold_with(this), - } -} +pub trait TypeVisitor<'tcx> : Sized { + fn enter_region_binder(&mut self) { } + fn exit_region_binder(&mut self) { } -pub fn super_fold_autoref<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - autoref: &adjustment::AutoRef<'tcx>) - -> adjustment::AutoRef<'tcx> -{ - match *autoref { - adjustment::AutoPtr(r, m) => { - let r = r.fold_with(this); - adjustment::AutoPtr(this.tcx().mk_region(r), m) - } - adjustment::AutoUnsafe(m) => adjustment::AutoUnsafe(m) + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + t.visit_subitems_with(self) } -} -pub fn super_fold_item_substs<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - substs: ty::ItemSubsts<'tcx>) - -> ty::ItemSubsts<'tcx> -{ - ty::ItemSubsts { - substs: substs.substs.fold_with(this), + fn visit_region(&mut self, r: ty::Region) -> bool { + r.visit_subitems_with(self) } } @@ -333,7 +172,7 @@ impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - let t1 = super_fold_ty(self, ty); + let t1 = ty.fold_subitems_with(self); (self.fldop)(t1) } } @@ -495,7 +334,7 @@ impl<'tcx> ty::ctxt<'tcx> { } pub fn no_late_bound_regions(&self, value: &Binder) -> Option - where T : TypeFoldable<'tcx> + RegionEscape + where T : TypeFoldable<'tcx> { if value.0.has_escaping_regions() { None @@ -561,7 +400,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> return t; } - super_fold_ty(self, t) + t.fold_subitems_with(self) } fn fold_region(&mut self, r: ty::Region) -> ty::Region { @@ -612,7 +451,7 @@ impl<'tcx> ty::ctxt<'tcx> { Some(u) => return u } - let t_norm = ty::fold::super_fold_ty(self, ty); + let t_norm = ty.fold_subitems_with(self); self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm); return t_norm; } @@ -621,7 +460,7 @@ impl<'tcx> ty::ctxt<'tcx> { where T : TypeFoldable<'tcx> { let u = self.tcx().anonymize_late_bound_regions(t); - ty::fold::super_fold_binder(self, &u) + u.fold_subitems_with(self) } fn fold_region(&mut self, r: ty::Region) -> ty::Region { @@ -678,3 +517,65 @@ pub fn shift_regions<'tcx, T:TypeFoldable<'tcx>>(tcx: &ty::ctxt<'tcx>, shift_region(region, amount) })) } + +impl<'tcx, T: TypeFoldable<'tcx>> RegionEscape for T { + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + struct RegionEscapeVisitor { + depth: u32, + } + + impl<'tcx> TypeVisitor<'tcx> for RegionEscapeVisitor { + fn enter_region_binder(&mut self) { + self.depth += 1; + } + + fn exit_region_binder(&mut self) { + self.depth -= 1; + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + t.region_depth > self.depth + } + + fn visit_region(&mut self, r: ty::Region) -> bool { + r.escapes_depth(self.depth) + } + } + + self.visit_with(&mut RegionEscapeVisitor { depth: depth }) + } +} + +impl<'tcx, T: TypeFoldable<'tcx>> HasTypeFlags for T { + fn has_type_flags(&self, flags: ty::TypeFlags) -> bool { + struct HasTypeFlagsVisitor { + flags: ty::TypeFlags, + } + + impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { + fn visit_ty(&mut self, t: Ty) -> bool { + t.flags.get().intersects(self.flags) + } + + fn visit_region(&mut self, r: ty::Region) -> bool { + if self.flags.intersects(ty::TypeFlags::HAS_LOCAL_NAMES) { + // does this represent a region that cannot be named + // in a global way? used in fulfillment caching. + match r { + ty::ReStatic | ty::ReEmpty => {} + _ => return true, + } + } + if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER) { + match r { + ty::ReVar(_) | ty::ReSkolemized(..) => { return true } + _ => {} + } + } + false + } + } + + self.visit_with(&mut HasTypeFlagsVisitor { flags: flags }) + } +} diff --git a/src/librustc/middle/ty/relate.rs b/src/librustc/middle/ty/relate.rs index ff0a9789cf1f8..137f60572bb45 100644 --- a/src/librustc/middle/ty/relate.rs +++ b/src/librustc/middle/ty/relate.rs @@ -15,7 +15,7 @@ use middle::def_id::DefId; use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs}; -use middle::ty::{self, HasTypeFlags, Ty}; +use middle::ty::{self, Ty}; use middle::ty::error::{ExpectedFound, TypeError}; use middle::ty::fold::TypeFoldable; use std::rc::Rc; @@ -80,7 +80,7 @@ pub trait TypeRelation<'a,'tcx> : Sized { where T: Relate<'a,'tcx>; } -pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> + HasTypeFlags { +pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> { fn relate>(relation: &mut R, a: &Self, b: &Self) diff --git a/src/librustc/middle/ty/structural_impls.rs b/src/librustc/middle/ty/structural_impls.rs index ecb2b85fd7744..8d3a93e72f542 100644 --- a/src/librustc/middle/ty/structural_impls.rs +++ b/src/librustc/middle/ty/structural_impls.rs @@ -11,8 +11,8 @@ use middle::subst::{self, VecPerParamSpace}; use middle::traits; use middle::ty::{self, TraitRef, Ty, TypeAndMut}; -use middle::ty::{HasTypeFlags, Lift, TypeFlags, RegionEscape}; -use middle::ty::fold::{TypeFoldable, TypeFolder}; +use middle::ty::Lift; +use middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use std::rc::Rc; use syntax::abi; @@ -20,390 +20,6 @@ use syntax::ptr::P; use rustc_front::hir; -// FIXME(#20298) -- all of these traits basically walk various -// structures to test whether types/regions are reachable with various -// properties. It should be possible to express them in terms of one -// common "walker" trait or something. - -impl<'tcx> RegionEscape for Ty<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.region_depth > depth - } -} - -impl<'tcx> RegionEscape for ty::TraitTy<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.principal.has_regions_escaping_depth(depth) || - self.bounds.has_regions_escaping_depth(depth) - } -} - -impl<'tcx> RegionEscape for ty::ExistentialBounds<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.region_bound.has_regions_escaping_depth(depth) || - self.projection_bounds.has_regions_escaping_depth(depth) - } -} - -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) || - self.regions.has_regions_escaping_depth(depth) - } -} - -impl<'tcx> RegionEscape for ty::ClosureSubsts<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.func_substs.has_regions_escaping_depth(depth) || - self.upvar_tys.iter().any(|t| t.has_regions_escaping_depth(depth)) - } -} - -impl RegionEscape for Vec { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.iter().any(|t| t.has_regions_escaping_depth(depth)) - } -} - -impl<'tcx> RegionEscape for ty::FnSig<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.inputs.has_regions_escaping_depth(depth) || - self.output.has_regions_escaping_depth(depth) - } -} - -impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.iter_enumerated().any(|(space, _, t)| { - if space == subst::FnSpace { - t.has_regions_escaping_depth(depth+1) - } else { - t.has_regions_escaping_depth(depth) - } - }) - } -} - -impl<'tcx> RegionEscape for ty::TypeScheme<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.ty.has_regions_escaping_depth(depth) - } -} - -impl RegionEscape for ty::Region { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.escapes_depth(depth) - } -} - -impl<'tcx> RegionEscape for ty::GenericPredicates<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.predicates.has_regions_escaping_depth(depth) - } -} - -impl<'tcx> RegionEscape for ty::Predicate<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - match *self { - ty::Predicate::Trait(ref data) => data.has_regions_escaping_depth(depth), - ty::Predicate::Equate(ref data) => data.has_regions_escaping_depth(depth), - ty::Predicate::RegionOutlives(ref data) => data.has_regions_escaping_depth(depth), - ty::Predicate::TypeOutlives(ref data) => data.has_regions_escaping_depth(depth), - ty::Predicate::Projection(ref data) => data.has_regions_escaping_depth(depth), - ty::Predicate::WellFormed(ty) => ty.has_regions_escaping_depth(depth), - ty::Predicate::ObjectSafe(_trait_def_id) => false, - } - } -} - -impl<'tcx> RegionEscape for TraitRef<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.substs.types.iter().any(|t| t.has_regions_escaping_depth(depth)) || - self.substs.regions.has_regions_escaping_depth(depth) - } -} - -impl<'tcx> RegionEscape for subst::RegionSubsts { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - match *self { - subst::ErasedRegions => false, - subst::NonerasedRegions(ref r) => { - r.iter().any(|t| t.has_regions_escaping_depth(depth)) - } - } - } -} - -impl<'tcx,T:RegionEscape> RegionEscape for ty::Binder { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.0.has_regions_escaping_depth(depth + 1) - } -} - -impl<'tcx> RegionEscape for ty::FnOutput<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - match *self { - ty::FnConverging(t) => t.has_regions_escaping_depth(depth), - ty::FnDiverging => false - } - } -} - -impl<'tcx> RegionEscape for ty::EquatePredicate<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth) - } -} - -impl<'tcx> RegionEscape for ty::TraitPredicate<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.trait_ref.has_regions_escaping_depth(depth) - } -} - -impl RegionEscape for ty::OutlivesPredicate { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.0.has_regions_escaping_depth(depth) || self.1.has_regions_escaping_depth(depth) - } -} - -impl<'tcx> RegionEscape for ty::ProjectionPredicate<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - self.projection_ty.has_regions_escaping_depth(depth) || - self.ty.has_regions_escaping_depth(depth) - } -} - -impl<'tcx> RegionEscape for ty::ProjectionTy<'tcx> { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - 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) - } -} - -impl<'tcx,T:HasTypeFlags> HasTypeFlags for [T] { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.iter().any(|p| p.has_type_flags(flags)) - } -} - -impl<'tcx,T:HasTypeFlags> HasTypeFlags for VecPerParamSpace { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.iter().any(|p| p.has_type_flags(flags)) - } -} - -impl HasTypeFlags for abi::Abi { - fn has_type_flags(&self, _flags: TypeFlags) -> bool { - false - } -} - -impl HasTypeFlags for hir::Unsafety { - fn has_type_flags(&self, _flags: TypeFlags) -> bool { - false - } -} - -impl HasTypeFlags for ty::BuiltinBounds { - fn has_type_flags(&self, _flags: TypeFlags) -> bool { - false - } -} - -impl<'tcx> HasTypeFlags for ty::ClosureTy<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.sig.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::ClosureUpvar<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.ty.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::ExistentialBounds<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.projection_bounds.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.predicates.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::Predicate<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - match *self { - ty::Predicate::Trait(ref data) => data.has_type_flags(flags), - ty::Predicate::Equate(ref data) => data.has_type_flags(flags), - ty::Predicate::RegionOutlives(ref data) => data.has_type_flags(flags), - ty::Predicate::TypeOutlives(ref data) => data.has_type_flags(flags), - ty::Predicate::Projection(ref data) => data.has_type_flags(flags), - ty::Predicate::WellFormed(data) => data.has_type_flags(flags), - ty::Predicate::ObjectSafe(_trait_def_id) => false, - } - } -} - -impl<'tcx> HasTypeFlags for ty::TraitPredicate<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.trait_ref.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::EquatePredicate<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.0.has_type_flags(flags) || self.1.has_type_flags(flags) - } -} - -impl HasTypeFlags for ty::Region { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - if flags.intersects(TypeFlags::HAS_LOCAL_NAMES) { - // does this represent a region that cannot be named in a global - // way? used in fulfillment caching. - match *self { - ty::ReStatic | ty::ReEmpty => {} - _ => return true - } - } - if flags.intersects(TypeFlags::HAS_RE_INFER) { - match *self { - ty::ReVar(_) | ty::ReSkolemized(..) => { return true } - _ => {} - } - } - false - } -} - -impl HasTypeFlags for ty::OutlivesPredicate { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.0.has_type_flags(flags) || self.1.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::ProjectionPredicate<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.projection_ty.has_type_flags(flags) || self.ty.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::ProjectionTy<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.trait_ref.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for Ty<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.flags.get().intersects(flags) - } -} - -impl<'tcx> HasTypeFlags for TypeAndMut<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.ty.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for TraitRef<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.substs.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for subst::Substs<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.types.has_type_flags(flags) || match self.regions { - subst::ErasedRegions => false, - subst::NonerasedRegions(ref r) => r.has_type_flags(flags) - } - } -} - -impl<'tcx,T> HasTypeFlags for Option - where T : HasTypeFlags -{ - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.iter().any(|t| t.has_type_flags(flags)) - } -} - -impl<'tcx,T> HasTypeFlags for Rc - where T : HasTypeFlags -{ - fn has_type_flags(&self, flags: TypeFlags) -> bool { - (**self).has_type_flags(flags) - } -} - -impl<'tcx,T> HasTypeFlags for Box - where T : HasTypeFlags -{ - fn has_type_flags(&self, flags: TypeFlags) -> bool { - (**self).has_type_flags(flags) - } -} - -impl HasTypeFlags for ty::Binder - where T : HasTypeFlags -{ - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.0.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::FnOutput<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - match *self { - ty::FnConverging(t) => t.has_type_flags(flags), - ty::FnDiverging => false, - } - } -} - -impl<'tcx> HasTypeFlags for ty::FnSig<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.inputs.iter().any(|t| t.has_type_flags(flags)) || - self.output.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::BareFnTy<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.sig.has_type_flags(flags) - } -} - -impl<'tcx> HasTypeFlags for ty::ClosureSubsts<'tcx> { - fn has_type_flags(&self, flags: TypeFlags) -> bool { - self.func_substs.has_type_flags(flags) || - self.upvar_tys.iter().any(|t| t.has_type_flags(flags)) - } -} - /////////////////////////////////////////////////////////////////////////// // Lift implementations @@ -511,6 +127,10 @@ macro_rules! CopyImpls { fn fold_with>(&self, _: &mut F) -> $ty { *self } + + fn visit_with>(&self, _: &mut F) -> bool { + false + } } )+ } @@ -522,18 +142,30 @@ impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T fn fold_with>(&self, folder: &mut F) -> (T, U) { (self.0.fold_with(folder), self.1.fold_with(folder)) } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.0.visit_with(visitor) || self.1.visit_with(visitor) + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option { fn fold_with>(&self, folder: &mut F) -> Option { self.as_ref().map(|t| t.fold_with(folder)) } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.iter().any(|t| t.visit_with(visitor)) + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { fn fold_with>(&self, folder: &mut F) -> Rc { Rc::new((**self).fold_with(folder)) } + + fn visit_with>(&self, visitor: &mut V) -> bool { + (**self).visit_with(visitor) + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { @@ -541,24 +173,50 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { let content: T = (**self).fold_with(folder); box content } + + fn visit_with>(&self, visitor: &mut V) -> bool { + (**self).visit_with(visitor) + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { fn fold_with>(&self, folder: &mut F) -> Vec { self.iter().map(|t| t.fold_with(folder)).collect() } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.iter().any(|t| t.visit_with(visitor)) + } } impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { fn fold_with>(&self, folder: &mut F) -> ty::Binder { folder.fold_binder(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + folder.enter_region_binder(); + let result = ty::Binder(self.0.fold_with(folder)); + folder.exit_region_binder(); + result + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + visitor.enter_region_binder(); + if self.0.visit_with(visitor) { return true } + visitor.exit_region_binder(); + false + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for P<[T]> { fn fold_with>(&self, folder: &mut F) -> P<[T]> { self.iter().map(|t| t.fold_with(folder)).collect() } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.iter().any(|t| t.visit_with(visitor)) + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace { @@ -582,60 +240,244 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace { } result } + + fn visit_with>(&self, visitor: &mut V) -> bool { + let mut entered_region_binder = false; + let result = self.iter_enumerated().any(|(space, index, t)| { + if space == subst::FnSpace && index == 0 { + visitor.enter_region_binder(); + entered_region_binder = true; + } + t.visit_with(visitor) + }); + if entered_region_binder { + visitor.exit_region_binder(); + } + result + } +} + +impl<'tcx> TypeFoldable<'tcx> for ty::TraitTy<'tcx> { + fn fold_with>(&self, folder: &mut F) -> Self { + ty::TraitTy { + principal: self.principal.fold_with(folder), + bounds: self.bounds.fold_with(folder), + } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.principal.visit_with(visitor) || self.bounds.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn fold_with>(&self, folder: &mut F) -> Ty<'tcx> { folder.fold_ty(*self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + let sty = match self.sty { + ty::TyBox(typ) => ty::TyBox(typ.fold_with(folder)), + ty::TyRawPtr(ref tm) => ty::TyRawPtr(tm.fold_with(folder)), + ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz), + ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)), + ty::TyEnum(tid, ref substs) => { + let substs = substs.fold_with(folder); + ty::TyEnum(tid, folder.tcx().mk_substs(substs)) + } + ty::TyTrait(ref trait_ty) => ty::TyTrait(trait_ty.fold_with(folder)), + ty::TyTuple(ref ts) => ty::TyTuple(ts.fold_with(folder)), + ty::TyBareFn(opt_def_id, ref f) => { + let bfn = f.fold_with(folder); + ty::TyBareFn(opt_def_id, folder.tcx().mk_bare_fn(bfn)) + } + ty::TyRef(r, ref tm) => { + let r = r.fold_with(folder); + ty::TyRef(folder.tcx().mk_region(r), tm.fold_with(folder)) + } + ty::TyStruct(did, ref substs) => { + let substs = substs.fold_with(folder); + ty::TyStruct(did, folder.tcx().mk_substs(substs)) + } + ty::TyClosure(did, ref substs) => { + ty::TyClosure(did, substs.fold_with(folder)) + } + ty::TyProjection(ref data) => ty::TyProjection(data.fold_with(folder)), + ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | + ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | + ty::TyParam(..) => self.sty.clone(), + }; + folder.tcx().mk_ty(sty) + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + visitor.visit_ty(self) + } + + fn visit_subitems_with>(&self, visitor: &mut V) -> bool { + match self.sty { + ty::TyBox(typ) => typ.visit_with(visitor), + ty::TyRawPtr(ref tm) => tm.visit_with(visitor), + ty::TyArray(typ, _sz) => typ.visit_with(visitor), + ty::TySlice(typ) => typ.visit_with(visitor), + ty::TyEnum(_tid, ref substs) => substs.visit_with(visitor), + ty::TyTrait(ref trait_ty) => trait_ty.visit_with(visitor), + ty::TyTuple(ref ts) => ts.visit_with(visitor), + ty::TyBareFn(_opt_def_id, ref f) => f.visit_with(visitor), + ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor), + ty::TyStruct(_did, ref substs) => substs.visit_with(visitor), + ty::TyClosure(_did, ref substs) => substs.visit_with(visitor), + ty::TyProjection(ref data) => data.visit_with(visitor), + ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | + ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | + ty::TyParam(..) => false, + } + } } impl<'tcx> TypeFoldable<'tcx> for ty::BareFnTy<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::BareFnTy<'tcx> { folder.fold_bare_fn_ty(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + ty::BareFnTy { sig: self.sig.fold_with(folder), + abi: self.abi, + unsafety: self.unsafety } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.sig.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::ClosureTy<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::ClosureTy<'tcx> { folder.fold_closure_ty(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + ty::ClosureTy { + sig: self.sig.fold_with(folder), + unsafety: self.unsafety, + abi: self.abi, + } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.sig.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::TypeAndMut<'tcx> { folder.fold_mt(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.ty.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::FnOutput<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::FnOutput<'tcx> { folder.fold_output(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + match *self { + ty::FnConverging(ref ty) => ty::FnConverging(ty.fold_with(folder)), + ty::FnDiverging => ty::FnDiverging + } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + match *self { + ty::FnConverging(ref ty) => ty.visit_with(visitor), + ty::FnDiverging => false, + } + } } impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::FnSig<'tcx> { folder.fold_fn_sig(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + ty::FnSig { inputs: self.inputs.fold_with(folder), + output: self.output.fold_with(folder), + variadic: self.variadic } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.inputs.visit_with(visitor) || self.output.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::TraitRef<'tcx> { folder.fold_trait_ref(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + let substs = self.substs.fold_with(folder); + ty::TraitRef { + def_id: self.def_id, + substs: folder.tcx().mk_substs(substs), + } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.substs.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::Region { fn fold_with>(&self, folder: &mut F) -> ty::Region { folder.fold_region(*self) } + + fn fold_subitems_with>(&self, _folder: &mut F) -> Self { + *self + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + visitor.visit_region(*self) + } + + fn visit_subitems_with>(&self, _visitor: &mut V) -> bool { + false + } } impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> { fn fold_with>(&self, folder: &mut F) -> subst::Substs<'tcx> { folder.fold_substs(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + let regions = match self.regions { + subst::ErasedRegions => subst::ErasedRegions, + subst::NonerasedRegions(ref regions) => { + subst::NonerasedRegions(regions.fold_with(folder)) + } + }; + + subst::Substs { regions: regions, + types: self.types.fold_with(folder) } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.types.visit_with(visitor) || match self.regions { + subst::ErasedRegions => false, + subst::NonerasedRegions(ref regions) => regions.visit_with(visitor), + } + } } impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { @@ -646,6 +488,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { upvar_tys: self.upvar_tys.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.func_substs.visit_with(visitor) || self.upvar_tys.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> { @@ -654,24 +500,61 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> { substs: self.substs.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.substs.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoRef<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::adjustment::AutoRef<'tcx> { folder.fold_autoref(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + match *self { + ty::adjustment::AutoPtr(r, m) => { + let r = r.fold_with(folder); + ty::adjustment::AutoPtr(folder.tcx().mk_region(r), m) + } + ty::adjustment::AutoUnsafe(m) => ty::adjustment::AutoUnsafe(m) + } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + match *self { + ty::adjustment::AutoPtr(r, _m) => r.visit_with(visitor), + ty::adjustment::AutoUnsafe(_m) => false, + } + } } impl<'tcx> TypeFoldable<'tcx> for ty::BuiltinBounds { fn fold_with>(&self, _folder: &mut F) -> ty::BuiltinBounds { *self } + + fn visit_with>(&self, _visitor: &mut V) -> bool { + false + } } impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialBounds<'tcx> { fn fold_with>(&self, folder: &mut F) -> ty::ExistentialBounds<'tcx> { folder.fold_existential_bounds(self) } + + fn fold_subitems_with>(&self, folder: &mut F) -> Self { + ty::ExistentialBounds { + region_bound: self.region_bound.fold_with(folder), + builtin_bounds: self.builtin_bounds, + projection_bounds: self.projection_bounds.fold_with(folder), + } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.region_bound.visit_with(visitor) || self.projection_bounds.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { @@ -686,6 +569,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { object_lifetime_default: self.object_lifetime_default.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.default.visit_with(visitor) || + self.object_lifetime_default.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault { @@ -701,6 +589,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault { ty::ObjectLifetimeDefault::Specific(r.fold_with(folder)), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + match *self { + ty::ObjectLifetimeDefault::Specific(r) => r.visit_with(visitor), + _ => false, + } + } } impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef { @@ -713,6 +608,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef { bounds: self.bounds.fold_with(folder) } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.bounds.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> { @@ -722,6 +621,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> { regions: self.regions.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.types.visit_with(visitor) || self.regions.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> { @@ -730,6 +633,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> { predicates: self.predicates.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.predicates.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { @@ -751,6 +658,18 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { ty::Predicate::ObjectSafe(trait_def_id), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + match *self { + ty::Predicate::Trait(ref a) => a.visit_with(visitor), + ty::Predicate::Equate(ref binder) => binder.visit_with(visitor), + ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor), + ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor), + ty::Predicate::Projection(ref binder) => binder.visit_with(visitor), + ty::Predicate::WellFormed(data) => data.visit_with(visitor), + ty::Predicate::ObjectSafe(_trait_def_id) => false, + } + } } impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> { @@ -760,6 +679,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> { ty: self.ty.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.projection_ty.visit_with(visitor) || self.ty.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> { @@ -769,6 +692,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> { item_name: self.item_name, } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.trait_ref.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> { @@ -777,6 +704,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> { predicates: self.predicates.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.predicates.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> { @@ -784,6 +715,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> { ty::EquatePredicate(self.0.fold_with(folder), self.1.fold_with(folder)) } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.0.visit_with(visitor) || self.1.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> { @@ -792,6 +727,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> { trait_ref: self.trait_ref.fold_with(folder) } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.trait_ref.visit_with(visitor) + } } impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate @@ -802,6 +741,10 @@ impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate ty::OutlivesPredicate(self.0.fold_with(folder), self.1.fold_with(folder)) } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.0.visit_with(visitor) || self.1.visit_with(visitor) + } } impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { @@ -812,6 +755,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { ty: self.ty.fold_with(folder), } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.ty.visit_with(visitor) + } } impl<'a, 'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'a, 'tcx> where 'tcx: 'a { @@ -826,4 +773,23 @@ impl<'a, 'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'a, 'tcx> where ' free_id_outlive: self.free_id_outlive, } } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.free_substs.visit_with(visitor) || + self.implicit_region_bound.visit_with(visitor) || + self.caller_bounds.visit_with(visitor) + } +} + +impl<'tcx> TypeFoldable<'tcx> for ty::TypeScheme<'tcx> { + fn fold_with>(&self, folder: &mut F) -> Self { + ty::TypeScheme { + generics: self.generics.fold_with(folder), + ty: self.ty.fold_with(folder), + } + } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.generics.visit_with(visitor) || self.ty.visit_with(visitor) + } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 11d3068f065b7..423cd62a13f81 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -256,6 +256,10 @@ impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> { -> TraitAndProjections<'tcx> { TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder)) } + + fn visit_with>(&self, visitor: &mut V) -> bool { + self.0.visit_with(visitor) || self.1.visit_with(visitor) + } } impl<'tcx> fmt::Display for TraitAndProjections<'tcx> { diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 964e981aec093..31b5839bd2167 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -469,7 +469,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> { } pub fn monomorphize(&self, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { monomorphize::apply_param_substs(self.ccx.tcx(), self.param_substs, @@ -650,7 +650,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { } pub fn monomorphize(&self, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { monomorphize::apply_param_substs(self.tcx(), self.fcx.param_substs, diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 80a86bac26b9a..0eaab6b3dbb98 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -299,7 +299,7 @@ pub fn apply_param_substs<'tcx,T>(tcx: &ty::ctxt<'tcx>, param_substs: &Substs<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { let substituted = value.subst(tcx, param_substs); normalize_associated_type(tcx, &substituted) diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs index 8dc95562e44af..91916efa88277 100644 --- a/src/librustc_typeck/check/assoc.rs +++ b/src/librustc_typeck/check/assoc.rs @@ -11,7 +11,6 @@ use middle::infer::InferCtxt; use middle::traits::{self, FulfillmentContext, Normalized, MiscObligation, SelectionContext, ObligationCause}; -use middle::ty::HasTypeFlags; use middle::ty::fold::TypeFoldable; use syntax::ast; use syntax::codemap::Span; @@ -23,7 +22,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, body_id: ast::NodeId, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { debug!("normalize_associated_types_in(value={:?})", value); let mut selcx = SelectionContext::new(infcx); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 14adc84f701f8..f99124664bbcd 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -318,7 +318,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { body_id: ast::NodeId, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { let mut fulfillment_cx = self.infcx.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, @@ -1334,7 +1334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { substs: &Substs<'tcx>, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { let value = value.subst(self.tcx(), substs); let result = self.normalize_associated_types_in(span, &value); @@ -1360,7 +1360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn normalize_associated_types_in(&self, span: Span, value: &T) -> T - where T : TypeFoldable<'tcx> + HasTypeFlags + where T : TypeFoldable<'tcx> { self.inh.normalize_associated_types_in(span, self.body_id, value) } From 76021d84b30b1b49fecab8e263cedb7a71f9d393 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 18 Dec 2015 10:07:06 +0000 Subject: [PATCH 2/3] Refactor away extension traits RegionEscape and HasTypeFlags --- src/librustc/middle/implicator.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 6 +- src/librustc/middle/infer/freshen.rs | 3 +- .../middle/infer/higher_ranked/mod.rs | 5 +- src/librustc/middle/infer/mod.rs | 2 +- src/librustc/middle/infer/resolve.rs | 3 +- src/librustc/middle/intrinsicck.rs | 2 +- src/librustc/middle/subst.rs | 2 +- src/librustc/middle/traits/error_reporting.rs | 3 +- src/librustc/middle/traits/fulfill.rs | 2 +- src/librustc/middle/traits/mod.rs | 3 +- src/librustc/middle/traits/object_safety.rs | 2 +- src/librustc/middle/traits/project.rs | 2 +- src/librustc/middle/traits/select.rs | 3 +- src/librustc/middle/ty/adjustment.rs | 3 +- src/librustc/middle/ty/flags.rs | 2 +- src/librustc/middle/ty/fold.rs | 155 ++++++++++++------ src/librustc/middle/ty/mod.rs | 71 +------- src/librustc/middle/ty/outlives.rs | 2 +- src/librustc/middle/ty/relate.rs | 3 +- src/librustc/middle/ty/structural_impls.rs | 3 +- src/librustc/middle/ty/sty.rs | 3 +- src/librustc/middle/ty/util.rs | 3 +- src/librustc/middle/ty/wf.rs | 2 +- src/librustc/util/ppaux.rs | 3 +- src/librustc_driver/test.rs | 2 +- src/librustc_metadata/decoder.rs | 2 +- src/librustc_metadata/tydecode.rs | 2 +- src/librustc_trans/trans/base.rs | 2 +- src/librustc_trans/trans/callee.rs | 2 +- src/librustc_trans/trans/common.rs | 2 +- src/librustc_trans/trans/intrinsic.rs | 2 +- src/librustc_trans/trans/meth.rs | 2 +- src/librustc_trans/trans/mir/constant.rs | 2 +- src/librustc_trans/trans/mir/did.rs | 2 +- src/librustc_trans/trans/mir/lvalue.rs | 2 +- src/librustc_trans/trans/mir/operand.rs | 2 +- src/librustc_trans/trans/monomorphize.rs | 2 +- src/librustc_trans/trans/type_of.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 4 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/check/op.rs | 2 +- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/check/writeback.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 3 +- src/librustc_typeck/lib.rs | 2 +- 51 files changed, 159 insertions(+), 186 deletions(-) diff --git a/src/librustc/middle/implicator.rs b/src/librustc/middle/implicator.rs index a16e1c4833086..d25084bbdffb5 100644 --- a/src/librustc/middle/implicator.rs +++ b/src/librustc/middle/implicator.rs @@ -14,7 +14,7 @@ use middle::def_id::DefId; use middle::infer::{InferCtxt, GenericKind}; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, RegionEscape, ToPredicate, Ty}; +use middle::ty::{self, ToPredicate, Ty}; use middle::ty::fold::{TypeFoldable, TypeFolder}; use syntax::ast; diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index d628227d5e63c..f390d85a28d66 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -82,7 +82,7 @@ use middle::def_id::DefId; use middle::infer::{self, TypeOrigin}; use middle::region; use middle::subst; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use middle::ty::{Region, ReFree}; use middle::ty::error::TypeError; @@ -250,7 +250,7 @@ pub trait ErrorReporting<'tcx> { fn values_str(&self, values: &ValuePairs<'tcx>) -> Option; - fn expected_found_str + HasTypeFlags>( + fn expected_found_str + TypeFoldable<'tcx>>( &self, exp_found: &ty::error::ExpectedFound) -> Option; @@ -575,7 +575,7 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { } } - fn expected_found_str + HasTypeFlags>( + fn expected_found_str + TypeFoldable<'tcx>>( &self, exp_found: &ty::error::ExpectedFound) -> Option diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs index 7202c0a8052ed..8b53a1520b316 100644 --- a/src/librustc/middle/infer/freshen.rs +++ b/src/librustc/middle/infer/freshen.rs @@ -30,8 +30,7 @@ //! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type //! inferencer knows "so far". -use middle::ty::{self, Ty, HasTypeFlags}; -use middle::ty::fold::TypeFoldable; +use middle::ty::{self, Ty, TypeFoldable}; use middle::ty::fold::TypeFolder; use std::collections::hash_map::{self, Entry}; diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index ef6d9ae41914b..e8f542db933cb 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -14,9 +14,8 @@ use super::{CombinedSnapshot, InferCtxt, HigherRankedType, SkolemizationMap}; use super::combine::CombineFields; -use middle::ty::{self, Binder}; +use middle::ty::{self, Binder, TypeFoldable}; use middle::ty::error::TypeError; -use middle::ty::fold::TypeFoldable; use middle::ty::relate::{Relate, RelateResult, TypeRelation}; use syntax::codemap::Span; use util::nodemap::{FnvHashMap, FnvHashSet}; @@ -557,7 +556,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, snapshot: &CombinedSnapshot, value: &T) -> T - where T : TypeFoldable<'tcx> + ty::HasTypeFlags + where T : TypeFoldable<'tcx> { debug_assert!(leak_check(infcx, &skol_map, snapshot).is_ok()); diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 941fb05c3d01d..922d4c251bb64 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -30,7 +30,7 @@ use middle::subst::Subst; use middle::traits; use middle::ty::adjustment; use middle::ty::{TyVid, IntVid, FloatVid}; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty}; use middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use middle::ty::fold::{TypeFolder, TypeFoldable}; use middle::ty::relate::{Relate, RelateResult, TypeRelation}; diff --git a/src/librustc/middle/infer/resolve.rs b/src/librustc/middle/infer/resolve.rs index d89036faef945..04c0cc2245db6 100644 --- a/src/librustc/middle/infer/resolve.rs +++ b/src/librustc/middle/infer/resolve.rs @@ -9,8 +9,7 @@ // except according to those terms. use super::{InferCtxt, FixupError, FixupResult}; -use middle::ty::{self, Ty, HasTypeFlags}; -use middle::ty::fold::{TypeFoldable}; +use middle::ty::{self, Ty, TypeFoldable}; /////////////////////////////////////////////////////////////////////////// // OPPORTUNISTIC TYPE RESOLVER diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index f1eed256dd156..69b952ca1f3fc 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -13,7 +13,7 @@ use middle::def::DefFn; use middle::def_id::DefId; use middle::subst::{Subst, Substs, EnumeratedItems}; use middle::ty::{TransmuteRestriction, ctxt, TyBareFn}; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use std::fmt; diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index d935b51813a5b..52a528f07a3b2 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -14,7 +14,7 @@ pub use self::ParamSpace::*; pub use self::RegionSubsts::*; use middle::cstore; -use middle::ty::{self, Ty, HasTypeFlags, RegionEscape}; +use middle::ty::{self, Ty}; use middle::ty::fold::{TypeFoldable, TypeFolder}; use serialize::{Encodable, Encoder, Decodable, Decoder}; diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 464b4dfb83bdd..883c5e7bb40eb 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -26,9 +26,8 @@ use super::{ use fmt_macros::{Parser, Piece, Position}; use middle::def_id::DefId; use middle::infer::InferCtxt; -use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty}; +use middle::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, Ty, TypeFoldable}; use middle::ty::fast_reject; -use middle::ty::fold::TypeFoldable; use util::nodemap::{FnvHashMap, FnvHashSet}; use std::cmp; diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index b93961f1aa9d2..4f8f6b846a6f4 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -9,7 +9,7 @@ // except according to those terms. use middle::infer::InferCtxt; -use middle::ty::{self, RegionEscape, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use syntax::ast; use util::common::ErrorReported; diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 01c2f56123501..6cf841cc47756 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -19,9 +19,8 @@ use dep_graph::DepNode; use middle::def_id::DefId; use middle::free_region::FreeRegionMap; use middle::subst; -use middle::ty::{self, HasTypeFlags, Ty}; +use middle::ty::{self, Ty, TypeFoldable}; use middle::ty::fast_reject; -use middle::ty::fold::TypeFoldable; use middle::infer::{self, fixup_err_to_string, InferCtxt}; use std::rc::Rc; diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index c8e34165b9021..0e4a42bd15134 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -23,7 +23,7 @@ use super::elaborate_predicates; use middle::def_id::DefId; use middle::subst::{self, SelfSpace, TypeSpace}; use middle::traits; -use middle::ty::{self, HasTypeFlags, ToPolyTraitRef, Ty}; +use middle::ty::{self, ToPolyTraitRef, Ty, TypeFoldable}; use std::rc::Rc; use syntax::ast; diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 9c317895c3665..5e7db57b43181 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -23,7 +23,7 @@ use super::util; use middle::infer::{self, TypeOrigin}; use middle::subst::Subst; -use middle::ty::{self, ToPredicate, RegionEscape, HasTypeFlags, ToPolyTraitRef, Ty}; +use middle::ty::{self, ToPredicate, ToPolyTraitRef, Ty}; use middle::ty::fold::{TypeFoldable, TypeFolder}; use syntax::parse::token; use util::common::FN_OUTPUT_NAME; diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index a31fccbb3f71e..f544f8ce36234 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -39,9 +39,8 @@ use middle::def_id::DefId; use middle::infer; use middle::infer::{InferCtxt, TypeFreshener, TypeOrigin}; use middle::subst::{Subst, Substs, TypeSpace}; -use middle::ty::{self, ToPredicate, RegionEscape, ToPolyTraitRef, Ty, HasTypeFlags}; +use middle::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TypeFoldable}; use middle::ty::fast_reject; -use middle::ty::fold::TypeFoldable; use middle::ty::relate::TypeRelation; use std::cell::RefCell; diff --git a/src/librustc/middle/ty/adjustment.rs b/src/librustc/middle/ty/adjustment.rs index c44ebcfdb693c..6cab0baa55325 100644 --- a/src/librustc/middle/ty/adjustment.rs +++ b/src/librustc/middle/ty/adjustment.rs @@ -11,8 +11,7 @@ pub use self::AutoAdjustment::*; pub use self::AutoRef::*; -use middle::ty::{self, Ty, TypeAndMut}; -use middle::ty::HasTypeFlags; +use middle::ty::{self, Ty, TypeAndMut, TypeFoldable}; use middle::ty::LvaluePreference::{NoPreference}; use syntax::ast; diff --git a/src/librustc/middle/ty/flags.rs b/src/librustc/middle/ty/flags.rs index 94a50e3cac7f7..a0b03fe8126dd 100644 --- a/src/librustc/middle/ty/flags.rs +++ b/src/librustc/middle/ty/flags.rs @@ -9,7 +9,7 @@ // except according to those terms. use middle::subst; -use middle::ty::{self, HasTypeFlags, Ty, TypeFlags}; +use middle::ty::{self, Ty, TypeFlags, TypeFoldable}; pub struct FlagComputation { pub flags: TypeFlags, diff --git a/src/librustc/middle/ty/fold.rs b/src/librustc/middle/ty/fold.rs index 8d68c1da7f84e..4701ed6193763 100644 --- a/src/librustc/middle/ty/fold.rs +++ b/src/librustc/middle/ty/fold.rs @@ -42,7 +42,7 @@ use middle::region; use middle::subst; use middle::ty::adjustment; -use middle::ty::{self, Binder, Ty, RegionEscape, HasTypeFlags}; +use middle::ty::{self, Binder, Ty, TypeFlags}; use std::fmt; use util::nodemap::{FnvHashMap, FnvHashSet}; @@ -59,6 +59,53 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn visit_subitems_with>(&self, visitor: &mut V) -> bool { self.visit_with(visitor) } + + fn has_regions_escaping_depth(&self, depth: u32) -> bool { + self.visit_with(&mut HasEscapingRegionsVisitor { depth: depth }) + } + fn has_escaping_regions(&self) -> bool { + self.has_regions_escaping_depth(0) + } + + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.visit_with(&mut HasTypeFlagsVisitor { flags: flags }) + } + fn has_projection_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PROJECTION) + } + fn references_error(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_ERR) + } + fn has_param_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_PARAMS) + } + fn has_self_ty(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_SELF) + } + fn has_infer_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INFER) + } + fn needs_infer(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER) + } + fn needs_subst(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_SUBST) + } + fn has_closure_types(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_TY_CLOSURE) + } + fn has_erasable_regions(&self) -> bool { + self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND | + TypeFlags::HAS_RE_INFER | + TypeFlags::HAS_FREE_REGIONS) + } + /// Indicates whether this value references only 'global' + /// types/lifetimes that are the same regardless of what fn we are + /// in. This is used for caching. Errs on the side of returning + /// false. + fn is_global(&self) -> bool { + !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES) + } } /// The TypeFolder trait defines the actual *folding*. There is a @@ -518,64 +565,74 @@ pub fn shift_regions<'tcx, T:TypeFoldable<'tcx>>(tcx: &ty::ctxt<'tcx>, })) } -impl<'tcx, T: TypeFoldable<'tcx>> RegionEscape for T { - fn has_regions_escaping_depth(&self, depth: u32) -> bool { - struct RegionEscapeVisitor { - depth: u32, - } - - impl<'tcx> TypeVisitor<'tcx> for RegionEscapeVisitor { - fn enter_region_binder(&mut self) { - self.depth += 1; - } +/// An "escaping region" is a bound region whose binder is not part of `t`. +/// +/// So, for example, consider a type like the following, which has two binders: +/// +/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope +/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope +/// +/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the +/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner +/// fn type*, that type has an escaping region: `'a`. +/// +/// Note that what I'm calling an "escaping region" is often just called a "free region". However, +/// we already use the term "free region". It refers to the regions that we use to represent bound +/// regions on a fn definition while we are typechecking its body. +/// +/// To clarify, conceptually there is no particular difference between an "escaping" region and a +/// "free" region. However, there is a big difference in practice. Basically, when "entering" a +/// binding level, one is generally required to do some sort of processing to a bound region, such +/// as replacing it with a fresh/skolemized region, or making an entry in the environment to +/// represent the scope to which it is attached, etc. An escaping region represents a bound region +/// for which this processing has not yet been done. +struct HasEscapingRegionsVisitor { + depth: u32, +} - fn exit_region_binder(&mut self) { - self.depth -= 1; - } +impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor { + fn enter_region_binder(&mut self) { + self.depth += 1; + } - fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - t.region_depth > self.depth - } + fn exit_region_binder(&mut self) { + self.depth -= 1; + } - fn visit_region(&mut self, r: ty::Region) -> bool { - r.escapes_depth(self.depth) - } - } + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + t.region_depth > self.depth + } - self.visit_with(&mut RegionEscapeVisitor { depth: depth }) + fn visit_region(&mut self, r: ty::Region) -> bool { + r.escapes_depth(self.depth) } } -impl<'tcx, T: TypeFoldable<'tcx>> HasTypeFlags for T { - fn has_type_flags(&self, flags: ty::TypeFlags) -> bool { - struct HasTypeFlagsVisitor { - flags: ty::TypeFlags, - } +struct HasTypeFlagsVisitor { + flags: ty::TypeFlags, +} - impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { - fn visit_ty(&mut self, t: Ty) -> bool { - t.flags.get().intersects(self.flags) - } +impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { + fn visit_ty(&mut self, t: Ty) -> bool { + t.flags.get().intersects(self.flags) + } - fn visit_region(&mut self, r: ty::Region) -> bool { - if self.flags.intersects(ty::TypeFlags::HAS_LOCAL_NAMES) { - // does this represent a region that cannot be named - // in a global way? used in fulfillment caching. - match r { - ty::ReStatic | ty::ReEmpty => {} - _ => return true, - } - } - if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER) { - match r { - ty::ReVar(_) | ty::ReSkolemized(..) => { return true } - _ => {} - } - } - false + fn visit_region(&mut self, r: ty::Region) -> bool { + if self.flags.intersects(ty::TypeFlags::HAS_LOCAL_NAMES) { + // does this represent a region that cannot be named + // in a global way? used in fulfillment caching. + match r { + ty::ReStatic | ty::ReEmpty => {} + _ => return true, } } - - self.visit_with(&mut HasTypeFlagsVisitor { flags: flags }) + if self.flags.intersects(ty::TypeFlags::HAS_RE_INFER) { + match r { + ty::ReVar(_) | ty::ReSkolemized(..) => { return true } + _ => {} + } + } + false } } diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index 2baf5c5145fcd..852d9d80a9148 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -17,6 +17,7 @@ pub use self::BorrowKind::*; pub use self::ImplOrTraitItem::*; pub use self::IntVarValue::*; pub use self::LvaluePreference::*; +pub use self::fold::TypeFoldable; use dep_graph::{self, DepNode}; use front::map as ast_map; @@ -2667,73 +2668,3 @@ impl<'tcx> ctxt<'tcx> { trait_ref.substs.clone().with_method(meth_tps, meth_regions) } } - -/// An "escaping region" is a bound region whose binder is not part of `t`. -/// -/// So, for example, consider a type like the following, which has two binders: -/// -/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize)) -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope -/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope -/// -/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the -/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner -/// fn type*, that type has an escaping region: `'a`. -/// -/// Note that what I'm calling an "escaping region" is often just called a "free region". However, -/// we already use the term "free region". It refers to the regions that we use to represent bound -/// regions on a fn definition while we are typechecking its body. -/// -/// To clarify, conceptually there is no particular difference between an "escaping" region and a -/// "free" region. However, there is a big difference in practice. Basically, when "entering" a -/// binding level, one is generally required to do some sort of processing to a bound region, such -/// as replacing it with a fresh/skolemized region, or making an entry in the environment to -/// represent the scope to which it is attached, etc. An escaping region represents a bound region -/// for which this processing has not yet been done. -pub trait RegionEscape { - fn has_escaping_regions(&self) -> bool { - self.has_regions_escaping_depth(0) - } - - fn has_regions_escaping_depth(&self, depth: u32) -> bool; -} - -pub trait HasTypeFlags { - fn has_type_flags(&self, flags: TypeFlags) -> bool; - fn has_projection_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PROJECTION) - } - fn references_error(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_ERR) - } - fn has_param_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_PARAMS) - } - fn has_self_ty(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_SELF) - } - fn has_infer_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_INFER) - } - fn needs_infer(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER) - } - fn needs_subst(&self) -> bool { - self.has_type_flags(TypeFlags::NEEDS_SUBST) - } - fn has_closure_types(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_CLOSURE) - } - fn has_erasable_regions(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_RE_EARLY_BOUND | - TypeFlags::HAS_RE_INFER | - TypeFlags::HAS_FREE_REGIONS) - } - /// Indicates whether this value references only 'global' - /// types/lifetimes that are the same regardless of what fn we are - /// in. This is used for caching. Errs on the side of returning - /// false. - fn is_global(&self) -> bool { - !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES) - } -} diff --git a/src/librustc/middle/ty/outlives.rs b/src/librustc/middle/ty/outlives.rs index 7752367febb19..fc20c1bcb85fe 100644 --- a/src/librustc/middle/ty/outlives.rs +++ b/src/librustc/middle/ty/outlives.rs @@ -13,7 +13,7 @@ // RFC for reference. use middle::infer::InferCtxt; -use middle::ty::{self, RegionEscape, Ty}; +use middle::ty::{self, Ty, TypeFoldable}; #[derive(Debug)] pub enum Component<'tcx> { diff --git a/src/librustc/middle/ty/relate.rs b/src/librustc/middle/ty/relate.rs index 137f60572bb45..46bc13bd5988b 100644 --- a/src/librustc/middle/ty/relate.rs +++ b/src/librustc/middle/ty/relate.rs @@ -15,9 +15,8 @@ use middle::def_id::DefId; use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs}; -use middle::ty::{self, Ty}; +use middle::ty::{self, Ty, TypeFoldable}; use middle::ty::error::{ExpectedFound, TypeError}; -use middle::ty::fold::TypeFoldable; use std::rc::Rc; use syntax::abi; use rustc_front::hir as ast; diff --git a/src/librustc/middle/ty/structural_impls.rs b/src/librustc/middle/ty/structural_impls.rs index 8d3a93e72f542..df2f3568754af 100644 --- a/src/librustc/middle/ty/structural_impls.rs +++ b/src/librustc/middle/ty/structural_impls.rs @@ -10,8 +10,7 @@ use middle::subst::{self, VecPerParamSpace}; use middle::traits; -use middle::ty::{self, TraitRef, Ty, TypeAndMut}; -use middle::ty::Lift; +use middle::ty::{self, Lift, TraitRef, Ty}; use middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use std::rc::Rc; diff --git a/src/librustc/middle/ty/sty.rs b/src/librustc/middle/ty/sty.rs index 6f72d3df07e37..7e8d38ae8e797 100644 --- a/src/librustc/middle/ty/sty.rs +++ b/src/librustc/middle/ty/sty.rs @@ -15,8 +15,7 @@ use middle::def_id::DefId; use middle::region; use middle::subst::{self, Substs}; use middle::traits; -use middle::ty::{self, AdtDef, TypeFlags, Ty, TyS}; -use middle::ty::{RegionEscape, ToPredicate}; +use middle::ty::{self, AdtDef, ToPredicate, TypeFlags, Ty, TyS, TypeFoldable}; use util::common::ErrorReported; use collections::enum_set::{self, EnumSet, CLike}; diff --git a/src/librustc/middle/ty/util.rs b/src/librustc/middle/ty/util.rs index 0517769356f75..af23efe2bf4ba 100644 --- a/src/librustc/middle/ty/util.rs +++ b/src/librustc/middle/ty/util.rs @@ -18,9 +18,8 @@ use middle::subst::{self, Subst, Substs}; use middle::infer; use middle::pat_util; use middle::traits; -use middle::ty::{self, Ty, TypeAndMut, TypeFlags}; +use middle::ty::{self, Ty, TypeAndMut, TypeFlags, TypeFoldable}; use middle::ty::{Disr, ParameterEnvironment}; -use middle::ty::{HasTypeFlags, RegionEscape}; use middle::ty::TypeVariants::*; use util::num::ToPrimitive; diff --git a/src/librustc/middle/ty/wf.rs b/src/librustc/middle/ty/wf.rs index d015711fa64db..5f0fc306c24f8 100644 --- a/src/librustc/middle/ty/wf.rs +++ b/src/librustc/middle/ty/wf.rs @@ -13,7 +13,7 @@ use middle::infer::InferCtxt; use middle::ty::outlives::{self, Component}; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, RegionEscape, ToPredicate, Ty}; +use middle::ty::{self, ToPredicate, Ty, TypeFoldable}; use std::iter::once; use syntax::ast; use syntax::codemap::Span; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 423cd62a13f81..9b644e7eba014 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -17,8 +17,7 @@ use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn}; use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple}; use middle::ty::TyClosure; use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer}; -use middle::ty::{self, Ty, HasTypeFlags}; -use middle::ty::fold::TypeFoldable; +use middle::ty::{self, Ty, TypeFoldable}; use std::fmt; use syntax::{abi}; diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 7bcf3276da7a4..8f3366eacb364 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -21,7 +21,7 @@ use rustc_typeck::middle::resolve_lifetime; use rustc_typeck::middle::stability; use rustc_typeck::middle::subst; use rustc_typeck::middle::subst::Subst; -use rustc_typeck::middle::ty::{self, Ty, RegionEscape}; +use rustc_typeck::middle::ty::{self, Ty, TypeFoldable}; use rustc_typeck::middle::ty::relate::TypeRelation; use rustc_typeck::middle::infer::{self, TypeOrigin}; use rustc_typeck::middle::infer::lub::Lub; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0b48cad36ba8f..b8dfb9f74c6a4 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -33,7 +33,7 @@ use middle::def_id::{DefId, DefIndex}; use middle::lang_items; use middle::subst; use middle::ty::{ImplContainer, TraitContainer}; -use middle::ty::{self, RegionEscape, Ty}; +use middle::ty::{self, Ty, TypeFoldable}; use rustc::mir; use rustc::mir::visit::MutVisitor; diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs index c7a5faed35cd0..5a48d6019d699 100644 --- a/src/librustc_metadata/tydecode.rs +++ b/src/librustc_metadata/tydecode.rs @@ -22,7 +22,7 @@ use middle::def_id::{DefId, DefIndex}; use middle::region; use middle::subst; use middle::subst::VecPerParamSpace; -use middle::ty::{self, ToPredicate, Ty, HasTypeFlags}; +use middle::ty::{self, ToPredicate, Ty, TypeFoldable}; use rbml; use rbml::leb128; diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 5a40ff7625224..daafdc0b8d7f6 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -42,7 +42,7 @@ use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::pat_util::simple_name; use middle::subst::Substs; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use rustc::dep_graph::DepNode; use rustc::front::map as hir_map; use rustc::util::common::time; diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index d33beab9313d0..e3b7502b69c0e 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -50,7 +50,7 @@ use trans::meth; use trans::monomorphize; use trans::type_::Type; use trans::type_of; -use middle::ty::{self, Ty, HasTypeFlags, RegionEscape}; +use middle::ty::{self, Ty, TypeFoldable}; use middle::ty::MethodCall; use rustc_front::hir; diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 31b5839bd2167..5046c2e29207c 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -37,7 +37,7 @@ use trans::monomorphize; use trans::type_::Type; use trans::type_of; use middle::traits; -use middle::ty::{self, HasTypeFlags, Ty}; +use middle::ty::{self, Ty}; use middle::ty::fold::{TypeFolder, TypeFoldable}; use rustc_front::hir; use rustc::mir::repr::Mir; diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index d8a3cc50ff4ee..07cc6ec8fbd11 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -35,7 +35,7 @@ use trans::glue; use trans::type_of; use trans::machine; use trans::type_::Type; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use middle::subst::Substs; use rustc::dep_graph::DepNode; use rustc_front::hir; diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 7a1cbf206074d..bd12dd8c3effc 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -34,7 +34,7 @@ use trans::machine; use trans::monomorphize; use trans::type_::Type; use trans::type_of::*; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use middle::ty::MethodCall; use syntax::ast; diff --git a/src/librustc_trans/trans/mir/constant.rs b/src/librustc_trans/trans/mir/constant.rs index 0f4a0407298c8..e461a1c05bcf3 100644 --- a/src/librustc_trans/trans/mir/constant.rs +++ b/src/librustc_trans/trans/mir/constant.rs @@ -11,7 +11,7 @@ use back::abi; use llvm::ValueRef; use middle::subst::Substs; -use middle::ty::{Ty, HasTypeFlags}; +use middle::ty::{Ty, TypeFoldable}; use rustc::middle::const_eval::ConstVal; use rustc::mir::repr as mir; use trans::common::{self, Block, C_bool, C_bytes, C_floating_f64, C_integral, C_str_slice}; diff --git a/src/librustc_trans/trans/mir/did.rs b/src/librustc_trans/trans/mir/did.rs index 737c3dace2efe..0e2387e3e349e 100644 --- a/src/librustc_trans/trans/mir/did.rs +++ b/src/librustc_trans/trans/mir/did.rs @@ -12,7 +12,7 @@ use syntax::codemap::DUMMY_SP; use rustc::front::map; -use rustc::middle::ty::{self, Ty, HasTypeFlags}; +use rustc::middle::ty::{self, Ty, TypeFoldable}; use rustc::middle::subst::Substs; use rustc::middle::const_eval; use rustc::middle::def_id::DefId; diff --git a/src/librustc_trans/trans/mir/lvalue.rs b/src/librustc_trans/trans/mir/lvalue.rs index f7245879e2dce..ba0427ec3d686 100644 --- a/src/librustc_trans/trans/mir/lvalue.rs +++ b/src/librustc_trans/trans/mir/lvalue.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::ValueRef; -use rustc::middle::ty::{self, Ty, HasTypeFlags}; +use rustc::middle::ty::{self, Ty, TypeFoldable}; use rustc::mir::repr as mir; use rustc::mir::tcx::LvalueTy; use trans::adt; diff --git a/src/librustc_trans/trans/mir/operand.rs b/src/librustc_trans/trans/mir/operand.rs index 3a3087b478852..6240473b78ec3 100644 --- a/src/librustc_trans/trans/mir/operand.rs +++ b/src/librustc_trans/trans/mir/operand.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::ValueRef; -use rustc::middle::ty::{Ty, HasTypeFlags}; +use rustc::middle::ty::{Ty, TypeFoldable}; use rustc::mir::repr as mir; use trans::base; use trans::common::{self, Block}; diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 0eaab6b3dbb98..416c1908c973e 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -23,7 +23,7 @@ use trans::base; use trans::common::*; use trans::declare; use trans::foreign; -use middle::ty::{self, HasTypeFlags, Ty}; +use middle::ty::{self, Ty}; use rustc::front::map as hir_map; use rustc_front::hir; diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index e65a212e41b13..8696bdd60e291 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -17,7 +17,7 @@ use trans::adt; use trans::common::*; use trans::foreign; use trans::machine; -use middle::ty::{self, RegionEscape, Ty}; +use middle::ty::{self, Ty, TypeFoldable}; use trans::type_::Type; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 607daa8237444..98effeefad2a7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -57,7 +57,7 @@ use middle::resolve_lifetime as rl; use middle::privacy::{AllPublic, LastMod}; use middle::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs, ParamSpace}; use middle::traits; -use middle::ty::{self, Ty, ToPredicate, HasTypeFlags}; +use middle::ty::{self, Ty, ToPredicate, TypeFoldable}; use middle::ty::wf::object_region_bounds; use require_c_abi_if_variadic; use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 588dee57c520e..926d7fd6e25eb 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -14,7 +14,7 @@ use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding}; use middle::pat_util::pat_is_resolved_const; use middle::privacy::{AllPublic, LastMod}; use middle::subst::Substs; -use middle::ty::{self, Ty, HasTypeFlags, LvaluePreference}; +use middle::ty::{self, Ty, TypeFoldable, LvaluePreference}; use check::{check_expr, check_expr_has_type, check_expr_with_expectation}; use check::{check_expr_coercable_to_type, demand, FnCtxt, Expectation}; use check::{check_expr_with_lvalue_pref}; diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 90e67944ef904..fd6c4f44ba428 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -45,7 +45,7 @@ use super::structurally_resolved_type; use lint; use middle::def_id::DefId; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use middle::ty::cast::{CastKind, CastTy}; use syntax::codemap::Span; use rustc_front::hir; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index a961268c6c49b..44b36294cb480 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, RegionEscape, ToPredicate, ToPolyTraitRef, TraitRef}; +use middle::ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable}; use middle::ty::adjustment::{AdjustDerefRef, AutoDerefRef, AutoPtr}; use middle::infer; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 3bf24aba62467..44dd0ef7b17d8 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -19,9 +19,7 @@ use middle::def_id::DefId; use middle::subst; use middle::subst::Subst; use middle::traits; -use middle::ty::{self, NoPreference, RegionEscape, Ty, ToPolyTraitRef, TraitRef}; -use middle::ty::HasTypeFlags; -use middle::ty::fold::TypeFoldable; +use middle::ty::{self, NoPreference, Ty, ToPolyTraitRef, TraitRef, TypeFoldable}; use middle::infer; use middle::infer::{InferCtxt, TypeOrigin}; use syntax::ast; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 65b0d5892756c..560e84b52d1d6 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -16,7 +16,7 @@ use CrateCtxt; use astconv::AstConv; use check::{self, FnCtxt}; use front::map as hir_map; -use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, HasTypeFlags}; +use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable}; use middle::cstore::{self, CrateStore, DefLike}; use middle::def; use middle::def_id::DefId; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f99124664bbcd..3cf75483fea0f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,7 @@ use middle::traits::{self, report_fulfillment_errors}; use middle::ty::{GenericPredicates, TypeScheme}; use middle::ty::{Disr, ParamTy, ParameterEnvironment}; use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue}; -use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty}; +use middle::ty::{self, ToPolyTraitRef, Ty}; use middle::ty::{MethodCall, MethodCallee}; use middle::ty::adjustment; use middle::ty::error::TypeError; diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index c5a36fb4ada25..f4841b75d13d5 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -19,7 +19,7 @@ use super::{ FnCtxt, }; use middle::def_id::DefId; -use middle::ty::{Ty, HasTypeFlags, PreferMutLvalue}; +use middle::ty::{Ty, TypeFoldable, PreferMutLvalue}; use syntax::ast; use syntax::parse::token; use rustc_front::hir; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 759d561a961b7..9852af3de9956 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -92,7 +92,7 @@ use middle::mem_categorization::Categorization; use middle::region::{self, CodeExtent}; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, RegionEscape, Ty, MethodCall, HasTypeFlags}; +use middle::ty::{self, Ty, MethodCall, TypeFoldable}; use middle::infer::{self, GenericKind, InferCtxt, SubregionOrigin, TypeOrigin, VerifyBound}; use middle::pat_util; use middle::ty::adjustment; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 1536f13a1d51a..c2abb074efa13 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -17,7 +17,7 @@ use astconv::AstConv; use check::FnCtxt; use middle::def_id::DefId; use middle::pat_util; -use middle::ty::{self, Ty, MethodCall, MethodCallee, HasTypeFlags}; +use middle::ty::{self, Ty, MethodCall, MethodCallee}; use middle::ty::adjustment; use middle::ty::fold::{TypeFolder,TypeFoldable}; use middle::infer; diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 07c920829d978..2c8fedb46a7b7 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -20,8 +20,7 @@ use middle::def_id::DefId; use middle::lang_items::UnsizeTraitLangItem; use middle::subst::{self, Subst}; use middle::traits; -use middle::ty; -use middle::ty::RegionEscape; +use middle::ty::{self, TypeFoldable}; use middle::ty::{ImplOrTraitItemId, ConstTraitItemId}; use middle::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment}; use middle::ty::{Ty, TyBool, TyChar, TyEnum, TyError}; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 580d200eb73a7..867d12a1def92 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -103,7 +103,7 @@ use front::map as hir_map; use middle::def; use middle::infer::{self, TypeOrigin}; use middle::subst; -use middle::ty::{self, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, TypeFoldable}; use session::config; use util::common::time; use rustc_front::hir; From 632756396375ea0e74463ed9e239662d887ed3c1 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 6 Jan 2016 02:01:28 +0000 Subject: [PATCH 3/3] Rename fold_subitems_with to super_fold_with --- src/librustc/middle/infer/combine.rs | 2 +- src/librustc/middle/infer/freshen.rs | 2 +- src/librustc/middle/infer/resolve.rs | 6 +- src/librustc/middle/subst.rs | 2 +- src/librustc/middle/traits/project.rs | 2 +- .../middle/traits/structural_impls.rs | 32 +-- src/librustc/middle/ty/fold.rs | 58 ++-- src/librustc/middle/ty/structural_impls.rs | 256 +++++++++--------- src/librustc/util/ppaux.rs | 5 +- 9 files changed, 182 insertions(+), 183 deletions(-) diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index a526586802cac..faf1bdb0ce504 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -318,7 +318,7 @@ impl<'cx, 'tcx> ty::fold::TypeFolder<'tcx> for Generalizer<'cx, 'tcx> { } } _ => { - t.fold_subitems_with(self) + t.super_fold_with(self) } } } diff --git a/src/librustc/middle/infer/freshen.rs b/src/librustc/middle/infer/freshen.rs index 8b53a1520b316..76dd62383f1b1 100644 --- a/src/librustc/middle/infer/freshen.rs +++ b/src/librustc/middle/infer/freshen.rs @@ -168,7 +168,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { ty::TyTuple(..) | ty::TyProjection(..) | ty::TyParam(..) => { - t.fold_subitems_with(self) + t.super_fold_with(self) } } } diff --git a/src/librustc/middle/infer/resolve.rs b/src/librustc/middle/infer/resolve.rs index 04c0cc2245db6..c68d0a9fa5683 100644 --- a/src/librustc/middle/infer/resolve.rs +++ b/src/librustc/middle/infer/resolve.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for OpportunisticTypeResolver<'a, 'tcx t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t0 = self.infcx.shallow_resolve(t); - t0.fold_subitems_with(self) + t0.super_fold_with(self) } } } @@ -67,7 +67,7 @@ impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for OpportunisticTypeAndRegionResolver t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t0 = self.infcx.shallow_resolve(t); - t0.fold_subitems_with(self) + t0.super_fold_with(self) } } @@ -132,7 +132,7 @@ impl<'a, 'tcx> ty::fold::TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { t)); } _ => { - t.fold_subitems_with(self) + t.super_fold_with(self) } } } diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 52a528f07a3b2..61f7b2db4c432 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -674,7 +674,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { self.ty_for_param(p, t) } _ => { - t.fold_subitems_with(self) + t.super_fold_with(self) } }; diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 5e7db57b43181..ad3524661d326 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -273,7 +273,7 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> { // normalize it when we instantiate those bound regions (which // should occur eventually). - let ty = ty.fold_subitems_with(self); + let ty = ty.super_fold_with(self); match ty.sty { ty::TyProjection(ref data) if !data.has_escaping_regions() => { // (*) diff --git a/src/librustc/middle/traits/structural_impls.rs b/src/librustc/middle/traits/structural_impls.rs index ea1657180657b..453420e2a54dc 100644 --- a/src/librustc/middle/traits/structural_impls.rs +++ b/src/librustc/middle/traits/structural_impls.rs @@ -132,7 +132,7 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> { - fn fold_with>(&self, folder: &mut F) -> traits::Obligation<'tcx, O> { + fn super_fold_with>(&self, folder: &mut F) -> Self { traits::Obligation { cause: self.cause.clone(), recursion_depth: self.recursion_depth, @@ -140,13 +140,13 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.predicate.visit_with(visitor) } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> { - fn fold_with>(&self, folder: &mut F) -> traits::VtableImplData<'tcx, N> { + fn super_fold_with>(&self, folder: &mut F) -> Self { traits::VtableImplData { impl_def_id: self.impl_def_id, substs: self.substs.fold_with(folder), @@ -154,13 +154,13 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData< } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.substs.visit_with(visitor) || self.nested.visit_with(visitor) } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> { - fn fold_with>(&self, folder: &mut F) -> traits::VtableClosureData<'tcx, N> { + fn super_fold_with>(&self, folder: &mut F) -> Self { traits::VtableClosureData { closure_def_id: self.closure_def_id, substs: self.substs.fold_with(folder), @@ -168,51 +168,51 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureDa } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.substs.visit_with(visitor) || self.nested.visit_with(visitor) } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableDefaultImplData { - fn fold_with>(&self, folder: &mut F) -> traits::VtableDefaultImplData { + fn super_fold_with>(&self, folder: &mut F) -> Self { traits::VtableDefaultImplData { trait_def_id: self.trait_def_id, nested: self.nested.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.nested.visit_with(visitor) } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData { - fn fold_with>(&self, folder: &mut F) -> traits::VtableBuiltinData { + fn super_fold_with>(&self, folder: &mut F) -> Self { traits::VtableBuiltinData { nested: self.nested.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.nested.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> { - fn fold_with>(&self, folder: &mut F) -> traits::VtableObjectData<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { traits::VtableObjectData { upcast_trait_ref: self.upcast_trait_ref.fold_with(folder), vtable_base: self.vtable_base } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.upcast_trait_ref.visit_with(visitor) } } impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> { - fn fold_with>(&self, folder: &mut F) -> traits::Vtable<'tcx, N> { + fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)), traits::VtableDefaultImpl(ref t) => traits::VtableDefaultImpl(t.fold_with(folder)), @@ -228,7 +228,7 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { traits::VtableImpl(ref v) => v.visit_with(visitor), traits::VtableDefaultImpl(ref t) => t.visit_with(visitor), @@ -242,14 +242,14 @@ impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> { - fn fold_with>(&self, folder: &mut F) -> Normalized<'tcx, T> { + fn super_fold_with>(&self, folder: &mut F) -> Self { Normalized { value: self.value.fold_with(folder), obligations: self.obligations.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.value.visit_with(visitor) || self.obligations.visit_with(visitor) } } diff --git a/src/librustc/middle/ty/fold.rs b/src/librustc/middle/ty/fold.rs index 4701ed6193763..da0245a8d2520 100644 --- a/src/librustc/middle/ty/fold.rs +++ b/src/librustc/middle/ty/fold.rs @@ -14,18 +14,18 @@ //! instance of a "folder" (a type which implements `TypeFolder`). Then //! the setup is intended to be: //! -//! T.fold_with(F) --calls--> F.fold_T(T) --calls--> T.fold_subitems_with(F) +//! T.fold_with(F) --calls--> F.fold_T(T) --calls--> T.super_fold_with(F) //! //! This way, when you define a new folder F, you can override -//! `fold_T()` to customize the behavior, and invoke `T.fold_subitems_with()` +//! `fold_T()` to customize the behavior, and invoke `T.super_fold_with()` //! to get the original behavior. Meanwhile, to actually fold //! something, you can just write `T.fold_with(F)`, which is //! convenient. (Note that `fold_with` will also transparently handle //! things like a `Vec` where T is foldable and so on.) //! //! In this ideal setup, the only function that actually *does* -//! anything is `T.fold_subitems_with()`, which traverses the type `T`. -//! Moreover, `T.fold_subitems_with()` should only ever call `T.fold_with()`. +//! anything is `T.super_fold_with()`, which traverses the type `T`. +//! Moreover, `T.super_fold_with()` should only ever call `T.fold_with()`. //! //! In some cases, we follow a degenerate pattern where we do not have //! a `fold_T` method. Instead, `T.fold_with` traverses the structure directly. @@ -35,7 +35,7 @@ //! proper thing. //! //! A `TypeFoldable` T can also be visited by a `TypeVisitor` V using similar setup: -//! T.visit_with(V) --calls--> V.visit_T(T) --calls--> T.visit_subitems_with(V). +//! T.visit_with(V) --calls--> V.visit_T(T) --calls--> T.super_visit_with(V). //! These methods return true to indicate that the visitor has found what it is looking for //! and does not need to visit anything else. @@ -50,14 +50,14 @@ use util::nodemap::{FnvHashMap, FnvHashSet}; /// The TypeFoldable trait is implemented for every type that can be folded. /// Basically, every type that has a corresponding method in TypeFolder. pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { - fn fold_with>(&self, folder: &mut F) -> Self; - fn fold_subitems_with>(&self, folder: &mut F) -> Self { - self.fold_with(folder) + fn super_fold_with>(&self, folder: &mut F) -> Self; + fn fold_with>(&self, folder: &mut F) -> Self { + self.super_fold_with(folder) } - fn visit_with>(&self, visitor: &mut V) -> bool; - fn visit_subitems_with>(&self, visitor: &mut V) -> bool { - self.visit_with(visitor) + fn super_visit_with>(&self, visitor: &mut V) -> bool; + fn visit_with>(&self, visitor: &mut V) -> bool { + self.super_visit_with(visitor) } fn has_regions_escaping_depth(&self, depth: u32) -> bool { @@ -131,64 +131,64 @@ pub trait TypeFolder<'tcx> : Sized { where T : TypeFoldable<'tcx> { // FIXME(#20526) this should replace `enter_region_binder`/`exit_region_binder`. - t.fold_subitems_with(self) + t.super_fold_with(self) } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - t.fold_subitems_with(self) + t.super_fold_with(self) } fn fold_mt(&mut self, t: &ty::TypeAndMut<'tcx>) -> ty::TypeAndMut<'tcx> { - t.fold_subitems_with(self) + t.super_fold_with(self) } fn fold_trait_ref(&mut self, t: &ty::TraitRef<'tcx>) -> ty::TraitRef<'tcx> { - t.fold_subitems_with(self) + t.super_fold_with(self) } fn fold_substs(&mut self, substs: &subst::Substs<'tcx>) -> subst::Substs<'tcx> { - substs.fold_subitems_with(self) + substs.super_fold_with(self) } fn fold_fn_sig(&mut self, sig: &ty::FnSig<'tcx>) -> ty::FnSig<'tcx> { - sig.fold_subitems_with(self) + sig.super_fold_with(self) } fn fold_output(&mut self, output: &ty::FnOutput<'tcx>) -> ty::FnOutput<'tcx> { - output.fold_subitems_with(self) + output.super_fold_with(self) } fn fold_bare_fn_ty(&mut self, fty: &ty::BareFnTy<'tcx>) -> ty::BareFnTy<'tcx> { - fty.fold_subitems_with(self) + fty.super_fold_with(self) } fn fold_closure_ty(&mut self, fty: &ty::ClosureTy<'tcx>) -> ty::ClosureTy<'tcx> { - fty.fold_subitems_with(self) + fty.super_fold_with(self) } fn fold_region(&mut self, r: ty::Region) -> ty::Region { - r.fold_subitems_with(self) + r.super_fold_with(self) } fn fold_existential_bounds(&mut self, s: &ty::ExistentialBounds<'tcx>) -> ty::ExistentialBounds<'tcx> { - s.fold_subitems_with(self) + s.super_fold_with(self) } fn fold_autoref(&mut self, ar: &adjustment::AutoRef<'tcx>) -> adjustment::AutoRef<'tcx> { - ar.fold_subitems_with(self) + ar.super_fold_with(self) } } @@ -197,11 +197,11 @@ pub trait TypeVisitor<'tcx> : Sized { fn exit_region_binder(&mut self) { } fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - t.visit_subitems_with(self) + t.super_visit_with(self) } fn visit_region(&mut self, r: ty::Region) -> bool { - r.visit_subitems_with(self) + r.super_visit_with(self) } } @@ -219,7 +219,7 @@ impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where fn tcx(&self) -> &ty::ctxt<'tcx> { self.tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - let t1 = ty.fold_subitems_with(self); + let t1 = ty.super_fold_with(self); (self.fldop)(t1) } } @@ -447,7 +447,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> return t; } - t.fold_subitems_with(self) + t.super_fold_with(self) } fn fold_region(&mut self, r: ty::Region) -> ty::Region { @@ -498,7 +498,7 @@ impl<'tcx> ty::ctxt<'tcx> { Some(u) => return u } - let t_norm = ty.fold_subitems_with(self); + let t_norm = ty.super_fold_with(self); self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm); return t_norm; } @@ -507,7 +507,7 @@ impl<'tcx> ty::ctxt<'tcx> { where T : TypeFoldable<'tcx> { let u = self.tcx().anonymize_late_bound_regions(t); - u.fold_subitems_with(self) + u.super_fold_with(self) } fn fold_region(&mut self, r: ty::Region) -> ty::Region { diff --git a/src/librustc/middle/ty/structural_impls.rs b/src/librustc/middle/ty/structural_impls.rs index df2f3568754af..01b2bd36b4f07 100644 --- a/src/librustc/middle/ty/structural_impls.rs +++ b/src/librustc/middle/ty/structural_impls.rs @@ -123,11 +123,11 @@ macro_rules! CopyImpls { ($($ty:ty),+) => { $( impl<'tcx> TypeFoldable<'tcx> for $ty { - fn fold_with>(&self, _: &mut F) -> $ty { + fn super_fold_with>(&self, _: &mut F) -> $ty { *self } - fn visit_with>(&self, _: &mut F) -> bool { + fn super_visit_with>(&self, _: &mut F) -> bool { false } } @@ -138,69 +138,69 @@ macro_rules! CopyImpls { CopyImpls! { (), hir::Unsafety, abi::Abi } impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { - fn fold_with>(&self, folder: &mut F) -> (T, U) { + fn super_fold_with>(&self, folder: &mut F) -> (T, U) { (self.0.fold_with(folder), self.1.fold_with(folder)) } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.0.visit_with(visitor) || self.1.visit_with(visitor) } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option { - fn fold_with>(&self, folder: &mut F) -> Option { + fn super_fold_with>(&self, folder: &mut F) -> Self { self.as_ref().map(|t| t.fold_with(folder)) } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { - fn fold_with>(&self, folder: &mut F) -> Rc { + fn super_fold_with>(&self, folder: &mut F) -> Self { Rc::new((**self).fold_with(folder)) } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { (**self).visit_with(visitor) } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { - fn fold_with>(&self, folder: &mut F) -> Box { + fn super_fold_with>(&self, folder: &mut F) -> Self { let content: T = (**self).fold_with(folder); box content } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { (**self).visit_with(visitor) } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { - fn fold_with>(&self, folder: &mut F) -> Vec { + fn super_fold_with>(&self, folder: &mut F) -> Self { self.iter().map(|t| t.fold_with(folder)).collect() } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } } impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { - fn fold_with>(&self, folder: &mut F) -> ty::Binder { - folder.fold_binder(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { folder.enter_region_binder(); let result = ty::Binder(self.0.fold_with(folder)); folder.exit_region_binder(); result } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_binder(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { visitor.enter_region_binder(); if self.0.visit_with(visitor) { return true } visitor.exit_region_binder(); @@ -209,17 +209,17 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for P<[T]> { - fn fold_with>(&self, folder: &mut F) -> P<[T]> { + fn super_fold_with>(&self, folder: &mut F) -> Self { self.iter().map(|t| t.fold_with(folder)).collect() } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace { - fn fold_with>(&self, folder: &mut F) -> VecPerParamSpace { + fn super_fold_with>(&self, folder: &mut F) -> Self { // Things in the Fn space take place under an additional level // of region binding relative to the other spaces. This is @@ -240,7 +240,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace { result } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { let mut entered_region_binder = false; let result = self.iter_enumerated().any(|(space, index, t)| { if space == subst::FnSpace && index == 0 { @@ -257,24 +257,20 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for VecPerParamSpace { } impl<'tcx> TypeFoldable<'tcx> for ty::TraitTy<'tcx> { - fn fold_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::TraitTy { principal: self.principal.fold_with(folder), bounds: self.bounds.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.principal.visit_with(visitor) || self.bounds.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { - fn fold_with>(&self, folder: &mut F) -> Ty<'tcx> { - folder.fold_ty(*self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { let sty = match self.sty { ty::TyBox(typ) => ty::TyBox(typ.fold_with(folder)), ty::TyRawPtr(ref tm) => ty::TyRawPtr(tm.fold_with(folder)), @@ -309,11 +305,11 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { folder.tcx().mk_ty(sty) } - fn visit_with>(&self, visitor: &mut V) -> bool { - visitor.visit_ty(self) + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_ty(*self) } - fn visit_subitems_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { match self.sty { ty::TyBox(typ) => typ.visit_with(visitor), ty::TyRawPtr(ref tm) => tm.visit_with(visitor), @@ -332,30 +328,30 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyParam(..) => false, } } -} -impl<'tcx> TypeFoldable<'tcx> for ty::BareFnTy<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::BareFnTy<'tcx> { - folder.fold_bare_fn_ty(self) + fn visit_with>(&self, visitor: &mut V) -> bool { + visitor.visit_ty(self) } +} - fn fold_subitems_with>(&self, folder: &mut F) -> Self { +impl<'tcx> TypeFoldable<'tcx> for ty::BareFnTy<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::BareFnTy { sig: self.sig.fold_with(folder), abi: self.abi, unsafety: self.unsafety } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_bare_fn_ty(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.sig.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::ClosureTy<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ClosureTy<'tcx> { - folder.fold_closure_ty(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::ClosureTy { sig: self.sig.fold_with(folder), unsafety: self.unsafety, @@ -363,38 +359,42 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureTy<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_closure_ty(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.sig.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::TypeAndMut<'tcx> { - folder.fold_mt(self) + fn super_fold_with>(&self, folder: &mut F) -> Self { + ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl } } - fn fold_subitems_with>(&self, folder: &mut F) -> Self { - ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl } + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_mt(self) } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.ty.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::FnOutput<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::FnOutput<'tcx> { - folder.fold_output(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { ty::FnConverging(ref ty) => ty::FnConverging(ty.fold_with(folder)), ty::FnDiverging => ty::FnDiverging } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_output(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { ty::FnConverging(ref ty) => ty.visit_with(visitor), ty::FnDiverging => false, @@ -403,27 +403,23 @@ impl<'tcx> TypeFoldable<'tcx> for ty::FnOutput<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::FnSig<'tcx> { - folder.fold_fn_sig(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::FnSig { inputs: self.inputs.fold_with(folder), output: self.output.fold_with(folder), variadic: self.variadic } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_fn_sig(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.inputs.visit_with(visitor) || self.output.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::TraitRef<'tcx> { - folder.fold_trait_ref(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { let substs = self.substs.fold_with(folder); ty::TraitRef { def_id: self.def_id, @@ -431,35 +427,35 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_trait_ref(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.substs.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::Region { - fn fold_with>(&self, folder: &mut F) -> ty::Region { + fn super_fold_with>(&self, _folder: &mut F) -> Self { + *self + } + + fn fold_with>(&self, folder: &mut F) -> Self { folder.fold_region(*self) } - fn fold_subitems_with>(&self, _folder: &mut F) -> Self { - *self + fn super_visit_with>(&self, _visitor: &mut V) -> bool { + false } fn visit_with>(&self, visitor: &mut V) -> bool { visitor.visit_region(*self) } - - fn visit_subitems_with>(&self, _visitor: &mut V) -> bool { - false - } } impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> { - fn fold_with>(&self, folder: &mut F) -> subst::Substs<'tcx> { - folder.fold_substs(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { let regions = match self.regions { subst::ErasedRegions => subst::ErasedRegions, subst::NonerasedRegions(ref regions) => { @@ -471,7 +467,11 @@ impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> { types: self.types.fold_with(folder) } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_substs(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.types.visit_with(visitor) || match self.regions { subst::ErasedRegions => false, subst::NonerasedRegions(ref regions) => regions.visit_with(visitor), @@ -480,7 +480,7 @@ impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ClosureSubsts<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { let func_substs = self.func_substs.fold_with(folder); ty::ClosureSubsts { func_substs: folder.tcx().mk_substs(func_substs), @@ -488,29 +488,25 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.func_substs.visit_with(visitor) || self.upvar_tys.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ItemSubsts<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::ItemSubsts { substs: self.substs.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.substs.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoRef<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::adjustment::AutoRef<'tcx> { - folder.fold_autoref(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { ty::adjustment::AutoPtr(r, m) => { let r = r.fold_with(folder); @@ -520,7 +516,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoRef<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_autoref(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { ty::adjustment::AutoPtr(r, _m) => r.visit_with(visitor), ty::adjustment::AutoUnsafe(_m) => false, @@ -529,21 +529,17 @@ impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoRef<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::BuiltinBounds { - fn fold_with>(&self, _folder: &mut F) -> ty::BuiltinBounds { + fn super_fold_with>(&self, _folder: &mut F) -> Self { *self } - fn visit_with>(&self, _visitor: &mut V) -> bool { + fn super_visit_with>(&self, _visitor: &mut V) -> bool { false } } impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialBounds<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ExistentialBounds<'tcx> { - folder.fold_existential_bounds(self) - } - - fn fold_subitems_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::ExistentialBounds { region_bound: self.region_bound.fold_with(folder), builtin_bounds: self.builtin_bounds, @@ -551,13 +547,17 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialBounds<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn fold_with>(&self, folder: &mut F) -> Self { + folder.fold_existential_bounds(self) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.region_bound.visit_with(visitor) || self.projection_bounds.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::TypeParameterDef<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::TypeParameterDef { name: self.name, def_id: self.def_id, @@ -569,14 +569,14 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.default.visit_with(visitor) || self.object_lifetime_default.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault { - fn fold_with>(&self, folder: &mut F) -> ty::ObjectLifetimeDefault { + fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { ty::ObjectLifetimeDefault::Ambiguous => ty::ObjectLifetimeDefault::Ambiguous, @@ -589,7 +589,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { ty::ObjectLifetimeDefault::Specific(r) => r.visit_with(visitor), _ => false, @@ -598,7 +598,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault { } impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef { - fn fold_with>(&self, folder: &mut F) -> ty::RegionParameterDef { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::RegionParameterDef { name: self.name, def_id: self.def_id, @@ -608,38 +608,38 @@ impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.bounds.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::Generics<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::Generics { types: self.types.fold_with(folder), regions: self.regions.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.types.visit_with(visitor) || self.regions.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::GenericPredicates<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::GenericPredicates { predicates: self.predicates.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.predicates.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::Predicate<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { match *self { ty::Predicate::Trait(ref a) => ty::Predicate::Trait(a.fold_with(folder)), @@ -658,7 +658,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { ty::Predicate::Trait(ref a) => a.visit_with(visitor), ty::Predicate::Equate(ref binder) => binder.visit_with(visitor), @@ -672,62 +672,62 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ProjectionPredicate<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::ProjectionPredicate { projection_ty: self.projection_ty.fold_with(folder), ty: self.ty.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.projection_ty.visit_with(visitor) || self.ty.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ProjectionTy<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::ProjectionTy { trait_ref: self.trait_ref.fold_with(folder), item_name: self.item_name, } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.trait_ref.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::InstantiatedPredicates<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::InstantiatedPredicates { predicates: self.predicates.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.predicates.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::EquatePredicate<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::EquatePredicate(self.0.fold_with(folder), self.1.fold_with(folder)) } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.0.visit_with(visitor) || self.1.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::TraitPredicate<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::TraitPredicate { trait_ref: self.trait_ref.fold_with(folder) } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.trait_ref.visit_with(visitor) } } @@ -736,18 +736,18 @@ impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>, { - fn fold_with>(&self, folder: &mut F) -> ty::OutlivesPredicate { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::OutlivesPredicate(self.0.fold_with(folder), self.1.fold_with(folder)) } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.0.visit_with(visitor) || self.1.visit_with(visitor) } } impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { - fn fold_with>(&self, folder: &mut F) -> ty::ClosureUpvar<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::ClosureUpvar { def: self.def, span: self.span, @@ -755,13 +755,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.ty.visit_with(visitor) } } impl<'a, 'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'a, 'tcx> where 'tcx: 'a { - fn fold_with>(&self, folder: &mut F) -> ty::ParameterEnvironment<'a, 'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::ParameterEnvironment { tcx: self.tcx, free_substs: self.free_substs.fold_with(folder), @@ -773,7 +773,7 @@ impl<'a, 'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'a, 'tcx> where ' } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.free_substs.visit_with(visitor) || self.implicit_region_bound.visit_with(visitor) || self.caller_bounds.visit_with(visitor) @@ -781,14 +781,14 @@ impl<'a, 'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'a, 'tcx> where ' } impl<'tcx> TypeFoldable<'tcx> for ty::TypeScheme<'tcx> { - fn fold_with>(&self, folder: &mut F) -> Self { + fn super_fold_with>(&self, folder: &mut F) -> Self { ty::TypeScheme { generics: self.generics.fold_with(folder), ty: self.ty.fold_with(folder), } } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.generics.visit_with(visitor) || self.ty.visit_with(visitor) } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 9b644e7eba014..77e39bba54afc 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -251,12 +251,11 @@ fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter, struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec>); impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> { - fn fold_with>(&self, folder: &mut F) - -> TraitAndProjections<'tcx> { + fn super_fold_with>(&self, folder: &mut F) -> Self { TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder)) } - fn visit_with>(&self, visitor: &mut V) -> bool { + fn super_visit_with>(&self, visitor: &mut V) -> bool { self.0.visit_with(visitor) || self.1.visit_with(visitor) } }