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