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, t: ty::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, r: ty::Region) -> ty::Region {
68 r
69 }
70
71 fn fold_trait_store(&mut self, s: ty::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 t: Option<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 t: ty::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_store: ty::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, ty: ty::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(t: ty::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, ty: ty::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, r: ty::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:- 6250: -> 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:- 5110: 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:- 2librustc/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:- 2librustc/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:- 1886: 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:- 243: -> 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:- 9231: 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)