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