]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/structural_impls.rs
Changed issue number to 36105
[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::subst::Substs;
13 use ty::{self, Lift, Ty, TyCtxt};
14 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
15
16 use std::rc::Rc;
17 use syntax::abi;
18 use syntax::ptr::P;
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<'tcx> Lift<'tcx> for ty::Region {
77     type Lifted = Self;
78     fn lift_to_tcx(&self, _: TyCtxt) -> Option<ty::Region> {
79         Some(*self)
80     }
81 }
82
83 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
84     type Lifted = ty::TraitRef<'tcx>;
85     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
86         tcx.lift(&self.substs).map(|substs| ty::TraitRef {
87             def_id: self.def_id,
88             substs: substs
89         })
90     }
91 }
92
93 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
94     type Lifted = ty::ExistentialTraitRef<'tcx>;
95     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
96         tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef {
97             def_id: self.def_id,
98             substs: substs
99         })
100     }
101 }
102
103 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
104     type Lifted = ty::TraitPredicate<'tcx>;
105     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
106                              -> Option<ty::TraitPredicate<'tcx>> {
107         tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
108             trait_ref: trait_ref
109         })
110     }
111 }
112
113 impl<'a, 'tcx> Lift<'tcx> for ty::EquatePredicate<'a> {
114     type Lifted = ty::EquatePredicate<'tcx>;
115     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
116                              -> Option<ty::EquatePredicate<'tcx>> {
117         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::EquatePredicate(a, b))
118     }
119 }
120
121 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
122     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
123     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
124         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
125     }
126 }
127
128 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
129     type Lifted = ty::ProjectionTy<'tcx>;
130     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
131                              -> Option<ty::ProjectionTy<'tcx>> {
132         tcx.lift(&self.trait_ref).map(|trait_ref| {
133             ty::ProjectionTy {
134                 trait_ref: trait_ref,
135                 item_name: self.item_name
136             }
137         })
138     }
139 }
140
141 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
142     type Lifted = ty::ProjectionPredicate<'tcx>;
143     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
144                              -> Option<ty::ProjectionPredicate<'tcx>> {
145         tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| {
146             ty::ProjectionPredicate {
147                 projection_ty: projection_ty,
148                 ty: ty
149             }
150         })
151     }
152 }
153
154 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
155     type Lifted = ty::ExistentialProjection<'tcx>;
156     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
157         tcx.lift(&(self.trait_ref, self.ty)).map(|(trait_ref, ty)| {
158             ty::ExistentialProjection {
159                 trait_ref: trait_ref,
160                 item_name: self.item_name,
161                 ty: ty
162             }
163         })
164     }
165 }
166
167 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
168     type Lifted = ty::Predicate<'tcx>;
169     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
170         match *self {
171             ty::Predicate::Trait(ref binder) => {
172                 tcx.lift(binder).map(ty::Predicate::Trait)
173             }
174             ty::Predicate::Equate(ref binder) => {
175                 tcx.lift(binder).map(ty::Predicate::Equate)
176             }
177             ty::Predicate::RegionOutlives(ref binder) => {
178                 tcx.lift(binder).map(ty::Predicate::RegionOutlives)
179             }
180             ty::Predicate::TypeOutlives(ref binder) => {
181                 tcx.lift(binder).map(ty::Predicate::TypeOutlives)
182             }
183             ty::Predicate::Projection(ref binder) => {
184                 tcx.lift(binder).map(ty::Predicate::Projection)
185             }
186             ty::Predicate::WellFormed(ty) => {
187                 tcx.lift(&ty).map(ty::Predicate::WellFormed)
188             }
189             ty::Predicate::Rfc1592(box ref a) => {
190                 tcx.lift(a).map(|a| ty::Predicate::Rfc1592(Box::new(a)))
191             }
192             ty::Predicate::ClosureKind(closure_def_id, kind) => {
193                 Some(ty::Predicate::ClosureKind(closure_def_id, kind))
194             }
195             ty::Predicate::ObjectSafe(trait_def_id) => {
196                 Some(ty::Predicate::ObjectSafe(trait_def_id))
197             }
198         }
199     }
200 }
201
202 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
203     type Lifted = ty::Binder<T::Lifted>;
204     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
205         tcx.lift(&self.0).map(|x| ty::Binder(x))
206     }
207 }
208
209 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
210     type Lifted = ty::ClosureSubsts<'tcx>;
211     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
212         tcx.lift(&(self.func_substs, self.upvar_tys)).map(|(substs, upvar_tys)| {
213             ty::ClosureSubsts {
214                 func_substs: substs,
215                 upvar_tys: upvar_tys
216             }
217         })
218     }
219 }
220
221 impl<'a, 'tcx> Lift<'tcx> for ty::ItemSubsts<'a> {
222     type Lifted = ty::ItemSubsts<'tcx>;
223     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
224         tcx.lift(&self.substs).map(|substs| {
225             ty::ItemSubsts {
226                 substs: substs
227             }
228         })
229     }
230 }
231
232 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoRef<'a> {
233     type Lifted = ty::adjustment::AutoRef<'tcx>;
234     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
235         match *self {
236             ty::adjustment::AutoPtr(r, m) => {
237                 tcx.lift(&r).map(|r| ty::adjustment::AutoPtr(r, m))
238             }
239             ty::adjustment::AutoUnsafe(m) => {
240                 Some(ty::adjustment::AutoUnsafe(m))
241             }
242         }
243     }
244 }
245
246 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
247     type Lifted = ty::FnSig<'tcx>;
248     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
249         tcx.lift(&self.inputs[..]).and_then(|inputs| {
250             tcx.lift(&self.output).map(|output| {
251                 ty::FnSig {
252                     inputs: inputs,
253                     output: output,
254                     variadic: self.variadic
255                 }
256             })
257         })
258     }
259 }
260
261 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureTy<'a> {
262     type Lifted = ty::ClosureTy<'tcx>;
263     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
264         tcx.lift(&self.sig).map(|sig| {
265             ty::ClosureTy {
266                 sig: sig,
267                 unsafety: self.unsafety,
268                 abi: self.abi
269             }
270         })
271     }
272 }
273
274 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
275     type Lifted = ty::error::ExpectedFound<T::Lifted>;
276     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
277         tcx.lift(&self.expected).and_then(|expected| {
278             tcx.lift(&self.found).map(|found| {
279                 ty::error::ExpectedFound {
280                     expected: expected,
281                     found: found
282                 }
283             })
284         })
285     }
286 }
287
288 impl<'a, 'tcx> Lift<'tcx> for type_variable::Default<'a> {
289     type Lifted = type_variable::Default<'tcx>;
290     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
291         tcx.lift(&self.ty).map(|ty| {
292             type_variable::Default {
293                 ty: ty,
294                 origin_span: self.origin_span,
295                 def_id: self.def_id
296             }
297         })
298     }
299 }
300
301 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
302     type Lifted = ty::error::TypeError<'tcx>;
303     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
304         use ty::error::TypeError::*;
305
306         Some(match *self {
307             Mismatch => Mismatch,
308             UnsafetyMismatch(x) => UnsafetyMismatch(x),
309             AbiMismatch(x) => AbiMismatch(x),
310             Mutability => Mutability,
311             BoxMutability => BoxMutability,
312             PtrMutability => PtrMutability,
313             RefMutability => RefMutability,
314             VecMutability => VecMutability,
315             TupleSize(x) => TupleSize(x),
316             FixedArraySize(x) => FixedArraySize(x),
317             TyParamSize(x) => TyParamSize(x),
318             ArgCount => ArgCount,
319             RegionsDoesNotOutlive(a, b) => RegionsDoesNotOutlive(a, b),
320             RegionsNotSame(a, b) => RegionsNotSame(a, b),
321             RegionsNoOverlap(a, b) => RegionsNoOverlap(a, b),
322             RegionsInsufficientlyPolymorphic(a, b) => {
323                 RegionsInsufficientlyPolymorphic(a, b)
324             }
325             RegionsOverlyPolymorphic(a, b) => RegionsOverlyPolymorphic(a, b),
326             IntegerAsChar => IntegerAsChar,
327             IntMismatch(x) => IntMismatch(x),
328             FloatMismatch(x) => FloatMismatch(x),
329             Traits(x) => Traits(x),
330             BuiltinBoundsMismatch(x) => BuiltinBoundsMismatch(x),
331             VariadicMismatch(x) => VariadicMismatch(x),
332             CyclicTy => CyclicTy,
333             ConvergenceMismatch(x) => ConvergenceMismatch(x),
334             ProjectionNameMismatched(x) => ProjectionNameMismatched(x),
335             ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
336
337             Sorts(ref x) => return tcx.lift(x).map(Sorts),
338             TyParamDefaultMismatch(ref x) => {
339                 return tcx.lift(x).map(TyParamDefaultMismatch)
340             }
341         })
342     }
343 }
344
345 ///////////////////////////////////////////////////////////////////////////
346 // TypeFoldable implementations.
347 //
348 // Ideally, each type should invoke `folder.fold_foo(self)` and
349 // nothing else. In some cases, though, we haven't gotten around to
350 // adding methods on the `folder` yet, and thus the folding is
351 // hard-coded here. This is less-flexible, because folders cannot
352 // override the behavior, but there are a lot of random types and one
353 // can easily refactor the folding into the TypeFolder trait as
354 // needed.
355
356 macro_rules! CopyImpls {
357     ($($ty:ty),+) => {
358         $(
359             impl<'tcx> TypeFoldable<'tcx> for $ty {
360                 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> $ty {
361                     *self
362                 }
363
364                 fn super_visit_with<F: TypeVisitor<'tcx>>(&self, _: &mut F) -> bool {
365                     false
366                 }
367             }
368         )+
369     }
370 }
371
372 CopyImpls! { (), hir::Unsafety, abi::Abi }
373
374 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
375     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
376         (self.0.fold_with(folder), self.1.fold_with(folder))
377     }
378
379     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
380         self.0.visit_with(visitor) || self.1.visit_with(visitor)
381     }
382 }
383
384 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option<T> {
385     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
386         self.as_ref().map(|t| t.fold_with(folder))
387     }
388
389     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
390         self.iter().any(|t| t.visit_with(visitor))
391     }
392 }
393
394 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
395     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
396         Rc::new((**self).fold_with(folder))
397     }
398
399     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
400         (**self).visit_with(visitor)
401     }
402 }
403
404 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
405     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
406         let content: T = (**self).fold_with(folder);
407         box content
408     }
409
410     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
411         (**self).visit_with(visitor)
412     }
413 }
414
415 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
416     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
417         self.iter().map(|t| t.fold_with(folder)).collect()
418     }
419
420     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
421         self.iter().any(|t| t.visit_with(visitor))
422     }
423 }
424
425 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
426     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
427         ty::Binder(self.0.fold_with(folder))
428     }
429
430     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
431         folder.fold_binder(self)
432     }
433
434     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
435         self.0.visit_with(visitor)
436     }
437
438     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
439         visitor.visit_binder(self)
440     }
441 }
442
443 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for P<[T]> {
444     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
445         self.iter().map(|t| t.fold_with(folder)).collect()
446     }
447
448     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
449         self.iter().any(|t| t.visit_with(visitor))
450     }
451 }
452
453 impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
454     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
455         ty::TraitObject {
456             principal: self.principal.fold_with(folder),
457             region_bound: self.region_bound.fold_with(folder),
458             builtin_bounds: self.builtin_bounds,
459             projection_bounds: self.projection_bounds.fold_with(folder),
460         }
461     }
462
463     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
464         self.principal.visit_with(visitor) ||
465         self.region_bound.visit_with(visitor) ||
466         self.projection_bounds.visit_with(visitor)
467     }
468 }
469
470 impl<'tcx> TypeFoldable<'tcx> for &'tcx [Ty<'tcx>] {
471     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
472         let tys = self.iter().map(|t| t.fold_with(folder)).collect();
473         folder.tcx().mk_type_list(tys)
474     }
475
476     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
477         self.iter().any(|t| t.visit_with(visitor))
478     }
479 }
480
481 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
482     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
483         let sty = match self.sty {
484             ty::TyBox(typ) => ty::TyBox(typ.fold_with(folder)),
485             ty::TyRawPtr(tm) => ty::TyRawPtr(tm.fold_with(folder)),
486             ty::TyArray(typ, sz) => ty::TyArray(typ.fold_with(folder), sz),
487             ty::TySlice(typ) => ty::TySlice(typ.fold_with(folder)),
488             ty::TyEnum(tid, substs) => ty::TyEnum(tid, substs.fold_with(folder)),
489             ty::TyTrait(ref trait_ty) => ty::TyTrait(trait_ty.fold_with(folder)),
490             ty::TyTuple(ts) => ty::TyTuple(ts.fold_with(folder)),
491             ty::TyFnDef(def_id, substs, f) => {
492                 ty::TyFnDef(def_id,
493                             substs.fold_with(folder),
494                             f.fold_with(folder))
495             }
496             ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
497             ty::TyRef(ref r, tm) => {
498                 ty::TyRef(r.fold_with(folder), tm.fold_with(folder))
499             }
500             ty::TyStruct(did, substs) => ty::TyStruct(did, substs.fold_with(folder)),
501             ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)),
502             ty::TyProjection(ref data) => ty::TyProjection(data.fold_with(folder)),
503             ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)),
504             ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
505             ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
506             ty::TyParam(..) | ty::TyNever => self.sty.clone(),
507         };
508         folder.tcx().mk_ty(sty)
509     }
510
511     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
512         folder.fold_ty(*self)
513     }
514
515     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
516         match self.sty {
517             ty::TyBox(typ) => typ.visit_with(visitor),
518             ty::TyRawPtr(ref tm) => tm.visit_with(visitor),
519             ty::TyArray(typ, _sz) => typ.visit_with(visitor),
520             ty::TySlice(typ) => typ.visit_with(visitor),
521             ty::TyEnum(_tid, ref substs) => substs.visit_with(visitor),
522             ty::TyTrait(ref trait_ty) => trait_ty.visit_with(visitor),
523             ty::TyTuple(ts) => ts.visit_with(visitor),
524             ty::TyFnDef(_, substs, ref f) => {
525                 substs.visit_with(visitor) || f.visit_with(visitor)
526             }
527             ty::TyFnPtr(ref f) => f.visit_with(visitor),
528             ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
529             ty::TyStruct(_did, ref substs) => substs.visit_with(visitor),
530             ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
531             ty::TyProjection(ref data) => data.visit_with(visitor),
532             ty::TyAnon(_, ref substs) => substs.visit_with(visitor),
533             ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
534             ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
535             ty::TyParam(..) | ty::TyNever => false,
536         }
537     }
538
539     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
540         visitor.visit_ty(self)
541     }
542 }
543
544 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::BareFnTy<'tcx> {
545     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
546         let fty = ty::BareFnTy {
547             sig: self.sig.fold_with(folder),
548             abi: self.abi,
549             unsafety: self.unsafety
550         };
551         folder.tcx().mk_bare_fn(fty)
552     }
553
554     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
555         folder.fold_bare_fn_ty(self)
556     }
557
558     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
559         self.sig.visit_with(visitor)
560     }
561 }
562
563 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureTy<'tcx> {
564     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
565        ty::ClosureTy {
566             sig: self.sig.fold_with(folder),
567             unsafety: self.unsafety,
568             abi: self.abi,
569         }
570     }
571
572     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
573         folder.fold_closure_ty(self)
574     }
575
576     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
577         self.sig.visit_with(visitor)
578     }
579 }
580
581 impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
582     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
583         ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl }
584     }
585
586     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
587         folder.fold_mt(self)
588     }
589
590     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
591         self.ty.visit_with(visitor)
592     }
593 }
594
595 impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
596     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
597         ty::FnSig { inputs: self.inputs.fold_with(folder),
598                     output: self.output.fold_with(folder),
599                     variadic: self.variadic }
600     }
601
602     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
603         folder.fold_fn_sig(self)
604     }
605
606     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
607         self.inputs.visit_with(visitor) || self.output.visit_with(visitor)
608     }
609 }
610
611 impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> {
612     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
613         ty::TraitRef {
614             def_id: self.def_id,
615             substs: self.substs.fold_with(folder),
616         }
617     }
618
619     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
620         self.substs.visit_with(visitor)
621     }
622 }
623
624 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> {
625     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
626         ty::ExistentialTraitRef {
627             def_id: self.def_id,
628             substs: self.substs.fold_with(folder),
629         }
630     }
631
632     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
633         self.substs.visit_with(visitor)
634     }
635 }
636
637 impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
638     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
639         ty::ImplHeader {
640             impl_def_id: self.impl_def_id,
641             self_ty: self.self_ty.fold_with(folder),
642             trait_ref: self.trait_ref.map(|t| t.fold_with(folder)),
643             predicates: self.predicates.iter().map(|p| p.fold_with(folder)).collect(),
644         }
645     }
646
647     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
648         folder.fold_impl_header(self)
649     }
650
651     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
652         self.self_ty.visit_with(visitor) ||
653             self.trait_ref.map(|r| r.visit_with(visitor)).unwrap_or(false) ||
654             self.predicates.iter().any(|p| p.visit_with(visitor))
655     }
656 }
657
658 impl<'tcx> TypeFoldable<'tcx> for ty::Region {
659     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
660         *self
661     }
662
663     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
664         folder.fold_region(*self)
665     }
666
667     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
668         false
669     }
670
671     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
672         visitor.visit_region(*self)
673     }
674 }
675
676 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Region {
677     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
678         *self
679     }
680
681     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
682         let region = folder.fold_region(**self);
683         folder.tcx().mk_region(region)
684     }
685
686     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
687         false
688     }
689
690     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
691         visitor.visit_region(**self)
692     }
693 }
694
695 impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> {
696     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
697         let types = self.types.fold_with(folder);
698         let regions = self.regions.fold_with(folder);
699         Substs::new(folder.tcx(), types, regions)
700     }
701
702     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
703         folder.fold_substs(self)
704     }
705
706     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
707         self.types.visit_with(visitor) || self.regions.visit_with(visitor)
708     }
709 }
710
711 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
712     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
713         ty::ClosureSubsts {
714             func_substs: self.func_substs.fold_with(folder),
715             upvar_tys: self.upvar_tys.fold_with(folder),
716         }
717     }
718
719     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
720         self.func_substs.visit_with(visitor) || self.upvar_tys.visit_with(visitor)
721     }
722 }
723
724 impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> {
725     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
726         ty::ItemSubsts {
727             substs: self.substs.fold_with(folder),
728         }
729     }
730
731     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
732         self.substs.visit_with(visitor)
733     }
734 }
735
736 impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoRef<'tcx> {
737     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
738         match *self {
739             ty::adjustment::AutoPtr(ref r, m) => {
740                 ty::adjustment::AutoPtr(r.fold_with(folder), m)
741             }
742             ty::adjustment::AutoUnsafe(m) => ty::adjustment::AutoUnsafe(m)
743         }
744     }
745
746     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
747         folder.fold_autoref(self)
748     }
749
750     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
751         match *self {
752             ty::adjustment::AutoPtr(r, _m) => r.visit_with(visitor),
753             ty::adjustment::AutoUnsafe(_m) => false,
754         }
755     }
756 }
757
758 impl<'tcx> TypeFoldable<'tcx> for ty::BuiltinBounds {
759     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
760         *self
761     }
762
763     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
764         false
765     }
766 }
767
768 impl<'tcx> TypeFoldable<'tcx> for ty::TypeParameterDef<'tcx> {
769     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
770         ty::TypeParameterDef {
771             name: self.name,
772             def_id: self.def_id,
773             index: self.index,
774             default: self.default.fold_with(folder),
775             default_def_id: self.default_def_id,
776             object_lifetime_default: self.object_lifetime_default.fold_with(folder),
777         }
778     }
779
780     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
781         self.default.visit_with(visitor) ||
782             self.object_lifetime_default.visit_with(visitor)
783     }
784 }
785
786 impl<'tcx> TypeFoldable<'tcx> for ty::ObjectLifetimeDefault {
787     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
788         match *self {
789             ty::ObjectLifetimeDefault::Ambiguous =>
790                 ty::ObjectLifetimeDefault::Ambiguous,
791
792             ty::ObjectLifetimeDefault::BaseDefault =>
793                 ty::ObjectLifetimeDefault::BaseDefault,
794
795             ty::ObjectLifetimeDefault::Specific(r) =>
796                 ty::ObjectLifetimeDefault::Specific(r.fold_with(folder)),
797         }
798     }
799
800     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
801         match *self {
802             ty::ObjectLifetimeDefault::Specific(r) => r.visit_with(visitor),
803             _ => false,
804         }
805     }
806 }
807
808 impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef {
809     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
810         ty::RegionParameterDef {
811             name: self.name,
812             def_id: self.def_id,
813             index: self.index,
814             bounds: self.bounds.fold_with(folder),
815         }
816     }
817
818     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
819         self.bounds.visit_with(visitor)
820     }
821 }
822
823 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
824     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
825         match *self {
826             ty::Predicate::Trait(ref a) =>
827                 ty::Predicate::Trait(a.fold_with(folder)),
828             ty::Predicate::Rfc1592(ref a) =>
829                 ty::Predicate::Rfc1592(a.fold_with(folder)),
830             ty::Predicate::Equate(ref binder) =>
831                 ty::Predicate::Equate(binder.fold_with(folder)),
832             ty::Predicate::RegionOutlives(ref binder) =>
833                 ty::Predicate::RegionOutlives(binder.fold_with(folder)),
834             ty::Predicate::TypeOutlives(ref binder) =>
835                 ty::Predicate::TypeOutlives(binder.fold_with(folder)),
836             ty::Predicate::Projection(ref binder) =>
837                 ty::Predicate::Projection(binder.fold_with(folder)),
838             ty::Predicate::WellFormed(data) =>
839                 ty::Predicate::WellFormed(data.fold_with(folder)),
840             ty::Predicate::ClosureKind(closure_def_id, kind) =>
841                 ty::Predicate::ClosureKind(closure_def_id, kind),
842             ty::Predicate::ObjectSafe(trait_def_id) =>
843                 ty::Predicate::ObjectSafe(trait_def_id),
844         }
845     }
846
847     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
848         match *self {
849             ty::Predicate::Trait(ref a) => a.visit_with(visitor),
850             ty::Predicate::Rfc1592(ref a) => a.visit_with(visitor),
851             ty::Predicate::Equate(ref binder) => binder.visit_with(visitor),
852             ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor),
853             ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor),
854             ty::Predicate::Projection(ref binder) => binder.visit_with(visitor),
855             ty::Predicate::WellFormed(data) => data.visit_with(visitor),
856             ty::Predicate::ClosureKind(_closure_def_id, _kind) => false,
857             ty::Predicate::ObjectSafe(_trait_def_id) => false,
858         }
859     }
860 }
861
862 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
863     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
864         ty::ProjectionPredicate {
865             projection_ty: self.projection_ty.fold_with(folder),
866             ty: self.ty.fold_with(folder),
867         }
868     }
869
870     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
871         self.projection_ty.visit_with(visitor) || self.ty.visit_with(visitor)
872     }
873 }
874
875 impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> {
876     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
877         ty::ExistentialProjection {
878             trait_ref: self.trait_ref.fold_with(folder),
879             item_name: self.item_name,
880             ty: self.ty.fold_with(folder),
881         }
882     }
883
884     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
885         self.trait_ref.visit_with(visitor) || self.ty.visit_with(visitor)
886     }
887 }
888
889 impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
890     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
891         ty::ProjectionTy {
892             trait_ref: self.trait_ref.fold_with(folder),
893             item_name: self.item_name,
894         }
895     }
896
897     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
898         self.trait_ref.visit_with(visitor)
899     }
900 }
901
902 impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
903     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
904         ty::InstantiatedPredicates {
905             predicates: self.predicates.fold_with(folder),
906         }
907     }
908
909     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
910         self.predicates.visit_with(visitor)
911     }
912 }
913
914 impl<'tcx> TypeFoldable<'tcx> for ty::EquatePredicate<'tcx> {
915     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
916         ty::EquatePredicate(self.0.fold_with(folder),
917                             self.1.fold_with(folder))
918     }
919
920     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
921         self.0.visit_with(visitor) || self.1.visit_with(visitor)
922     }
923 }
924
925 impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
926     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
927         ty::TraitPredicate {
928             trait_ref: self.trait_ref.fold_with(folder)
929         }
930     }
931
932     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
933         self.trait_ref.visit_with(visitor)
934     }
935 }
936
937 impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U>
938     where T : TypeFoldable<'tcx>,
939           U : TypeFoldable<'tcx>,
940 {
941     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
942         ty::OutlivesPredicate(self.0.fold_with(folder),
943                               self.1.fold_with(folder))
944     }
945
946     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
947         self.0.visit_with(visitor) || self.1.visit_with(visitor)
948     }
949 }
950
951 impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
952     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
953         ty::ClosureUpvar {
954             def: self.def,
955             span: self.span,
956             ty: self.ty.fold_with(folder),
957         }
958     }
959
960     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
961         self.ty.visit_with(visitor)
962     }
963 }
964
965 impl<'tcx> TypeFoldable<'tcx> for ty::ParameterEnvironment<'tcx> {
966     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
967         ty::ParameterEnvironment {
968             free_substs: self.free_substs.fold_with(folder),
969             implicit_region_bound: self.implicit_region_bound.fold_with(folder),
970             caller_bounds: self.caller_bounds.fold_with(folder),
971             free_id_outlive: self.free_id_outlive,
972         }
973     }
974
975     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
976         self.free_substs.visit_with(visitor) ||
977             self.implicit_region_bound.visit_with(visitor) ||
978             self.caller_bounds.visit_with(visitor)
979     }
980 }
981
982 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
983     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
984         ty::error::ExpectedFound {
985             expected: self.expected.fold_with(folder),
986             found: self.found.fold_with(folder),
987         }
988     }
989
990     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
991         self.expected.visit_with(visitor) || self.found.visit_with(visitor)
992     }
993 }