]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/structural_impls.rs
rustdoc: Hide `self: Box<Self>` in list of deref methods
[rust.git] / src / librustc / ty / structural_impls.rs
1 // Copyright 2012-2015 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 use infer::type_variable;
12 use ty::{self, Lift, Ty, TyCtxt};
13 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
14 use rustc_data_structures::accumulate_vec::AccumulateVec;
15 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
16
17 use std::rc::Rc;
18 use syntax::abi;
19
20 use hir;
21
22 ///////////////////////////////////////////////////////////////////////////
23 // Lift implementations
24
25 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
26     type Lifted = (A::Lifted, B::Lifted);
27     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
28         tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
29     }
30 }
31
32 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
33     type Lifted = Option<T::Lifted>;
34     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
35         match *self {
36             Some(ref x) => tcx.lift(x).map(Some),
37             None => Some(None)
38         }
39     }
40 }
41
42 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
43     type Lifted = Result<T::Lifted, E::Lifted>;
44     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
45         match *self {
46             Ok(ref x) => tcx.lift(x).map(Ok),
47             Err(ref e) => tcx.lift(e).map(Err)
48         }
49     }
50 }
51
52 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
53     type Lifted = Vec<T::Lifted>;
54     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
55         // type annotation needed to inform `projection_must_outlive`
56         let mut result : Vec<<T as Lift<'tcx>>::Lifted>
57             = Vec::with_capacity(self.len());
58         for x in self {
59             if let Some(value) = tcx.lift(x) {
60                 result.push(value);
61             } else {
62                 return None;
63             }
64         }
65         Some(result)
66     }
67 }
68
69 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
70     type Lifted = Vec<T::Lifted>;
71     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
72         tcx.lift(&self[..])
73     }
74 }
75
76 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
77     type Lifted = ty::TraitRef<'tcx>;
78     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
79         tcx.lift(&self.substs).map(|substs| ty::TraitRef {
80             def_id: self.def_id,
81             substs: substs
82         })
83     }
84 }
85
86 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
87     type Lifted = ty::ExistentialTraitRef<'tcx>;
88     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
89         tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef {
90             def_id: self.def_id,
91             substs: substs
92         })
93     }
94 }
95
96 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
97     type Lifted = ty::TraitPredicate<'tcx>;
98     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
99                              -> Option<ty::TraitPredicate<'tcx>> {
100         tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
101             trait_ref: trait_ref
102         })
103     }
104 }
105
106 impl<'a, 'tcx> Lift<'tcx> for ty::EquatePredicate<'a> {
107     type Lifted = ty::EquatePredicate<'tcx>;
108     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
109                              -> Option<ty::EquatePredicate<'tcx>> {
110         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::EquatePredicate(a, b))
111     }
112 }
113
114 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
115     type Lifted = ty::SubtypePredicate<'tcx>;
116     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
117                              -> Option<ty::SubtypePredicate<'tcx>> {
118         tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
119             a_is_expected: self.a_is_expected,
120             a: a,
121             b: b,
122         })
123     }
124 }
125
126 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
127     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
128     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
129         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
130     }
131 }
132
133 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
134     type Lifted = ty::ProjectionTy<'tcx>;
135     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
136                              -> Option<ty::ProjectionTy<'tcx>> {
137         tcx.lift(&self.trait_ref).map(|trait_ref| {
138             ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, self.item_name(tcx))
139         })
140     }
141 }
142
143 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
144     type Lifted = ty::ProjectionPredicate<'tcx>;
145     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
146                              -> Option<ty::ProjectionPredicate<'tcx>> {
147         tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| {
148             ty::ProjectionPredicate {
149                 projection_ty: projection_ty,
150                 ty: ty
151             }
152         })
153     }
154 }
155
156 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
157     type Lifted = ty::ExistentialProjection<'tcx>;
158     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
159         tcx.lift(&(self.trait_ref, self.ty)).map(|(trait_ref, ty)| {
160             ty::ExistentialProjection {
161                 trait_ref: trait_ref,
162                 item_name: self.item_name,
163                 ty: ty
164             }
165         })
166     }
167 }
168
169 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
170     type Lifted = ty::Predicate<'tcx>;
171     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
172         match *self {
173             ty::Predicate::Trait(ref binder) => {
174                 tcx.lift(binder).map(ty::Predicate::Trait)
175             }
176             ty::Predicate::Equate(ref binder) => {
177                 tcx.lift(binder).map(ty::Predicate::Equate)
178             }
179             ty::Predicate::Subtype(ref binder) => {
180                 tcx.lift(binder).map(ty::Predicate::Subtype)
181             }
182             ty::Predicate::RegionOutlives(ref binder) => {
183                 tcx.lift(binder).map(ty::Predicate::RegionOutlives)
184             }
185             ty::Predicate::TypeOutlives(ref binder) => {
186                 tcx.lift(binder).map(ty::Predicate::TypeOutlives)
187             }
188             ty::Predicate::Projection(ref binder) => {
189                 tcx.lift(binder).map(ty::Predicate::Projection)
190             }
191             ty::Predicate::WellFormed(ty) => {
192                 tcx.lift(&ty).map(ty::Predicate::WellFormed)
193             }
194             ty::Predicate::ClosureKind(closure_def_id, kind) => {
195                 Some(ty::Predicate::ClosureKind(closure_def_id, kind))
196             }
197             ty::Predicate::ObjectSafe(trait_def_id) => {
198                 Some(ty::Predicate::ObjectSafe(trait_def_id))
199             }
200         }
201     }
202 }
203
204 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
205     type Lifted = ty::Binder<T::Lifted>;
206     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
207         tcx.lift(&self.0).map(|x| ty::Binder(x))
208     }
209 }
210
211 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
212     type Lifted = ty::ClosureSubsts<'tcx>;
213     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
214         tcx.lift(&self.substs).map(|substs| {
215             ty::ClosureSubsts { substs: substs }
216         })
217     }
218 }
219
220 impl<'a, 'tcx> Lift<'tcx> for ty::ItemSubsts<'a> {
221     type Lifted = ty::ItemSubsts<'tcx>;
222     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
223         tcx.lift(&self.substs).map(|substs| {
224             ty::ItemSubsts {
225                 substs: substs
226             }
227         })
228     }
229 }
230
231 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
232     type Lifted = ty::adjustment::AutoBorrow<'tcx>;
233     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
234         match *self {
235             ty::adjustment::AutoBorrow::Ref(r, m) => {
236                 tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
237             }
238             ty::adjustment::AutoBorrow::RawPtr(m) => {
239                 Some(ty::adjustment::AutoBorrow::RawPtr(m))
240             }
241         }
242     }
243 }
244
245 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
246     type Lifted = ty::FnSig<'tcx>;
247     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
248         tcx.lift(&self.inputs_and_output).map(|x| {
249             ty::FnSig {
250                 inputs_and_output: x,
251                 variadic: self.variadic,
252                 unsafety: self.unsafety,
253                 abi: self.abi,
254             }
255         })
256     }
257 }
258
259 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
260     type Lifted = ty::error::ExpectedFound<T::Lifted>;
261     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
262         tcx.lift(&self.expected).and_then(|expected| {
263             tcx.lift(&self.found).map(|found| {
264                 ty::error::ExpectedFound {
265                     expected: expected,
266                     found: found
267                 }
268             })
269         })
270     }
271 }
272
273 impl<'a, 'tcx> Lift<'tcx> for type_variable::Default<'a> {
274     type Lifted = type_variable::Default<'tcx>;
275     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
276         tcx.lift(&self.ty).map(|ty| {
277             type_variable::Default {
278                 ty: ty,
279                 origin_span: self.origin_span,
280                 def_id: self.def_id
281             }
282         })
283     }
284 }
285
286 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
287     type Lifted = ty::error::TypeError<'tcx>;
288     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
289         use ty::error::TypeError::*;
290
291         Some(match *self {
292             Mismatch => Mismatch,
293             UnsafetyMismatch(x) => UnsafetyMismatch(x),
294             AbiMismatch(x) => AbiMismatch(x),
295             Mutability => Mutability,
296             TupleSize(x) => TupleSize(x),
297             FixedArraySize(x) => FixedArraySize(x),
298             ArgCount => ArgCount,
299             RegionsDoesNotOutlive(a, b) => {
300                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
301             }
302             RegionsNotSame(a, b) => {
303                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsNotSame(a, b))
304             }
305             RegionsNoOverlap(a, b) => {
306                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsNoOverlap(a, b))
307             }
308             RegionsInsufficientlyPolymorphic(a, b, ref c) => {
309                 let c = c.clone();
310                 return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b, c))
311             }
312             RegionsOverlyPolymorphic(a, b, ref c) => {
313                 let c = c.clone();
314                 return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b, c))
315             }
316             IntMismatch(x) => IntMismatch(x),
317             FloatMismatch(x) => FloatMismatch(x),
318             Traits(x) => Traits(x),
319             VariadicMismatch(x) => VariadicMismatch(x),
320             CyclicTy => CyclicTy,
321             ProjectionNameMismatched(x) => ProjectionNameMismatched(x),
322             ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
323
324             Sorts(ref x) => return tcx.lift(x).map(Sorts),
325             TyParamDefaultMismatch(ref x) => {
326                 return tcx.lift(x).map(TyParamDefaultMismatch)
327             }
328             ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch)
329         })
330     }
331 }
332
333 ///////////////////////////////////////////////////////////////////////////
334 // TypeFoldable implementations.
335 //
336 // Ideally, each type should invoke `folder.fold_foo(self)` and
337 // nothing else. In some cases, though, we haven't gotten around to
338 // adding methods on the `folder` yet, and thus the folding is
339 // hard-coded here. This is less-flexible, because folders cannot
340 // override the behavior, but there are a lot of random types and one
341 // can easily refactor the folding into the TypeFolder trait as
342 // needed.
343
344 macro_rules! CopyImpls {
345     ($($ty:ty),+) => {
346         $(
347             impl<'tcx> TypeFoldable<'tcx> for $ty {
348                 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> $ty {
349                     *self
350                 }
351
352                 fn super_visit_with<F: TypeVisitor<'tcx>>(&self, _: &mut F) -> bool {
353                     false
354                 }
355             }
356         )+
357     }
358 }
359
360 CopyImpls! { (), hir::Unsafety, abi::Abi }
361
362 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
363     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
364         (self.0.fold_with(folder), self.1.fold_with(folder))
365     }
366
367     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
368         self.0.visit_with(visitor) || self.1.visit_with(visitor)
369     }
370 }
371
372 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option<T> {
373     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
374         self.as_ref().map(|t| t.fold_with(folder))
375     }
376
377     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
378         self.iter().any(|t| t.visit_with(visitor))
379     }
380 }
381
382 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
383     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
384         Rc::new((**self).fold_with(folder))
385     }
386
387     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
388         (**self).visit_with(visitor)
389     }
390 }
391
392 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
393     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
394         let content: T = (**self).fold_with(folder);
395         box content
396     }
397
398     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
399         (**self).visit_with(visitor)
400     }
401 }
402
403 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
404     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
405         self.iter().map(|t| t.fold_with(folder)).collect()
406     }
407
408     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
409         self.iter().any(|t| t.visit_with(visitor))
410     }
411 }
412
413 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
414     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
415         ty::Binder(self.0.fold_with(folder))
416     }
417
418     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
419         folder.fold_binder(self)
420     }
421
422     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
423         self.0.visit_with(visitor)
424     }
425
426     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
427         visitor.visit_binder(self)
428     }
429 }
430
431 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<ty::ExistentialPredicate<'tcx>> {
432     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
433         let v = self.iter().map(|p| p.fold_with(folder)).collect::<AccumulateVec<[_; 8]>>();
434         folder.tcx().intern_existential_predicates(&v)
435     }
436
437     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
438         self.iter().any(|p| p.visit_with(visitor))
439     }
440 }
441
442 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
443     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self  {
444         use ty::ExistentialPredicate::*;
445         match *self {
446             Trait(ref tr) => Trait(tr.fold_with(folder)),
447             Projection(ref p) => Projection(p.fold_with(folder)),
448             AutoTrait(did) => AutoTrait(did),
449         }
450     }
451
452     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
453         match *self {
454             ty::ExistentialPredicate::Trait(ref tr) => tr.visit_with(visitor),
455             ty::ExistentialPredicate::Projection(ref p) => p.visit_with(visitor),
456             ty::ExistentialPredicate::AutoTrait(_) => false,
457         }
458     }
459 }
460
461 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<Ty<'tcx>> {
462     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
463         let v = self.iter().map(|t| t.fold_with(folder)).collect::<AccumulateVec<[_; 8]>>();
464         folder.tcx().intern_type_list(&v)
465     }
466
467     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
468         self.iter().any(|t| t.visit_with(visitor))
469     }
470 }
471
472 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
473     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
474         let sty = match self.sty {
475             ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)),
476             ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz),
477             ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)),
478             ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)),
479             ty::TyDynamic(ref trait_ty, ref region) =>
480                 ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
481             ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted),
482             ty::TyFnDef(def_id, substs, f) => {
483                 ty::TyFnDef(def_id,
484                             substs.fold_with(folder),
485                             f.fold_with(folder))
486             }
487             ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
488             ty::TyRef(ref r, tm) => {
489                 ty::TyRef(r.fold_with(folder), tm.fold_with(folder))
490             }
491             ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)),
492             ty::TyProjection(ref data) => ty::TyProjection(data.fold_with(folder)),
493             ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)),
494             ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
495             ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
496             ty::TyParam(..) | ty::TyNever => return self
497         };
498
499         if self.sty == sty {
500             self
501         } else {
502             folder.tcx().mk_ty(sty)
503         }
504     }
505
506     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
507         folder.fold_ty(*self)
508     }
509
510     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
511         match self.sty {
512             ty::TyRawPtr(ref tm) => tm.visit_with(visitor),
513             ty::TyArray(typ, _sz) => typ.visit_with(visitor),
514             ty::TySlice(typ) => typ.visit_with(visitor),
515             ty::TyAdt(_, substs) => substs.visit_with(visitor),
516             ty::TyDynamic(ref trait_ty, ref reg) =>
517                 trait_ty.visit_with(visitor) || reg.visit_with(visitor),
518             ty::TyTuple(ts, _) => ts.visit_with(visitor),
519             ty::TyFnDef(_, substs, ref f) => {
520                 substs.visit_with(visitor) || f.visit_with(visitor)
521             }
522             ty::TyFnPtr(ref f) => f.visit_with(visitor),
523             ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
524             ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
525             ty::TyProjection(ref data) => data.visit_with(visitor),
526             ty::TyAnon(_, ref substs) => substs.visit_with(visitor),
527             ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
528             ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
529             ty::TyParam(..) | ty::TyNever => false,
530         }
531     }
532
533     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
534         visitor.visit_ty(self)
535     }
536 }
537
538 impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
539     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
540         ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl }
541     }
542
543     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
544         folder.fold_mt(self)
545     }
546
547     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
548         self.ty.visit_with(visitor)
549     }
550 }
551
552 impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
553     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
554         let inputs_and_output = self.inputs_and_output.fold_with(folder);
555         ty::FnSig {
556             inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output),
557             variadic: self.variadic,
558             unsafety: self.unsafety,
559             abi: self.abi,
560         }
561     }
562
563     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
564         folder.fold_fn_sig(self)
565     }
566
567     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
568         self.inputs().iter().any(|i| i.visit_with(visitor)) ||
569         self.output().visit_with(visitor)
570     }
571 }
572
573 impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
574     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
575         ty::TraitRef {
576             def_id: self.def_id,
577             substs: self.substs.fold_with(folder),
578         }
579     }
580
581     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
582         self.substs.visit_with(visitor)
583     }
584
585     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
586         visitor.visit_trait_ref(*self)
587     }
588 }
589
590 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> {
591     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
592         ty::ExistentialTraitRef {
593             def_id: self.def_id,
594             substs: self.substs.fold_with(folder),
595         }
596     }
597
598     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
599         self.substs.visit_with(visitor)
600     }
601 }
602
603 impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
604     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
605         ty::ImplHeader {
606             impl_def_id: self.impl_def_id,
607             self_ty: self.self_ty.fold_with(folder),
608             trait_ref: self.trait_ref.map(|t| t.fold_with(folder)),
609             predicates: self.predicates.iter().map(|p| p.fold_with(folder)).collect(),
610         }
611     }
612
613     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
614         folder.fold_impl_header(self)
615     }
616
617     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
618         self.self_ty.visit_with(visitor) ||
619             self.trait_ref.map(|r| r.visit_with(visitor)).unwrap_or(false) ||
620             self.predicates.iter().any(|p| p.visit_with(visitor))
621     }
622 }
623
624 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
625     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
626         *self
627     }
628
629     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
630         folder.fold_region(*self)
631     }
632
633     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
634         false
635     }
636
637     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
638         visitor.visit_region(*self)
639     }
640 }
641
642 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
643     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
644         ty::ClosureSubsts {
645             substs: self.substs.fold_with(folder),
646         }
647     }
648
649     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
650         self.substs.visit_with(visitor)
651     }
652 }
653
654 impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> {
655     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
656         ty::ItemSubsts {
657             substs: self.substs.fold_with(folder),
658         }
659     }
660
661     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
662         self.substs.visit_with(visitor)
663     }
664 }
665
666 impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
667     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
668         match *self {
669             ty::adjustment::AutoBorrow::Ref(ref r, m) => {
670                 ty::adjustment::AutoBorrow::Ref(r.fold_with(folder), m)
671             }
672             ty::adjustment::AutoBorrow::RawPtr(m) => ty::adjustment::AutoBorrow::RawPtr(m)
673         }
674     }
675
676     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
677         folder.fold_autoref(self)
678     }
679
680     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
681         match *self {
682             ty::adjustment::AutoBorrow::Ref(r, _m) => r.visit_with(visitor),
683             ty::adjustment::AutoBorrow::RawPtr(_m) => false,
684         }
685     }
686 }
687
688 impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
689     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
690         ty::GenericPredicates {
691             parent: self.parent,
692             predicates: self.predicates.fold_with(folder),
693         }
694     }
695
696     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
697         self.predicates.visit_with(visitor)
698     }
699 }
700
701 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
702     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
703         match *self {
704             ty::Predicate::Trait(ref a) =>
705                 ty::Predicate::Trait(a.fold_with(folder)),
706             ty::Predicate::Equate(ref binder) =>
707                 ty::Predicate::Equate(binder.fold_with(folder)),
708             ty::Predicate::Subtype(ref binder) =>
709                 ty::Predicate::Subtype(binder.fold_with(folder)),
710             ty::Predicate::RegionOutlives(ref binder) =>
711                 ty::Predicate::RegionOutlives(binder.fold_with(folder)),
712             ty::Predicate::TypeOutlives(ref binder) =>
713                 ty::Predicate::TypeOutlives(binder.fold_with(folder)),
714             ty::Predicate::Projection(ref binder) =>
715                 ty::Predicate::Projection(binder.fold_with(folder)),
716             ty::Predicate::WellFormed(data) =>
717                 ty::Predicate::WellFormed(data.fold_with(folder)),
718             ty::Predicate::ClosureKind(closure_def_id, kind) =>
719                 ty::Predicate::ClosureKind(closure_def_id, kind),
720             ty::Predicate::ObjectSafe(trait_def_id) =>
721                 ty::Predicate::ObjectSafe(trait_def_id),
722         }
723     }
724
725     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
726         match *self {
727             ty::Predicate::Trait(ref a) => a.visit_with(visitor),
728             ty::Predicate::Equate(ref binder) => binder.visit_with(visitor),
729             ty::Predicate::Subtype(ref binder) => binder.visit_with(visitor),
730             ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor),
731             ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
732             ty::Predicate::Projection(ref binder) => binder.visit_with(visitor),
733             ty::Predicate::WellFormed(data) => data.visit_with(visitor),
734             ty::Predicate::ClosureKind(_closure_def_id, _kind) => false,
735             ty::Predicate::ObjectSafe(_trait_def_id) => false,
736         }
737     }
738 }
739
740 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
741     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
742         ty::ProjectionPredicate {
743             projection_ty: self.projection_ty.fold_with(folder),
744             ty: self.ty.fold_with(folder),
745         }
746     }
747
748     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
749         self.projection_ty.visit_with(visitor) || self.ty.visit_with(visitor)
750     }
751 }
752
753 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> {
754     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
755         ty::ExistentialProjection {
756             trait_ref: self.trait_ref.fold_with(folder),
757             item_name: self.item_name,
758             ty: self.ty.fold_with(folder),
759         }
760     }
761
762     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
763         self.trait_ref.visit_with(visitor) || self.ty.visit_with(visitor)
764     }
765 }
766
767 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
768     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
769         ty::ProjectionTy {
770             trait_ref: self.trait_ref.fold_with(folder),
771             item_def_id: self.item_def_id,
772         }
773     }
774
775     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
776         self.trait_ref.visit_with(visitor)
777     }
778 }
779
780 impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
781     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
782         ty::InstantiatedPredicates {
783             predicates: self.predicates.fold_with(folder),
784         }
785     }
786
787     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
788         self.predicates.visit_with(visitor)
789     }
790 }
791
792 impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> {
793     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
794         ty::EquatePredicate(self.0.fold_with(folder), self.1.fold_with(folder))
795     }
796
797     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
798         self.0.visit_with(visitor) || self.1.visit_with(visitor)
799     }
800 }
801
802 impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
803     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
804         ty::SubtypePredicate {
805             a_is_expected: self.a_is_expected,
806             a: self.a.fold_with(folder),
807             b: self.b.fold_with(folder)
808         }
809     }
810
811     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
812         self.a.visit_with(visitor) || self.b.visit_with(visitor)
813     }
814 }
815
816 impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
817     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
818         ty::TraitPredicate {
819             trait_ref: self.trait_ref.fold_with(folder)
820         }
821     }
822
823     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
824         self.trait_ref.visit_with(visitor)
825     }
826 }
827
828 impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
829     where T : TypeFoldable<'tcx>,
830           U : TypeFoldable<'tcx>,
831 {
832     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
833         ty::OutlivesPredicate(self.0.fold_with(folder),
834                               self.1.fold_with(folder))
835     }
836
837     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
838         self.0.visit_with(visitor) || self.1.visit_with(visitor)
839     }
840 }
841
842 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
843     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
844         ty::ClosureUpvar {
845             def: self.def,
846             span: self.span,
847             ty: self.ty.fold_with(folder),
848         }
849     }
850
851     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
852         self.ty.visit_with(visitor)
853     }
854 }
855
856 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
857     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
858         ty::error::ExpectedFound {
859             expected: self.expected.fold_with(folder),
860             found: self.found.fold_with(folder),
861         }
862     }
863
864     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
865         self.expected.visit_with(visitor) || self.found.visit_with(visitor)
866     }
867 }
868
869 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
870     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
871         self.iter().map(|x| x.fold_with(folder)).collect()
872     }
873
874     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
875         self.iter().any(|t| t.visit_with(visitor))
876     }
877 }