(index<- )        ./librustc/middle/ty_fold.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  // Generalized type folding mechanism.
  12  
  13  use middle::ty;
  14  use util::ppaux::Repr;
  15  
  16  pub trait TypeFolder {
  17      fn tcx<'a>(&'a self) -> &'a ty::ctxt;
  18  
  19      fn fold_ty(&mut self, tty::t) -> ty::t {
  20          super_fold_ty(self, t)
  21      }
  22  
  23      fn fold_mt(&mut self, t&ty::mt) -> ty::mt {
  24          super_fold_mt(self, t)
  25      }
  26  
  27      fn fold_trait_ref(&mut self, t&ty::TraitRef) -> ty::TraitRef {
  28          super_fold_trait_ref(self, t)
  29      }
  30  
  31      fn fold_sty(&mut self, sty&ty::sty) -> ty::sty {
  32          super_fold_sty(self, sty)
  33      }
  34  
  35      fn fold_substs(&mut self,
  36                     substs&ty::substs)
  37                     -> ty::substs {
  38          super_fold_substs(self, substs)
  39      }
  40  
  41      fn fold_sig(&mut self,
  42                  sig&ty::FnSig)
  43                  -> ty::FnSig {
  44          super_fold_sig(self, sig)
  45      }
  46  
  47      fn fold_bare_fn_ty(&mut self,
  48                         fty&ty::BareFnTy)
  49                         -> ty::BareFnTy {
  50          ty::BareFnTy { sig: self.fold_sig(&fty.sig),
  51                         abi: fty.abi,
  52                         fn_style: fty.fn_style }
  53      }
  54  
  55      fn fold_closure_ty(&mut self,
  56                         fty&ty::ClosureTy)
  57                         -> ty::ClosureTy {
  58          ty::ClosureTy {
  59              store: self.fold_trait_store(fty.store),
  60              sig: self.fold_sig(&fty.sig),
  61              fn_style: fty.fn_style,
  62              onceness: fty.onceness,
  63              bounds: fty.bounds,
  64          }
  65      }
  66  
  67      fn fold_region(&mut self, rty::Region) -> ty::Region {
  68          r
  69      }
  70  
  71      fn fold_trait_store(&mut self, sty::TraitStore) -> ty::TraitStore {
  72          super_fold_trait_store(self, s)
  73      }
  74  
  75      fn fold_autoref(&mut self, ar&ty::AutoRef) -> ty::AutoRef {
  76          super_fold_autoref(self, ar)
  77      }
  78  }
  79  
  80  pub fn fold_opt_ty<T:TypeFolder>(this: &mut T,
  81                                   tOption<ty::t>)
  82                                   -> Option<ty::t> {
  83      t.map(|t| this.fold_ty(t))
  84  }
  85  
  86  pub fn fold_ty_vec<T:TypeFolder>(this: &mut T, tys: &[ty::t]) -> Vec<ty::t> {
  87      tys.iter().map(|t| this.fold_ty(*t)).collect()
  88  }
  89  
  90  pub fn super_fold_ty<T:TypeFolder>(this: &mut T,
  91                                     tty::t)
  92                                     -> ty::t {
  93      let sty = this.fold_sty(&ty::get(t).sty);
  94      ty::mk_t(this.tcx(), sty)
  95  }
  96  
  97  pub fn super_fold_substs<T:TypeFolder>(this: &mut T,
  98                                         substs: &ty::substs)
  99                                         -> ty::substs {
 100      let regions = match substs.regions {
 101          ty::ErasedRegions => {
 102              ty::ErasedRegions
 103          }
 104          ty::NonerasedRegions(ref regions) => {
 105              ty::NonerasedRegions(regions.map(|r| this.fold_region(*r)))
 106          }
 107      };
 108  
 109      ty::substs { regions: regions,
 110                   self_ty: fold_opt_ty(this, substs.self_ty),
 111                   tps: fold_ty_vec(this, substs.tps.as_slice()), }
 112  }
 113  
 114  pub fn super_fold_sig<T:TypeFolder>(this: &mut T,
 115                                      sig: &ty::FnSig)
 116                                      -> ty::FnSig {
 117      ty::FnSig { binder_id: sig.binder_id,
 118                  inputs: fold_ty_vec(this, sig.inputs.as_slice()),
 119                  output: this.fold_ty(sig.output),
 120                  variadic: sig.variadic }
 121  }
 122  
 123  pub fn super_fold_trait_ref<T:TypeFolder>(this: &mut T,
 124                                            t: &ty::TraitRef)
 125                                            -> ty::TraitRef {
 126      ty::TraitRef {
 127          def_id: t.def_id,
 128          substs: this.fold_substs(&t.substs)
 129      }
 130  }
 131  
 132  pub fn super_fold_mt<T:TypeFolder>(this: &mut T,
 133                                     mt: &ty::mt) -> ty::mt {
 134      ty::mt {ty: this.fold_ty(mt.ty),
 135              mutbl: mt.mutbl}
 136  }
 137  
 138  pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
 139                                      sty: &ty::sty) -> ty::sty {
 140      match *sty {
 141          ty::ty_box(typ) => {
 142              ty::ty_box(this.fold_ty(typ))
 143          }
 144          ty::ty_uniq(typ) => {
 145              ty::ty_uniq(this.fold_ty(typ))
 146          }
 147          ty::ty_ptr(ref tm) => {
 148              ty::ty_ptr(this.fold_mt(tm))
 149          }
 150          ty::ty_vec(ref tm, sz) => {
 151              ty::ty_vec(this.fold_mt(tm), sz)
 152          }
 153          ty::ty_enum(tid, ref substs) => {
 154              ty::ty_enum(tid, this.fold_substs(substs))
 155          }
 156          ty::ty_trait(box ty::TyTrait {
 157                  def_id,
 158                  ref substs,
 159                  store,
 160                  bounds
 161              }) => {
 162              ty::ty_trait(box ty::TyTrait {
 163                  def_id: def_id,
 164                  substs: this.fold_substs(substs),
 165                  store: this.fold_trait_store(store),
 166                  bounds: bounds
 167              })
 168          }
 169          ty::ty_tup(ref ts) => {
 170              ty::ty_tup(fold_ty_vec(this, ts.as_slice()))
 171          }
 172          ty::ty_bare_fn(ref f) => {
 173              ty::ty_bare_fn(this.fold_bare_fn_ty(f))
 174          }
 175          ty::ty_closure(ref f) => {
 176              ty::ty_closure(box this.fold_closure_ty(*f))
 177          }
 178          ty::ty_rptr(r, ref tm) => {
 179              ty::ty_rptr(this.fold_region(r),
 180                          ty::mt {ty: this.fold_ty(tm.ty),
 181                                  mutbl: tm.mutbl})
 182          }
 183          ty::ty_struct(did, ref substs) => {
 184              ty::ty_struct(did,
 185                            this.fold_substs(substs))
 186          }
 187          ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char | ty::ty_str |
 188          ty::ty_int(_) | ty::ty_uint(_) | ty::ty_float(_) |
 189          ty::ty_err | ty::ty_infer(_) |
 190          ty::ty_param(..) | ty::ty_self(_) => {
 191              (*sty).clone()
 192          }
 193      }
 194  }
 195  
 196  pub fn super_fold_trait_store<T:TypeFolder>(this: &mut T,
 197                                              trait_storety::TraitStore)
 198                                              -> ty::TraitStore {
 199      match trait_store {
 200          ty::UniqTraitStore => ty::UniqTraitStore,
 201          ty::RegionTraitStore(r, m) => {
 202              ty::RegionTraitStore(this.fold_region(r), m)
 203          }
 204      }
 205  }
 206  
 207  pub fn super_fold_autoref<T:TypeFolder>(this: &mut T,
 208                                          autoref: &ty::AutoRef)
 209                                          -> ty::AutoRef
 210  {
 211      match *autoref {
 212          ty::AutoPtr(r, m) => ty::AutoPtr(this.fold_region(r), m),
 213          ty::AutoBorrowVec(r, m) => ty::AutoBorrowVec(this.fold_region(r), m),
 214          ty::AutoBorrowVecRef(r, m) => ty::AutoBorrowVecRef(this.fold_region(r), m),
 215          ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
 216          ty::AutoBorrowObj(r, m) => ty::AutoBorrowObj(this.fold_region(r), m),
 217      }
 218  }
 219  
 220  ///////////////////////////////////////////////////////////////////////////
 221  // Some sample folders
 222  
 223  pub struct BottomUpFolder<'a> {
 224      pub tcx: &'a ty::ctxt,
 225      pub fldop: |ty::t|: 'a -> ty::t,
 226  }
 227  
 228  impl<'a> TypeFolder for BottomUpFolder<'a> {
 229      fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
 230  
 231      fn fold_ty(&mut self, tyty::t) -> ty::t {
 232          let t1 = super_fold_ty(self, ty);
 233          (self.fldop)(t1)
 234      }
 235  }
 236  
 237  ///////////////////////////////////////////////////////////////////////////
 238  // Region folder
 239  
 240  pub struct RegionFolder<'a> {
 241      tcx: &'a ty::ctxt,
 242      fld_t: |ty::t|: 'a -> ty::t,
 243      fld_r: |ty::Region|: 'a -> ty::Region,
 244  }
 245  
 246  impl<'a> RegionFolder<'a> {
 247      pub fn general(tcx&'a ty::ctxt,
 248                     fld_r|ty::Region|: 'a -> ty::Region,
 249                     fld_t|ty::t|: 'a -> ty::t)
 250                     -> RegionFolder<'a> {
 251          RegionFolder {
 252              tcx: tcx,
 253              fld_t: fld_t,
 254              fld_r: fld_r
 255          }
 256      }
 257  
 258      pub fn regions(tcx&'a ty::ctxt, fld_r|ty::Region|: 'a -> ty::Region)
 259                     -> RegionFolder<'a> {
 260          fn noop(tty::t) -> ty::t { t }
 261  
 262          RegionFolder {
 263              tcx: tcx,
 264              fld_t: noop,
 265              fld_r: fld_r
 266          }
 267      }
 268  }
 269  
 270  impl<'a> TypeFolder for RegionFolder<'a> {
 271      fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
 272  
 273      fn fold_ty(&mut self, tyty::t) -> ty::t {
 274          debug!("RegionFolder.fold_ty({})", ty.repr(self.tcx()));
 275          let t1 = super_fold_ty(self, ty);
 276          (self.fld_t)(t1)
 277      }
 278  
 279      fn fold_region(&mut self, rty::Region) -> ty::Region {
 280          debug!("RegionFolder.fold_region({})", r.repr(self.tcx()));
 281          (self.fld_r)(r)
 282      }
 283  }


librustc/middle/ty_fold.rs:239:1-239:1 -struct- definition:
pub struct RegionFolder<'a> {
    tcx: &'a ty::ctxt,
    fld_t: |ty::t|: 'a -> ty::t,
references:- 6
250:                    -> RegionFolder<'a> {
251:         RegionFolder {
252:             tcx: tcx,
--
262:         RegionFolder {
263:             tcx: tcx,
--
270: impl<'a> TypeFolder for RegionFolder<'a> {
271:     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }


librustc/middle/ty_fold.rs:85:1-85:1 -fn- definition:
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()
}
references:- 5
110:                  self_ty: fold_opt_ty(this, substs.self_ty),
111:                  tps: fold_ty_vec(this, substs.tps.as_slice()), }
112: }
--
117:     ty::FnSig { binder_id: sig.binder_id,
118:                 inputs: fold_ty_vec(this, sig.inputs.as_slice()),
119:                 output: this.fold_ty(sig.output),
librustc/middle/ty.rs:
4158:                 binder_id: ast::DUMMY_NODE_ID,
4159:                 inputs: ty_fold::fold_ty_vec(self, sig.inputs.as_slice()),
4160:                 output: self.fold_ty(sig.output),
librustc/middle/ty_fold.rs:
169:         ty::ty_tup(ref ts) => {
170:             ty::ty_tup(fold_ty_vec(this, ts.as_slice()))
171:         }


librustc/middle/ty_fold.rs:222:1-222:1 -struct- definition:
pub struct BottomUpFolder<'a> {
    pub tcx: &'a ty::ctxt,
    pub fldop: |ty::t|: 'a -> ty::t,
references:- 2
librustc/middle/ty.rs:
1501: pub fn fold_ty(cx: &ctxt, t0: t, fldop: |t| -> t) -> t {
1502:     let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
1503:     f.fold_ty(t0)
librustc/middle/ty_fold.rs:
228: impl<'a> TypeFolder for BottomUpFolder<'a> {
229:     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }


librustc/middle/ty_fold.rs:79:1-79:1 -fn- definition:
pub fn fold_opt_ty<T:TypeFolder>(this: &mut T,
                                 t: Option<ty::t>)
                                 -> Option<ty::t> {
references:- 2
librustc/middle/ty.rs:
4147:             substs { regions: ErasedRegions,
4148:                      self_ty: ty_fold::fold_opt_ty(self, substs.self_ty),
4149:                      tps: ty_fold::fold_ty_vec(self, substs.tps.as_slice()) }
librustc/middle/ty_fold.rs:
109:     ty::substs { regions: regions,
110:                  self_ty: fold_opt_ty(this, substs.self_ty),
111:                  tps: fold_ty_vec(this, substs.tps.as_slice()), }


librustc/middle/ty_fold.rs:15:1-15:1 -trait- definition:
pub trait TypeFolder {
    fn tcx<'a>(&'a self) -> &'a ty::ctxt;
    fn fold_ty(&mut self, t: ty::t) -> ty::t {
references:- 18
86: pub fn fold_ty_vec<T:TypeFolder>(this: &mut T, tys: &[ty::t]) -> Vec<ty::t> {
87:     tys.iter().map(|t| this.fold_ty(*t)).collect()
--
228: impl<'a> TypeFolder for BottomUpFolder<'a> {
229:     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
--
270: impl<'a> TypeFolder for RegionFolder<'a> {
271:     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
librustc/middle/subst.rs:
76: impl<'a> TypeFolder for SubstFolder<'a> {
77:     fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
librustc/middle/typeck/check/writeback.rs:
459: impl<'cx> TypeFolder for Resolver<'cx> {
460:     fn tcx<'a>(&'a self) -> &'a ty::ctxt {
librustc/middle/typeck/check/regionmanip.rs:
96:     impl<'a> TypeFolder for RegionRelator<'a> {
97:         fn tcx<'a>(&'a self) -> &'a ty::ctxt {
librustc/middle/typeck/infer/resolve.rs:
98: impl<'a> ty_fold::TypeFolder for ResolveState<'a> {
99:     fn tcx<'a>(&'a self) -> &'a ty::ctxt {
librustc/middle/ty.rs:
4126:     impl<'a> TypeFolder for TypeNormalizer<'a> {
4127:         fn tcx<'a>(&'a self) -> &'a ctxt { let TypeNormalizer(c) = *self; c }
librustc/middle/ty_fold.rs:
97: pub fn super_fold_substs<T:TypeFolder>(this: &mut T,
98:                                        substs: &ty::substs)


librustc/middle/ty_fold.rs:113:1-113:1 -fn- definition:
pub fn super_fold_sig<T:TypeFolder>(this: &mut T,
                                    sig: &ty::FnSig)
                                    -> ty::FnSig {
references:- 2
43:                 -> ty::FnSig {
44:         super_fold_sig(self, sig)
45:     }
librustc/middle/typeck/check/regionmanip.rs:
40:         });
41:         ty_fold::super_fold_sig(&mut f, fn_sig)
42:     };


librustc/middle/ty_fold.rs:89:1-89:1 -fn- definition:
pub fn super_fold_ty<T:TypeFolder>(this: &mut T,
                                   t: ty::t)
                                   -> ty::t {
references:- 9
231:     fn fold_ty(&mut self, ty: ty::t) -> ty::t {
232:         let t1 = super_fold_ty(self, ty);
233:         (self.fldop)(t1)
librustc/middle/subst.rs:
125:             }
126:             _ => ty_fold::super_fold_ty(self, t)
127:         }
librustc/middle/typeck/check/regionmanip.rs:
105:                     self.stack.push(r);
106:                     ty_fold::super_fold_ty(self, ty);
107:                     self.stack.pop().unwrap();
--
110:                 _ => {
111:                     ty_fold::super_fold_ty(self, ty);
112:                 }
librustc/middle/typeck/infer/resolve.rs:
181:                     self.type_depth += 1;
182:                     let result = ty_fold::super_fold_ty(self, typ);
183:                     self.type_depth -= 1;
librustc/middle/ty.rs:
4135:             let t_norm = ty_fold::super_fold_ty(self, t);
4136:             self.tcx().normalized_cache.borrow_mut().insert(t, t_norm);
librustc/middle/ty_fold.rs:
274:         debug!("RegionFolder.fold_ty({})", ty.repr(self.tcx()));
275:         let t1 = super_fold_ty(self, ty);
276:         (self.fld_t)(t1)