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