]> git.lizzy.rs Git - rust.git/commitdiff
Factor out foldable better to reduce code duplication. There is now a "double
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 12 May 2014 21:12:51 +0000 (17:12 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Mon, 12 May 2014 21:46:26 +0000 (17:46 -0400)
dispatch" pattern that lets you easily write new folders and then apply them to
various structures, reusing the "folding" effort.

src/librustc/middle/subst.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/writeback.rs

index 59ff1f804036da62b3a3600c77d2c9516faf36fe..96d2670134226d4521a8550debc7bef6fb78ce93 100644 (file)
 
 use middle::ty;
 use middle::ty_fold;
-use middle::ty_fold::TypeFolder;
+use middle::ty_fold::{TypeFoldable, TypeFolder};
 use util::ppaux::Repr;
 
-use std::rc::Rc;
 use syntax::codemap::Span;
-use syntax::owned_slice::OwnedSlice;
 
 ///////////////////////////////////////////////////////////////////////////
 // Public trait `Subst`
 //
 // Just call `foo.subst(tcx, substs)` to perform a substitution across
-// `foo`.
-// Or use `foo.subst_spanned(tcx, substs, Some(span))` when there is more
-// information available (for better errors).
+// `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
+// there is more information available (for better errors).
 
 pub trait Subst {
     fn subst(&self, tcx: &ty::ctxt, substs: &ty::substs) -> Self {
         self.subst_spanned(tcx, substs, None)
     }
+
     fn subst_spanned(&self, tcx: &ty::ctxt,
                      substs: &ty::substs,
-                     span: Option<Span>) -> Self;
+                     span: Option<Span>)
+                     -> Self;
 }
 
-///////////////////////////////////////////////////////////////////////////
-// Substitution over types
-//
-// Because this is so common, we make a special optimization to avoid
-// doing anything if `substs` is a no-op.  I tried to generalize these
-// to all subst methods but ran into trouble due to the limitations of
-// our current method/trait matching algorithm. - Niko
-
-impl Subst for ty::t {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
+impl<T:TypeFoldable> Subst for T {
+    fn subst_spanned(&self,
+                     tcx: &ty::ctxt,
                      substs: &ty::substs,
-                     span: Option<Span>) -> ty::t {
-        if ty::substs_is_noop(substs) && !ty::type_has_params(*self) {
-            *self
-        } else {
-            let mut folder = SubstFolder {
-                tcx: tcx,
-                substs: substs,
-                span: span,
-                root_ty: Some(*self)
-            };
-            folder.fold_ty(*self)
-        }
+                     span: Option<Span>)
+                     -> T
+    {
+        let mut folder = SubstFolder { tcx: tcx,
+                                       substs: substs,
+                                       span: span,
+                                       root_ty: None,
+                                       ty_stack_depth: 0 };
+        (*self).fold_with(&mut folder)
     }
 }
 
+///////////////////////////////////////////////////////////////////////////
+// The actual substitution engine itself is a type folder.
+
 struct SubstFolder<'a> {
     tcx: &'a ty::ctxt,
     substs: &'a ty::substs,
@@ -70,14 +62,31 @@ struct SubstFolder<'a> {
     span: Option<Span>,
 
     // The root type that is being substituted, if available.
-    root_ty: Option<ty::t>
+    root_ty: Option<ty::t>,
+
+    // Depth of type stack
+    ty_stack_depth: uint,
 }
 
 impl<'a> TypeFolder for SubstFolder<'a> {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
 
     fn fold_region(&mut self, r: ty::Region) -> ty::Region {
-        r.subst(self.tcx, self.substs)
+        // Note: This routine only handles regions that are bound on
+        // type declarations and other outer declarations, not those
+        // bound in *fn types*. Region substitution of the bound
+        // regions that appear in a function signature is done using
+        // the specialized routine
+        // `middle::typeck::check::regionmanip::replace_late_regions_in_fn_sig()`.
+        match r {
+            ty::ReEarlyBound(_, i, _) => {
+                match self.substs.regions {
+                    ty::ErasedRegions => ty::ReStatic,
+                    ty::NonerasedRegions(ref regions) => *regions.get(i),
+                }
+            }
+            _ => r
+        }
     }
 
     fn fold_ty(&mut self, t: ty::t) -> ty::t {
@@ -85,8 +94,18 @@ fn fold_ty(&mut self, t: ty::t) -> ty::t {
             return t;
         }
 
-        match ty::get(t).sty {
+        // track the root type we were asked to substitute
+        let depth = self.ty_stack_depth;
+        if depth == 0 {
+            self.root_ty = Some(t);
+        }
+        self.ty_stack_depth += 1;
+
+        let t1 = match ty::get(t).sty {
             ty::ty_param(p) => {
+                // FIXME -- This...really shouldn't happen. We should
+                // never be substituting without knowing what's in
+                // scope and knowing that the indices will line up!
                 if p.idx < self.substs.tps.len() {
                     *self.substs.tps.get(p.idx)
                 } else {
@@ -124,189 +143,14 @@ fn fold_ty(&mut self, t: ty::t) -> ty::t {
                 }
             }
             _ => ty_fold::super_fold_ty(self, t)
-        }
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Other types
-
-impl<T:Subst> Subst for Vec<T> {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> Vec<T> {
-        self.iter().map(|t| t.subst_spanned(tcx, substs, span)).collect()
-    }
-}
-impl<T:Subst> Subst for Rc<T> {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> Rc<T> {
-        Rc::new((**self).subst_spanned(tcx, substs, span))
-    }
-}
-
-impl<T:Subst> Subst for OwnedSlice<T> {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> OwnedSlice<T> {
-        self.map(|t| t.subst_spanned(tcx, substs, span))
-    }
-}
-
-impl<T:Subst + 'static> Subst for @T {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> @T {
-        match self {
-            t => @(**t).subst_spanned(tcx, substs, span)
-        }
-    }
-}
-
-impl<T:Subst> Subst for Option<T> {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> Option<T> {
-        self.as_ref().map(|t| t.subst_spanned(tcx, substs, span))
-    }
-}
-
-impl Subst for ty::TraitRef {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::TraitRef {
-        ty::TraitRef {
-            def_id: self.def_id,
-            substs: self.substs.subst_spanned(tcx, substs, span)
-        }
-    }
-}
-
-impl Subst for ty::substs {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::substs {
-        ty::substs {
-            regions: self.regions.subst_spanned(tcx, substs, span),
-            self_ty: self.self_ty.map(|typ| typ.subst_spanned(tcx, substs, span)),
-            tps: self.tps.iter().map(|typ| typ.subst_spanned(tcx, substs, span)).collect()
-        }
-    }
-}
-
-impl Subst for ty::ItemSubsts {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>)
-                     -> ty::ItemSubsts {
-        ty::ItemSubsts {
-            substs: self.substs.subst_spanned(tcx, substs, span)
-        }
-    }
-}
-
-impl Subst for ty::RegionSubsts {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::RegionSubsts {
-        match *self {
-            ty::ErasedRegions => {
-                ty::ErasedRegions
-            }
-            ty::NonerasedRegions(ref regions) => {
-                ty::NonerasedRegions(regions.subst_spanned(tcx, substs, span))
-            }
-        }
-    }
-}
-
-impl Subst for ty::BareFnTy {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::BareFnTy {
-        let mut folder = SubstFolder {
-            tcx: tcx,
-            substs: substs,
-            span: span,
-            root_ty: None
         };
-        folder.fold_bare_fn_ty(self)
-    }
-}
 
-impl Subst for ty::ParamBounds {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::ParamBounds {
-        ty::ParamBounds {
-            builtin_bounds: self.builtin_bounds,
-            trait_bounds: self.trait_bounds.subst_spanned(tcx, substs, span)
+        assert_eq!(depth + 1, self.ty_stack_depth);
+        self.ty_stack_depth -= 1;
+        if depth == 0 {
+            self.root_ty = None;
         }
-    }
-}
 
-impl Subst for ty::TypeParameterDef {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::TypeParameterDef {
-        ty::TypeParameterDef {
-            ident: self.ident,
-            def_id: self.def_id,
-            bounds: self.bounds.subst_spanned(tcx, substs, span),
-            default: self.default.map(|x| x.subst_spanned(tcx, substs, span))
-        }
-    }
-}
-
-impl Subst for ty::Generics {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::Generics {
-        ty::Generics {
-            type_param_defs: self.type_param_defs.subst_spanned(tcx, substs, span),
-            region_param_defs: self.region_param_defs.subst_spanned(tcx, substs, span),
-        }
-    }
-}
-
-impl Subst for ty::RegionParameterDef {
-    fn subst_spanned(&self, _: &ty::ctxt,
-                     _: &ty::substs,
-                     _: Option<Span>) -> ty::RegionParameterDef {
-        *self
-    }
-}
-
-impl Subst for ty::Region {
-    fn subst_spanned(&self, _tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     _: Option<Span>) -> ty::Region {
-        // Note: This routine only handles regions that are bound on
-        // type declarations and other outer declarations, not those
-        // bound in *fn types*. Region substitution of the bound
-        // regions that appear in a function signature is done using
-        // the specialized routine
-        // `middle::typeck::check::regionmanip::replace_late_regions_in_fn_sig()`.
-        match self {
-            &ty::ReEarlyBound(_, i, _) => {
-                match substs.regions {
-                    ty::ErasedRegions => ty::ReStatic,
-                    ty::NonerasedRegions(ref regions) => *regions.get(i),
-                }
-            }
-            _ => *self
-        }
-    }
-}
-
-impl Subst for ty::ty_param_bounds_and_ty {
-    fn subst_spanned(&self, tcx: &ty::ctxt,
-                     substs: &ty::substs,
-                     span: Option<Span>) -> ty::ty_param_bounds_and_ty {
-        ty::ty_param_bounds_and_ty {
-            generics: self.generics.subst_spanned(tcx, substs, span),
-            ty: self.ty.subst_spanned(tcx, substs, span)
-        }
+        t1
     }
 }
index f37a4ab0aaa4aafb2da24cd9dceb0048ba8d8885..7ef61a2361d3968b544c9a321dd4c3f3b9e61f6a 100644 (file)
@@ -26,7 +26,7 @@
 use middle::typeck;
 use middle::typeck::MethodCall;
 use middle::ty_fold;
-use middle::ty_fold::TypeFolder;
+use middle::ty_fold::{TypeFoldable,TypeFolder};
 use middle;
 use util::ppaux::{note_and_explain_region, bound_region_ptr_to_str};
 use util::ppaux::{trait_store_to_str, ty_to_str};
@@ -1034,7 +1034,7 @@ pub struct ParameterEnvironment {
     pub self_param_bound: Option<Rc<TraitRef>>,
 
     /// Bounds on each numbered type parameter
-    pub type_param_bounds: Vec<ParamBounds> ,
+    pub type_param_bounds: Vec<ParamBounds>,
 }
 
 /// A polytype.
@@ -1519,7 +1519,9 @@ pub fn walk_regions_and_ty(cx: &ctxt, ty: t, fldr: |r: Region|, fldt: |t: t|)
 
 impl ItemSubsts {
     pub fn empty() -> ItemSubsts {
-        ItemSubsts { substs: substs::empty() }
+        ItemSubsts {
+            substs: substs::empty(),
+        }
     }
 
     pub fn is_noop(&self) -> bool {
@@ -4102,8 +4104,8 @@ fn fold_substs(&mut self,
                        substs: &substs)
                        -> substs {
             substs { regions: ErasedRegions,
-                     self_ty: ty_fold::fold_opt_ty(self, substs.self_ty),
-                     tps: ty_fold::fold_ty_vec(self, substs.tps.as_slice()) }
+                     self_ty: substs.self_ty.fold_with(self),
+                     tps: substs.tps.fold_with(self) }
         }
 
         fn fold_sig(&mut self,
@@ -4113,8 +4115,8 @@ fn fold_sig(&mut self,
             // are erased at trans time.
             ty::FnSig {
                 binder_id: ast::DUMMY_NODE_ID,
-                inputs: ty_fold::fold_ty_vec(self, sig.inputs.as_slice()),
-                output: self.fold_ty(sig.output),
+                inputs: sig.inputs.fold_with(self),
+                output: sig.output.fold_with(self),
                 variadic: sig.variadic,
             }
         }
index 86291a7d6cb3e6a98d9743182d35442ee9573725..27a02ea47cb9144b576bc5785bf82cf153868935 100644 (file)
 // Generalized type folding mechanism.
 
 use middle::ty;
+use middle::typeck;
+use std::rc::Rc;
+use syntax::owned_slice::OwnedSlice;
 use util::ppaux::Repr;
 
+///////////////////////////////////////////////////////////////////////////
+// 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 {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> Self;
+}
+
+/// The TypeFolder trait defines the actual *folding*. There is a
+/// method defined for every foldable type. Each of these has a
+/// default implementation that does an "identity" fold. Within each
+/// identity fold, it should invoke `foo.fold_with(self)` to fold each
+/// sub-item.
 pub trait TypeFolder {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt;
 
@@ -46,22 +63,15 @@ fn fold_sig(&mut self,
 
     fn fold_bare_fn_ty(&mut self,
                        fty: &ty::BareFnTy)
-                       -> ty::BareFnTy {
-        ty::BareFnTy { sig: self.fold_sig(&fty.sig),
-                       abi: fty.abi,
-                       fn_style: fty.fn_style }
+                       -> ty::BareFnTy
+    {
+        super_fold_bare_fn_ty(self, fty)
     }
 
     fn fold_closure_ty(&mut self,
                        fty: &ty::ClosureTy)
                        -> ty::ClosureTy {
-        ty::ClosureTy {
-            store: self.fold_trait_store(fty.store),
-            sig: self.fold_sig(&fty.sig),
-            fn_style: fty.fn_style,
-            onceness: fty.onceness,
-            bounds: fty.bounds,
-        }
+        super_fold_closure_ty(self, fty)
     }
 
     fn fold_region(&mut self, r: ty::Region) -> ty::Region {
@@ -75,22 +85,195 @@ fn fold_trait_store(&mut self, s: ty::TraitStore) -> ty::TraitStore {
     fn fold_autoref(&mut self, ar: &ty::AutoRef) -> ty::AutoRef {
         super_fold_autoref(self, ar)
     }
+
+    fn fold_item_substs(&mut self, i: ty::ItemSubsts) -> ty::ItemSubsts {
+        super_fold_item_substs(self, i)
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// TypeFoldable implementations.
+//
+// Ideally, each type should invoke `folder.fold_foo(self)` and
+// nothing else. In some cases, though, we haven't gotten around to
+// adding methods on the `folder` yet, and thus the folding is
+// hard-coded here. This is less-flexible, because folders cannot
+// override the behavior, but there are a lot of random types and one
+// can easily refactor the folding into the TypeFolder trait as
+// needed.
+
+impl<T:TypeFoldable> TypeFoldable for Option<T> {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> Option<T> {
+        self.as_ref().map(|t| t.fold_with(folder))
+    }
+}
+
+impl<T:TypeFoldable> TypeFoldable for Rc<T> {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> Rc<T> {
+        Rc::new((**self).fold_with(folder))
+    }
+}
+
+impl<T:TypeFoldable> TypeFoldable for Vec<T> {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> Vec<T> {
+        self.iter().map(|t| t.fold_with(folder)).collect()
+    }
+}
+
+impl<T:TypeFoldable> TypeFoldable for OwnedSlice<T> {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> OwnedSlice<T> {
+        self.iter().map(|t| t.fold_with(folder)).collect()
+    }
+}
+
+impl TypeFoldable for ty::TraitStore {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::TraitStore {
+        folder.fold_trait_store(*self)
+    }
+}
+
+impl TypeFoldable for ty::t {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::t {
+        folder.fold_ty(*self)
+    }
+}
+
+impl TypeFoldable for ty::BareFnTy {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::BareFnTy {
+        folder.fold_bare_fn_ty(self)
+    }
+}
+
+impl TypeFoldable for ty::ClosureTy {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::ClosureTy {
+        folder.fold_closure_ty(self)
+    }
+}
+
+impl TypeFoldable for ty::mt {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::mt {
+        folder.fold_mt(self)
+    }
+}
+
+impl TypeFoldable for ty::FnSig {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::FnSig {
+        folder.fold_sig(self)
+    }
+}
+
+impl TypeFoldable for ty::sty {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::sty {
+        folder.fold_sty(self)
+    }
+}
+
+impl TypeFoldable for ty::TraitRef {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::TraitRef {
+        folder.fold_trait_ref(self)
+    }
+}
+
+impl TypeFoldable for ty::Region {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::Region {
+        folder.fold_region(*self)
+    }
+}
+
+impl TypeFoldable for ty::substs {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::substs {
+        folder.fold_substs(self)
+    }
+}
+
+impl TypeFoldable for ty::ItemSubsts {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::ItemSubsts {
+        ty::ItemSubsts {
+            substs: self.substs.fold_with(folder),
+        }
+    }
+}
+
+impl TypeFoldable for ty::AutoRef {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::AutoRef {
+        folder.fold_autoref(self)
+    }
+}
+
+impl TypeFoldable for typeck::vtable_origin {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> typeck::vtable_origin {
+        match *self {
+            typeck::vtable_static(def_id, ref substs, ref origins) => {
+                let r_substs = substs.fold_with(folder);
+                let r_origins = origins.fold_with(folder);
+                typeck::vtable_static(def_id, r_substs, r_origins)
+            }
+            typeck::vtable_param(n, b) => {
+                typeck::vtable_param(n, b)
+            }
+        }
+    }
+}
+
+impl TypeFoldable for typeck::impl_res {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> typeck::impl_res {
+        typeck::impl_res {
+            trait_vtables: self.trait_vtables.fold_with(folder),
+            self_vtables: self.self_vtables.fold_with(folder),
+        }
+    }
 }
 
-pub fn fold_opt_ty<T:TypeFolder>(this: &mut T,
-                                 t: Option<ty::t>)
-                                 -> Option<ty::t> {
-    t.map(|t| this.fold_ty(t))
+impl TypeFoldable for ty::BuiltinBounds {
+    fn fold_with<F:TypeFolder>(&self, _folder: &mut F) -> ty::BuiltinBounds {
+        *self
+    }
 }
 
-pub fn fold_ty_vec<T:TypeFolder>(this: &mut T, tys: &[ty::t]) -> Vec<ty::t> {
-    tys.iter().map(|t| this.fold_ty(*t)).collect()
+impl TypeFoldable for ty::ParamBounds {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::ParamBounds {
+        ty::ParamBounds {
+            builtin_bounds: self.builtin_bounds.fold_with(folder),
+            trait_bounds: self.trait_bounds.fold_with(folder),
+        }
+    }
 }
 
+impl TypeFoldable for ty::TypeParameterDef {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::TypeParameterDef {
+        ty::TypeParameterDef {
+            ident: self.ident,
+            def_id: self.def_id,
+            bounds: self.bounds.fold_with(folder),
+            default: self.default.fold_with(folder),
+        }
+    }
+}
+
+impl TypeFoldable for ty::RegionParameterDef {
+    fn fold_with<F:TypeFolder>(&self, _folder: &mut F) -> ty::RegionParameterDef {
+        *self
+    }
+}
+
+impl TypeFoldable for ty::Generics {
+    fn fold_with<F:TypeFolder>(&self, folder: &mut F) -> ty::Generics {
+        ty::Generics {
+            type_param_defs: self.type_param_defs.fold_with(folder),
+            region_param_defs: self.region_param_defs.fold_with(folder)
+        }
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////
+// "super" routines: these are the default implementations for TypeFolder.
+//
+// They should invoke `foo.fold_with()` to do recursive folding.
+
 pub fn super_fold_ty<T:TypeFolder>(this: &mut T,
                                    t: ty::t)
                                    -> ty::t {
-    let sty = this.fold_sty(&ty::get(t).sty);
+    let sty = ty::get(t).sty.fold_with(this);
     ty::mk_t(this.tcx(), sty)
 }
 
@@ -102,36 +285,58 @@ pub fn super_fold_substs<T:TypeFolder>(this: &mut T,
             ty::ErasedRegions
         }
         ty::NonerasedRegions(ref regions) => {
-            ty::NonerasedRegions(regions.map(|r| this.fold_region(*r)))
+            ty::NonerasedRegions(regions.fold_with(this))
         }
     };
 
     ty::substs { regions: regions,
-                 self_ty: fold_opt_ty(this, substs.self_ty),
-                 tps: fold_ty_vec(this, substs.tps.as_slice()), }
+                 self_ty: substs.self_ty.fold_with(this),
+                 tps: substs.tps.fold_with(this) }
 }
 
 pub fn super_fold_sig<T:TypeFolder>(this: &mut T,
                                     sig: &ty::FnSig)
                                     -> ty::FnSig {
     ty::FnSig { binder_id: sig.binder_id,
-                inputs: fold_ty_vec(this, sig.inputs.as_slice()),
-                output: this.fold_ty(sig.output),
+                inputs: sig.inputs.fold_with(this),
+                output: sig.output.fold_with(this),
                 variadic: sig.variadic }
 }
 
+pub fn super_fold_bare_fn_ty<T:TypeFolder>(this: &mut T,
+                                           fty: &ty::BareFnTy)
+                                           -> ty::BareFnTy
+{
+    ty::BareFnTy { sig: fty.sig.fold_with(this),
+                   abi: fty.abi,
+                   fn_style: fty.fn_style }
+}
+
+pub fn super_fold_closure_ty<T:TypeFolder>(this: &mut T,
+                                           fty: &ty::ClosureTy)
+                                           -> ty::ClosureTy
+{
+    ty::ClosureTy {
+        store: fty.store.fold_with(this),
+        sig: fty.sig.fold_with(this),
+        fn_style: fty.fn_style,
+        onceness: fty.onceness,
+        bounds: fty.bounds,
+    }
+}
+
 pub fn super_fold_trait_ref<T:TypeFolder>(this: &mut T,
                                           t: &ty::TraitRef)
                                           -> ty::TraitRef {
     ty::TraitRef {
         def_id: t.def_id,
-        substs: this.fold_substs(&t.substs)
+        substs: t.substs.fold_with(this),
     }
 }
 
 pub fn super_fold_mt<T:TypeFolder>(this: &mut T,
                                    mt: &ty::mt) -> ty::mt {
-    ty::mt {ty: this.fold_ty(mt.ty),
+    ty::mt {ty: mt.ty.fold_with(this),
             mutbl: mt.mutbl}
 }
 
@@ -139,19 +344,19 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
                                     sty: &ty::sty) -> ty::sty {
     match *sty {
         ty::ty_box(typ) => {
-            ty::ty_box(this.fold_ty(typ))
+            ty::ty_box(typ.fold_with(this))
         }
         ty::ty_uniq(typ) => {
-            ty::ty_uniq(this.fold_ty(typ))
+            ty::ty_uniq(typ.fold_with(this))
         }
         ty::ty_ptr(ref tm) => {
-            ty::ty_ptr(this.fold_mt(tm))
+            ty::ty_ptr(tm.fold_with(this))
         }
         ty::ty_vec(ref tm, sz) => {
-            ty::ty_vec(this.fold_mt(tm), sz)
+            ty::ty_vec(tm.fold_with(this), sz)
         }
         ty::ty_enum(tid, ref substs) => {
-            ty::ty_enum(tid, this.fold_substs(substs))
+            ty::ty_enum(tid, substs.fold_with(this))
         }
         ty::ty_trait(box ty::TyTrait {
                 def_id,
@@ -161,28 +366,25 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
             }) => {
             ty::ty_trait(box ty::TyTrait {
                 def_id: def_id,
-                substs: this.fold_substs(substs),
-                store: this.fold_trait_store(store),
+                substs: substs.fold_with(this),
+                store: store.fold_with(this),
                 bounds: bounds
             })
         }
         ty::ty_tup(ref ts) => {
-            ty::ty_tup(fold_ty_vec(this, ts.as_slice()))
+            ty::ty_tup(ts.fold_with(this))
         }
         ty::ty_bare_fn(ref f) => {
-            ty::ty_bare_fn(this.fold_bare_fn_ty(f))
+            ty::ty_bare_fn(f.fold_with(this))
         }
         ty::ty_closure(ref f) => {
-            ty::ty_closure(box this.fold_closure_ty(*f))
+            ty::ty_closure(box f.fold_with(this))
         }
         ty::ty_rptr(r, ref tm) => {
-            ty::ty_rptr(this.fold_region(r),
-                        ty::mt {ty: this.fold_ty(tm.ty),
-                                mutbl: tm.mutbl})
+            ty::ty_rptr(r.fold_with(this), tm.fold_with(this))
         }
         ty::ty_struct(did, ref substs) => {
-            ty::ty_struct(did,
-                          this.fold_substs(substs))
+            ty::ty_struct(did, substs.fold_with(this))
         }
         ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char | ty::ty_str |
         ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
@@ -199,7 +401,7 @@ pub fn super_fold_trait_store<T:TypeFolder>(this: &mut T,
     match trait_store {
         ty::UniqTraitStore => ty::UniqTraitStore,
         ty::RegionTraitStore(r, m) => {
-            ty::RegionTraitStore(this.fold_region(r), m)
+            ty::RegionTraitStore(r.fold_with(this), m)
         }
     }
 }
@@ -209,11 +411,20 @@ pub fn super_fold_autoref<T:TypeFolder>(this: &mut T,
                                         -> ty::AutoRef
 {
     match *autoref {
-        ty::AutoPtr(r, m) => ty::AutoPtr(this.fold_region(r), m),
-        ty::AutoBorrowVec(r, m) => ty::AutoBorrowVec(this.fold_region(r), m),
-        ty::AutoBorrowVecRef(r, m) => ty::AutoBorrowVecRef(this.fold_region(r), m),
+        ty::AutoPtr(r, m) => ty::AutoPtr(r.fold_with(this), m),
+        ty::AutoBorrowVec(r, m) => ty::AutoBorrowVec(r.fold_with(this), m),
+        ty::AutoBorrowVecRef(r, m) => ty::AutoBorrowVecRef(r.fold_with(this), m),
         ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
-        ty::AutoBorrowObj(r, m) => ty::AutoBorrowObj(this.fold_region(r), m),
+        ty::AutoBorrowObj(r, m) => ty::AutoBorrowObj(r.fold_with(this), m),
+    }
+}
+
+pub fn super_fold_item_substs<T:TypeFolder>(this: &mut T,
+                                            substs: ty::ItemSubsts)
+                                            -> ty::ItemSubsts
+{
+    ty::ItemSubsts {
+        substs: substs.substs.fold_with(this),
     }
 }
 
index 472386209e399291ce9f0bbd3deef550f5f2966e..22a8168ecaad112b79d9244590ac4f3573044475 100644 (file)
@@ -3963,10 +3963,12 @@ pub fn instantiate_path(fcx: &FnCtxt,
         (tps, regions)
     };
 
+    let substs = substs { regions: regions,
+                          self_ty: None,
+                          tps: tps };
+
     fcx.write_ty_substs(node_id, tpt.ty, ty::ItemSubsts {
-        substs: substs { regions: regions,
-                         self_ty: None,
-                         tps: tps }
+        substs: substs,
     });
 
     debug!("<<<");
index 8c7a3fed21b4ec212fb79d5822dc599ff3a02cd6..993a678bd267e35a8425b537f687099df3f30816 100644 (file)
@@ -15,7 +15,7 @@
 
 use middle::pat_util;
 use middle::ty;
-use middle::ty_fold::TypeFolder;
+use middle::ty_fold::{TypeFolder,TypeFoldable};
 use middle::typeck::astconv::AstConv;
 use middle::typeck::check::FnCtxt;
 use middle::typeck::infer::{force_all, resolve_all, resolve_region};
@@ -23,7 +23,6 @@
 use middle::typeck::infer;
 use middle::typeck::impl_res;
 use middle::typeck::{MethodCall, MethodCallee};
-use middle::typeck::{vtable_origin, vtable_static, vtable_param};
 use middle::typeck::write_substs_to_tcx;
 use middle::typeck::write_ty_to_tcx;
 use util::ppaux::Repr;
@@ -355,77 +354,9 @@ trait ResolveIn {
     fn resolve_in(&self, resolver: &mut Resolver) -> Self;
 }
 
-impl<T:ResolveIn> ResolveIn for Option<T> {
-    fn resolve_in(&self, resolver: &mut Resolver) -> Option<T> {
-        self.as_ref().map(|t| t.resolve_in(resolver))
-    }
-}
-
-impl<T:ResolveIn> ResolveIn for Vec<T> {
-    fn resolve_in(&self, resolver: &mut Resolver) -> Vec<T> {
-        self.iter().map(|t| t.resolve_in(resolver)).collect()
-    }
-}
-
-impl ResolveIn for ty::TraitStore {
-    fn resolve_in(&self, resolver: &mut Resolver) -> ty::TraitStore {
-        resolver.fold_trait_store(*self)
-    }
-}
-
-impl ResolveIn for ty::t {
-    fn resolve_in(&self, resolver: &mut Resolver) -> ty::t {
-        resolver.fold_ty(*self)
-    }
-}
-
-impl ResolveIn for ty::Region {
-    fn resolve_in(&self, resolver: &mut Resolver) -> ty::Region {
-        resolver.fold_region(*self)
-    }
-}
-
-impl ResolveIn for ty::substs {
-    fn resolve_in(&self, resolver: &mut Resolver) -> ty::substs {
-        resolver.fold_substs(self)
-    }
-}
-
-impl ResolveIn for ty::ItemSubsts {
-    fn resolve_in(&self, resolver: &mut Resolver) -> ty::ItemSubsts {
-        ty::ItemSubsts {
-            substs: self.substs.resolve_in(resolver)
-        }
-    }
-}
-
-impl ResolveIn for ty::AutoRef {
-    fn resolve_in(&self, resolver: &mut Resolver) -> ty::AutoRef {
-        resolver.fold_autoref(self)
-    }
-}
-
-impl ResolveIn for vtable_origin {
-    fn resolve_in(&self, resolver: &mut Resolver) -> vtable_origin {
-        match *self {
-            vtable_static(def_id, ref substs, ref origins) => {
-                let r_substs = substs.resolve_in(resolver);
-                let r_origins = origins.resolve_in(resolver);
-                vtable_static(def_id, r_substs, r_origins)
-            }
-            vtable_param(n, b) => {
-                vtable_param(n, b)
-            }
-        }
-    }
-}
-
-impl ResolveIn for impl_res {
-    fn resolve_in(&self, resolver: &mut Resolver) -> impl_res {
-        impl_res {
-            trait_vtables: self.trait_vtables.resolve_in(resolver),
-            self_vtables: self.self_vtables.resolve_in(resolver),
-        }
+impl<T:TypeFoldable> ResolveIn for T {
+    fn resolve_in(&self, resolver: &mut Resolver) -> T {
+        self.fold_with(resolver)
     }
 }