]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/structural_impls.rs
a19eb1d9545a23e8a2e2eb0a8d1fec9a4770e0ae
[rust.git] / src / librustc / ty / structural_impls.rs
1 //! This module contains implements of the `Lift` and `TypeFoldable`
2 //! traits for various types in the Rust compiler. Most are written by
3 //! hand, though we've recently added some macros (e.g.,
4 //! `BraceStructLiftImpl!`) to help with the tedium.
5
6 use crate::mir::ProjectionKind;
7 use crate::mir::interpret::ConstValue;
8 use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
9 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
10 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
11 use smallvec::SmallVec;
12 use crate::mir::interpret;
13
14 use std::marker::PhantomData;
15 use std::rc::Rc;
16
17 ///////////////////////////////////////////////////////////////////////////
18 // Atomic structs
19 //
20 // For things that don't carry any arena-allocated data (and are
21 // copy...), just add them to this list.
22
23 CloneTypeFoldableAndLiftImpls! {
24     (),
25     bool,
26     usize,
27     crate::ty::layout::VariantIdx,
28     u64,
29     String,
30     crate::middle::region::Scope,
31     ::syntax::ast::FloatTy,
32     ::syntax::ast::NodeId,
33     ::syntax_pos::symbol::Symbol,
34     crate::hir::def::Def,
35     crate::hir::def_id::DefId,
36     crate::hir::InlineAsm,
37     crate::hir::MatchSource,
38     crate::hir::Mutability,
39     crate::hir::Unsafety,
40     ::rustc_target::spec::abi::Abi,
41     crate::mir::Local,
42     crate::mir::Promoted,
43     crate::traits::Reveal,
44     crate::ty::adjustment::AutoBorrowMutability,
45     crate::ty::AdtKind,
46     // Including `BoundRegion` is a *bit* dubious, but direct
47     // references to bound region appear in `ty::Error`, and aren't
48     // really meant to be folded. In general, we can only fold a fully
49     // general `Region`.
50     crate::ty::BoundRegion,
51     crate::ty::Placeholder<crate::ty::BoundRegion>,
52     crate::ty::ClosureKind,
53     crate::ty::FreeRegion,
54     crate::ty::InferTy,
55     crate::ty::IntVarValue,
56     crate::ty::ParamConst,
57     crate::ty::ParamTy,
58     crate::ty::UniverseIndex,
59     crate::ty::Variance,
60     ::syntax_pos::Span,
61 }
62
63 ///////////////////////////////////////////////////////////////////////////
64 // Lift implementations
65
66 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
67     type Lifted = (A::Lifted, B::Lifted);
68     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
69         tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
70     }
71 }
72
73 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
74     type Lifted = (A::Lifted, B::Lifted, C::Lifted);
75     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
76         tcx.lift(&self.0).and_then(|a| {
77             tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c)))
78         })
79     }
80 }
81
82 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
83     type Lifted = Option<T::Lifted>;
84     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
85         match *self {
86             Some(ref x) => tcx.lift(x).map(Some),
87             None => Some(None)
88         }
89     }
90 }
91
92 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
93     type Lifted = Result<T::Lifted, E::Lifted>;
94     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
95         match *self {
96             Ok(ref x) => tcx.lift(x).map(Ok),
97             Err(ref e) => tcx.lift(e).map(Err)
98         }
99     }
100 }
101
102 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
103     type Lifted = Box<T::Lifted>;
104     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
105         tcx.lift(&**self).map(Box::new)
106     }
107 }
108
109 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
110     type Lifted = Vec<T::Lifted>;
111     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
112         // type annotation needed to inform `projection_must_outlive`
113         let mut result : Vec<<T as Lift<'tcx>>::Lifted>
114             = Vec::with_capacity(self.len());
115         for x in self {
116             if let Some(value) = tcx.lift(x) {
117                 result.push(value);
118             } else {
119                 return None;
120             }
121         }
122         Some(result)
123     }
124 }
125
126 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
127     type Lifted = Vec<T::Lifted>;
128     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
129         tcx.lift(&self[..])
130     }
131 }
132
133 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
134     type Lifted = IndexVec<I, T::Lifted>;
135     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
136         self.iter()
137             .map(|e| tcx.lift(e))
138             .collect()
139     }
140 }
141
142 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
143     type Lifted = ty::TraitRef<'tcx>;
144     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
145         tcx.lift(&self.substs).map(|substs| ty::TraitRef {
146             def_id: self.def_id,
147             substs,
148         })
149     }
150 }
151
152 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
153     type Lifted = ty::ExistentialTraitRef<'tcx>;
154     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
155         tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef {
156             def_id: self.def_id,
157             substs,
158         })
159     }
160 }
161
162 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
163     type Lifted = ty::TraitPredicate<'tcx>;
164     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
165                              -> Option<ty::TraitPredicate<'tcx>> {
166         tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
167             trait_ref,
168         })
169     }
170 }
171
172 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
173     type Lifted = ty::SubtypePredicate<'tcx>;
174     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
175                              -> Option<ty::SubtypePredicate<'tcx>> {
176         tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
177             a_is_expected: self.a_is_expected,
178             a,
179             b,
180         })
181     }
182 }
183
184 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
185     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
186     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
187         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
188     }
189 }
190
191 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
192     type Lifted = ty::ProjectionTy<'tcx>;
193     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
194                              -> Option<ty::ProjectionTy<'tcx>> {
195         tcx.lift(&self.substs).map(|substs| {
196             ty::ProjectionTy {
197                 item_def_id: self.item_def_id,
198                 substs,
199             }
200         })
201     }
202 }
203
204 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
205     type Lifted = ty::ProjectionPredicate<'tcx>;
206     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
207                              -> Option<ty::ProjectionPredicate<'tcx>> {
208         tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| {
209             ty::ProjectionPredicate {
210                 projection_ty,
211                 ty,
212             }
213         })
214     }
215 }
216
217 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
218     type Lifted = ty::ExistentialProjection<'tcx>;
219     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
220         tcx.lift(&self.substs).map(|substs| {
221             ty::ExistentialProjection {
222                 substs,
223                 ty: tcx.lift(&self.ty).expect("type must lift when substs do"),
224                 item_def_id: self.item_def_id,
225             }
226         })
227     }
228 }
229
230 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
231     type Lifted = ty::Predicate<'tcx>;
232     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
233         match *self {
234             ty::Predicate::Trait(ref binder) => {
235                 tcx.lift(binder).map(ty::Predicate::Trait)
236             }
237             ty::Predicate::Subtype(ref binder) => {
238                 tcx.lift(binder).map(ty::Predicate::Subtype)
239             }
240             ty::Predicate::RegionOutlives(ref binder) => {
241                 tcx.lift(binder).map(ty::Predicate::RegionOutlives)
242             }
243             ty::Predicate::TypeOutlives(ref binder) => {
244                 tcx.lift(binder).map(ty::Predicate::TypeOutlives)
245             }
246             ty::Predicate::Projection(ref binder) => {
247                 tcx.lift(binder).map(ty::Predicate::Projection)
248             }
249             ty::Predicate::WellFormed(ty) => {
250                 tcx.lift(&ty).map(ty::Predicate::WellFormed)
251             }
252             ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
253                 tcx.lift(&closure_substs)
254                    .map(|closure_substs| ty::Predicate::ClosureKind(closure_def_id,
255                                                                     closure_substs,
256                                                                     kind))
257             }
258             ty::Predicate::ObjectSafe(trait_def_id) => {
259                 Some(ty::Predicate::ObjectSafe(trait_def_id))
260             }
261             ty::Predicate::ConstEvaluatable(def_id, substs) => {
262                 tcx.lift(&substs).map(|substs| {
263                     ty::Predicate::ConstEvaluatable(def_id, substs)
264                 })
265             }
266         }
267     }
268 }
269
270 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
271     type Lifted = ty::Binder<T::Lifted>;
272     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
273         tcx.lift(self.skip_binder()).map(ty::Binder::bind)
274     }
275 }
276
277 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
278     type Lifted = ty::ParamEnv<'tcx>;
279     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
280         tcx.lift(&self.caller_bounds).map(|caller_bounds| {
281             ty::ParamEnv {
282                 reveal: self.reveal,
283                 caller_bounds,
284                 def_id: self.def_id,
285             }
286         })
287     }
288 }
289
290 impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
291     type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
292     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
293         tcx.lift(&self.param_env).and_then(|param_env| {
294             tcx.lift(&self.value).map(|value| {
295                 ty::ParamEnvAnd {
296                     param_env,
297                     value,
298                 }
299             })
300         })
301     }
302 }
303
304 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
305     type Lifted = ty::ClosureSubsts<'tcx>;
306     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
307         tcx.lift(&self.substs).map(|substs| {
308             ty::ClosureSubsts { substs }
309         })
310     }
311 }
312
313 impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
314     type Lifted = ty::GeneratorSubsts<'tcx>;
315     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
316         tcx.lift(&self.substs).map(|substs| {
317             ty::GeneratorSubsts { substs }
318         })
319     }
320 }
321
322 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
323     type Lifted = ty::adjustment::Adjustment<'tcx>;
324     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
325         tcx.lift(&self.kind).and_then(|kind| {
326             tcx.lift(&self.target).map(|target| {
327                 ty::adjustment::Adjustment { kind, target }
328             })
329         })
330     }
331 }
332
333 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
334     type Lifted = ty::adjustment::Adjust<'tcx>;
335     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
336         match *self {
337             ty::adjustment::Adjust::NeverToAny =>
338                 Some(ty::adjustment::Adjust::NeverToAny),
339             ty::adjustment::Adjust::ReifyFnPointer =>
340                 Some(ty::adjustment::Adjust::ReifyFnPointer),
341             ty::adjustment::Adjust::UnsafeFnPointer =>
342                 Some(ty::adjustment::Adjust::UnsafeFnPointer),
343             ty::adjustment::Adjust::ClosureFnPointer =>
344                 Some(ty::adjustment::Adjust::ClosureFnPointer),
345             ty::adjustment::Adjust::MutToConstPointer =>
346                 Some(ty::adjustment::Adjust::MutToConstPointer),
347             ty::adjustment::Adjust::Unsize =>
348                 Some(ty::adjustment::Adjust::Unsize),
349             ty::adjustment::Adjust::Deref(ref overloaded) => {
350                 tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
351             }
352             ty::adjustment::Adjust::Borrow(ref autoref) => {
353                 tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow)
354             }
355         }
356     }
357 }
358
359 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
360     type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
361     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
362         tcx.lift(&self.region).map(|region| {
363             ty::adjustment::OverloadedDeref {
364                 region,
365                 mutbl: self.mutbl,
366             }
367         })
368     }
369 }
370
371 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
372     type Lifted = ty::adjustment::AutoBorrow<'tcx>;
373     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
374         match *self {
375             ty::adjustment::AutoBorrow::Ref(r, m) => {
376                 tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
377             }
378             ty::adjustment::AutoBorrow::RawPtr(m) => {
379                 Some(ty::adjustment::AutoBorrow::RawPtr(m))
380             }
381         }
382     }
383 }
384
385 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
386     type Lifted = ty::GenSig<'tcx>;
387     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
388         tcx.lift(&(self.yield_ty, self.return_ty))
389            .map(|(yield_ty, return_ty)| {
390                ty::GenSig {
391                    yield_ty,
392                    return_ty,
393                }
394            })
395     }
396 }
397
398 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
399     type Lifted = ty::FnSig<'tcx>;
400     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
401         tcx.lift(&self.inputs_and_output).map(|x| {
402             ty::FnSig {
403                 inputs_and_output: x,
404                 c_variadic: self.c_variadic,
405                 unsafety: self.unsafety,
406                 abi: self.abi,
407             }
408         })
409     }
410 }
411
412 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
413     type Lifted = ty::error::ExpectedFound<T::Lifted>;
414     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
415         tcx.lift(&self.expected).and_then(|expected| {
416             tcx.lift(&self.found).map(|found| {
417                 ty::error::ExpectedFound {
418                     expected,
419                     found,
420                 }
421             })
422         })
423     }
424 }
425
426 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
427     type Lifted = ty::error::TypeError<'tcx>;
428     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
429         use crate::ty::error::TypeError::*;
430
431         Some(match *self {
432             Mismatch => Mismatch,
433             UnsafetyMismatch(x) => UnsafetyMismatch(x),
434             AbiMismatch(x) => AbiMismatch(x),
435             Mutability => Mutability,
436             TupleSize(x) => TupleSize(x),
437             FixedArraySize(x) => FixedArraySize(x),
438             ArgCount => ArgCount,
439             RegionsDoesNotOutlive(a, b) => {
440                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
441             }
442             RegionsInsufficientlyPolymorphic(a, b) => {
443                 return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
444             }
445             RegionsOverlyPolymorphic(a, b) => {
446                 return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
447             }
448             RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
449             IntMismatch(x) => IntMismatch(x),
450             FloatMismatch(x) => FloatMismatch(x),
451             Traits(x) => Traits(x),
452             VariadicMismatch(x) => VariadicMismatch(x),
453             CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)),
454             ProjectionMismatched(x) => ProjectionMismatched(x),
455             ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
456             Sorts(ref x) => return tcx.lift(x).map(Sorts),
457             ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch)
458         })
459     }
460 }
461
462 impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
463     type Lifted = ty::InstanceDef<'tcx>;
464     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
465         match *self {
466             ty::InstanceDef::Item(def_id) =>
467                 Some(ty::InstanceDef::Item(def_id)),
468             ty::InstanceDef::VtableShim(def_id) =>
469                 Some(ty::InstanceDef::VtableShim(def_id)),
470             ty::InstanceDef::Intrinsic(def_id) =>
471                 Some(ty::InstanceDef::Intrinsic(def_id)),
472             ty::InstanceDef::FnPtrShim(def_id, ref ty) =>
473                 Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)),
474             ty::InstanceDef::Virtual(def_id, n) =>
475                 Some(ty::InstanceDef::Virtual(def_id, n)),
476             ty::InstanceDef::ClosureOnceShim { call_once } =>
477                 Some(ty::InstanceDef::ClosureOnceShim { call_once }),
478             ty::InstanceDef::DropGlue(def_id, ref ty) =>
479                 Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)),
480             ty::InstanceDef::CloneShim(def_id, ref ty) =>
481                 Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)),
482         }
483     }
484 }
485
486 BraceStructLiftImpl! {
487     impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> {
488         type Lifted = ty::TypeAndMut<'tcx>;
489         ty, mutbl
490     }
491 }
492
493 BraceStructLiftImpl! {
494     impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> {
495         type Lifted = ty::Instance<'tcx>;
496         def, substs
497     }
498 }
499
500 BraceStructLiftImpl! {
501     impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> {
502         type Lifted = interpret::GlobalId<'tcx>;
503         instance, promoted
504     }
505 }
506
507 // FIXME(eddyb) this is like what some of the macros above generate,
508 // except that macros *also* generate a foldable impl, which we don't
509 // want (with it we'd risk bypassing `fold_region` / `fold_const`).
510 impl<'tcx> Lift<'tcx> for ty::RegionKind {
511     type Lifted = ty::RegionKind;
512     fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
513         Some(self.clone())
514     }
515 }
516
517 impl<'a, 'tcx> Lift<'tcx> for ty::LazyConst<'a> {
518     type Lifted = ty::LazyConst<'tcx>;
519     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
520         match self {
521             ty::LazyConst::Evaluated(v) => Some(ty::LazyConst::Evaluated(tcx.lift(v)?)),
522             ty::LazyConst::Unevaluated(def_id, substs) => {
523                 Some(ty::LazyConst::Unevaluated(*def_id, tcx.lift(substs)?))
524             }
525         }
526     }
527 }
528
529 BraceStructLiftImpl! {
530     impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
531         type Lifted = ty::Const<'tcx>;
532         val, ty
533     }
534 }
535
536 impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
537     type Lifted = ConstValue<'tcx>;
538     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
539         match *self {
540             ConstValue::Param(param) => Some(ConstValue::Param(param)),
541             ConstValue::Infer(infer) => {
542                 Some(ConstValue::Infer(match infer {
543                     InferConst::Var(vid) => InferConst::Var(vid.lift_to_tcx(tcx)?),
544                     InferConst::Fresh(i) => InferConst::Fresh(i),
545                     InferConst::Canonical(debrujin, var) => InferConst::Canonical(debrujin, var),
546                 }))
547             }
548             ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
549             ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
550             ConstValue::ByRef(ptr, alloc) => Some(ConstValue::ByRef(
551                 ptr, alloc.lift_to_tcx(tcx)?,
552             )),
553         }
554     }
555 }
556
557 impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
558     type Lifted = ConstVid<'tcx>;
559     fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
560         Some(ConstVid {
561             index: self.index,
562             phantom: PhantomData,
563         })
564     }
565 }
566
567 ///////////////////////////////////////////////////////////////////////////
568 // TypeFoldable implementations.
569 //
570 // Ideally, each type should invoke `folder.fold_foo(self)` and
571 // nothing else. In some cases, though, we haven't gotten around to
572 // adding methods on the `folder` yet, and thus the folding is
573 // hard-coded here. This is less-flexible, because folders cannot
574 // override the behavior, but there are a lot of random types and one
575 // can easily refactor the folding into the TypeFolder trait as
576 // needed.
577
578 /// AdtDefs are basically the same as a DefId.
579 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
580     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
581         *self
582     }
583
584     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
585         false
586     }
587 }
588
589 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
590     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
591         (self.0.fold_with(folder), self.1.fold_with(folder))
592     }
593
594     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
595         self.0.visit_with(visitor) || self.1.visit_with(visitor)
596     }
597 }
598
599 EnumTypeFoldableImpl! {
600     impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
601         (Some)(a),
602         (None),
603     } where T: TypeFoldable<'tcx>
604 }
605
606 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
607     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
608         Rc::new((**self).fold_with(folder))
609     }
610
611     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
612         (**self).visit_with(visitor)
613     }
614 }
615
616 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
617     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
618         let content: T = (**self).fold_with(folder);
619         box content
620     }
621
622     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
623         (**self).visit_with(visitor)
624     }
625 }
626
627 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
628     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
629         self.iter().map(|t| t.fold_with(folder)).collect()
630     }
631
632     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
633         self.iter().any(|t| t.visit_with(visitor))
634     }
635 }
636
637 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
638     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
639         self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice()
640     }
641
642     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
643         self.iter().any(|t| t.visit_with(visitor))
644     }
645 }
646
647 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
648     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
649         self.map_bound_ref(|ty| ty.fold_with(folder))
650     }
651
652     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
653         folder.fold_binder(self)
654     }
655
656     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
657         self.skip_binder().visit_with(visitor)
658     }
659
660     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
661         visitor.visit_binder(self)
662     }
663 }
664
665 BraceStructTypeFoldableImpl! {
666     impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { reveal, caller_bounds, def_id }
667 }
668
669 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
670     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
671         let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
672         folder.tcx().intern_existential_predicates(&v)
673     }
674
675     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
676         self.iter().any(|p| p.visit_with(visitor))
677     }
678 }
679
680 EnumTypeFoldableImpl! {
681     impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
682         (ty::ExistentialPredicate::Trait)(a),
683         (ty::ExistentialPredicate::Projection)(a),
684         (ty::ExistentialPredicate::AutoTrait)(a),
685     }
686 }
687
688 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
689     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
690         let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
691         folder.tcx().intern_type_list(&v)
692     }
693
694     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
695         self.iter().any(|t| t.visit_with(visitor))
696     }
697 }
698
699 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind<'tcx>> {
700     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
701         let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
702         folder.tcx().intern_projs(&v)
703     }
704
705     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
706         self.iter().any(|t| t.visit_with(visitor))
707     }
708 }
709
710 impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
711     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
712         use crate::ty::InstanceDef::*;
713         Self {
714             substs: self.substs.fold_with(folder),
715             def: match self.def {
716                 Item(did) => Item(did.fold_with(folder)),
717                 VtableShim(did) => VtableShim(did.fold_with(folder)),
718                 Intrinsic(did) => Intrinsic(did.fold_with(folder)),
719                 FnPtrShim(did, ty) => FnPtrShim(
720                     did.fold_with(folder),
721                     ty.fold_with(folder),
722                 ),
723                 Virtual(did, i) => Virtual(
724                     did.fold_with(folder),
725                     i,
726                 ),
727                 ClosureOnceShim { call_once } => ClosureOnceShim {
728                     call_once: call_once.fold_with(folder),
729                 },
730                 DropGlue(did, ty) => DropGlue(
731                     did.fold_with(folder),
732                     ty.fold_with(folder),
733                 ),
734                 CloneShim(did, ty) => CloneShim(
735                     did.fold_with(folder),
736                     ty.fold_with(folder),
737                 ),
738             },
739         }
740     }
741
742     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
743         use crate::ty::InstanceDef::*;
744         self.substs.visit_with(visitor) ||
745         match self.def {
746             Item(did) | VtableShim(did) | Intrinsic(did) | Virtual(did, _) => {
747                 did.visit_with(visitor)
748             },
749             FnPtrShim(did, ty) | CloneShim(did, ty) => {
750                 did.visit_with(visitor) || ty.visit_with(visitor)
751             },
752             DropGlue(did, ty) => {
753                 did.visit_with(visitor) || ty.visit_with(visitor)
754             },
755             ClosureOnceShim { call_once } => call_once.visit_with(visitor),
756         }
757     }
758 }
759
760 impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
761     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
762         Self {
763             instance: self.instance.fold_with(folder),
764             promoted: self.promoted
765         }
766     }
767
768     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
769         self.instance.visit_with(visitor)
770     }
771 }
772
773 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
774     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
775         let sty = match self.sty {
776             ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
777             ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
778             ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
779             ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)),
780             ty::Dynamic(ref trait_ty, ref region) =>
781                 ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
782             ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)),
783             ty::FnDef(def_id, substs) => {
784                 ty::FnDef(def_id, substs.fold_with(folder))
785             }
786             ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)),
787             ty::Ref(ref r, ty, mutbl) => {
788                 ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl)
789             }
790             ty::Generator(did, substs, movability) => {
791                 ty::Generator(
792                     did,
793                     substs.fold_with(folder),
794                     movability)
795             }
796             ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)),
797             ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)),
798             ty::Projection(ref data) => ty::Projection(data.fold_with(folder)),
799             ty::UnnormalizedProjection(ref data) => {
800                 ty::UnnormalizedProjection(data.fold_with(folder))
801             }
802             ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)),
803
804             ty::Bool |
805             ty::Char |
806             ty::Str |
807             ty::Int(_) |
808             ty::Uint(_) |
809             ty::Float(_) |
810             ty::Error |
811             ty::Infer(_) |
812             ty::Param(..) |
813             ty::Bound(..) |
814             ty::Placeholder(..) |
815             ty::Never |
816             ty::Foreign(..) => return self
817         };
818
819         if self.sty == sty {
820             self
821         } else {
822             folder.tcx().mk_ty(sty)
823         }
824     }
825
826     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
827         folder.fold_ty(*self)
828     }
829
830     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
831         match self.sty {
832             ty::RawPtr(ref tm) => tm.visit_with(visitor),
833             ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor),
834             ty::Slice(typ) => typ.visit_with(visitor),
835             ty::Adt(_, substs) => substs.visit_with(visitor),
836             ty::Dynamic(ref trait_ty, ref reg) =>
837                 trait_ty.visit_with(visitor) || reg.visit_with(visitor),
838             ty::Tuple(ts) => ts.visit_with(visitor),
839             ty::FnDef(_, substs) => substs.visit_with(visitor),
840             ty::FnPtr(ref f) => f.visit_with(visitor),
841             ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor),
842             ty::Generator(_did, ref substs, _) => {
843                 substs.visit_with(visitor)
844             }
845             ty::GeneratorWitness(ref types) => types.visit_with(visitor),
846             ty::Closure(_did, ref substs) => substs.visit_with(visitor),
847             ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => {
848                 data.visit_with(visitor)
849             }
850             ty::Opaque(_, ref substs) => substs.visit_with(visitor),
851
852             ty::Bool |
853             ty::Char |
854             ty::Str |
855             ty::Int(_) |
856             ty::Uint(_) |
857             ty::Float(_) |
858             ty::Error |
859             ty::Infer(_) |
860             ty::Bound(..) |
861             ty::Placeholder(..) |
862             ty::Param(..) |
863             ty::Never |
864             ty::Foreign(..) => false,
865         }
866     }
867
868     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
869         visitor.visit_ty(self)
870     }
871 }
872
873 BraceStructTypeFoldableImpl! {
874     impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
875         ty, mutbl
876     }
877 }
878
879 BraceStructTypeFoldableImpl! {
880     impl<'tcx> TypeFoldable<'tcx> for ty::GenSig<'tcx> {
881         yield_ty, return_ty
882     }
883 }
884
885 BraceStructTypeFoldableImpl! {
886     impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
887         inputs_and_output, c_variadic, unsafety, abi
888     }
889 }
890
891 BraceStructTypeFoldableImpl! {
892     impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { def_id, substs }
893 }
894
895 BraceStructTypeFoldableImpl! {
896     impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> { def_id, substs }
897 }
898
899 BraceStructTypeFoldableImpl! {
900     impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
901         impl_def_id,
902         self_ty,
903         trait_ref,
904         predicates,
905     }
906 }
907
908 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
909     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
910         *self
911     }
912
913     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
914         folder.fold_region(*self)
915     }
916
917     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
918         false
919     }
920
921     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
922         visitor.visit_region(*self)
923     }
924 }
925
926 BraceStructTypeFoldableImpl! {
927     impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
928         substs,
929     }
930 }
931
932 BraceStructTypeFoldableImpl! {
933     impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> {
934         substs,
935     }
936 }
937
938 BraceStructTypeFoldableImpl! {
939     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjustment<'tcx> {
940         kind,
941         target,
942     }
943 }
944
945 EnumTypeFoldableImpl! {
946     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
947         (ty::adjustment::Adjust::NeverToAny),
948         (ty::adjustment::Adjust::ReifyFnPointer),
949         (ty::adjustment::Adjust::UnsafeFnPointer),
950         (ty::adjustment::Adjust::ClosureFnPointer),
951         (ty::adjustment::Adjust::MutToConstPointer),
952         (ty::adjustment::Adjust::Unsize),
953         (ty::adjustment::Adjust::Deref)(a),
954         (ty::adjustment::Adjust::Borrow)(a),
955     }
956 }
957
958 BraceStructTypeFoldableImpl! {
959     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
960         region, mutbl,
961     }
962 }
963
964 EnumTypeFoldableImpl! {
965     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
966         (ty::adjustment::AutoBorrow::Ref)(a, b),
967         (ty::adjustment::AutoBorrow::RawPtr)(m),
968     }
969 }
970
971 BraceStructTypeFoldableImpl! {
972     impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
973         parent, predicates
974     }
975 }
976
977 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
978     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
979         let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
980         folder.tcx().intern_predicates(&v)
981     }
982
983     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
984         self.iter().any(|p| p.visit_with(visitor))
985     }
986 }
987
988 EnumTypeFoldableImpl! {
989     impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
990         (ty::Predicate::Trait)(a),
991         (ty::Predicate::Subtype)(a),
992         (ty::Predicate::RegionOutlives)(a),
993         (ty::Predicate::TypeOutlives)(a),
994         (ty::Predicate::Projection)(a),
995         (ty::Predicate::WellFormed)(a),
996         (ty::Predicate::ClosureKind)(a, b, c),
997         (ty::Predicate::ObjectSafe)(a),
998         (ty::Predicate::ConstEvaluatable)(a, b),
999     }
1000 }
1001
1002 BraceStructTypeFoldableImpl! {
1003     impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
1004         projection_ty, ty
1005     }
1006 }
1007
1008 BraceStructTypeFoldableImpl! {
1009     impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> {
1010         ty, substs, item_def_id
1011     }
1012 }
1013
1014 BraceStructTypeFoldableImpl! {
1015     impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
1016         substs, item_def_id
1017     }
1018 }
1019
1020 BraceStructTypeFoldableImpl! {
1021     impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
1022         predicates
1023     }
1024 }
1025
1026 BraceStructTypeFoldableImpl! {
1027     impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> {
1028         param_env, value
1029     } where T: TypeFoldable<'tcx>
1030 }
1031
1032 BraceStructTypeFoldableImpl! {
1033     impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
1034         a_is_expected, a, b
1035     }
1036 }
1037
1038 BraceStructTypeFoldableImpl! {
1039     impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
1040         trait_ref
1041     }
1042 }
1043
1044 TupleStructTypeFoldableImpl! {
1045     impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U> {
1046         a, b
1047     } where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>,
1048 }
1049
1050 BraceStructTypeFoldableImpl! {
1051     impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
1052         def, span, ty
1053     }
1054 }
1055
1056 BraceStructTypeFoldableImpl! {
1057     impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
1058         expected, found
1059     } where T: TypeFoldable<'tcx>
1060 }
1061
1062 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
1063     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1064         self.iter().map(|x| x.fold_with(folder)).collect()
1065     }
1066
1067     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1068         self.iter().any(|t| t.visit_with(visitor))
1069     }
1070 }
1071
1072 EnumTypeFoldableImpl! {
1073     impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
1074         (ty::error::TypeError::Mismatch),
1075         (ty::error::TypeError::UnsafetyMismatch)(x),
1076         (ty::error::TypeError::AbiMismatch)(x),
1077         (ty::error::TypeError::Mutability),
1078         (ty::error::TypeError::TupleSize)(x),
1079         (ty::error::TypeError::FixedArraySize)(x),
1080         (ty::error::TypeError::ArgCount),
1081         (ty::error::TypeError::RegionsDoesNotOutlive)(a, b),
1082         (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b),
1083         (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b),
1084         (ty::error::TypeError::RegionsPlaceholderMismatch),
1085         (ty::error::TypeError::IntMismatch)(x),
1086         (ty::error::TypeError::FloatMismatch)(x),
1087         (ty::error::TypeError::Traits)(x),
1088         (ty::error::TypeError::VariadicMismatch)(x),
1089         (ty::error::TypeError::CyclicTy)(t),
1090         (ty::error::TypeError::ProjectionMismatched)(x),
1091         (ty::error::TypeError::ProjectionBoundsLength)(x),
1092         (ty::error::TypeError::Sorts)(x),
1093         (ty::error::TypeError::ExistentialMismatch)(x),
1094     }
1095 }
1096
1097 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> {
1098     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1099         let new = match self {
1100             ty::LazyConst::Evaluated(v) => ty::LazyConst::Evaluated(v.fold_with(folder)),
1101             ty::LazyConst::Unevaluated(def_id, substs) => {
1102                 ty::LazyConst::Unevaluated(*def_id, substs.fold_with(folder))
1103             }
1104         };
1105         folder.tcx().mk_lazy_const(new)
1106     }
1107
1108     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1109         folder.fold_const(*self)
1110     }
1111
1112     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1113         match *self {
1114             ty::LazyConst::Evaluated(c) => c.visit_with(visitor),
1115             ty::LazyConst::Unevaluated(_, substs) => substs.visit_with(visitor),
1116         }
1117     }
1118
1119     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1120         visitor.visit_const(self)
1121     }
1122 }
1123
1124 impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
1125     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1126         let ty = self.ty.fold_with(folder);
1127         let val = self.val.fold_with(folder);
1128         ty::Const {
1129             ty,
1130             val
1131         }
1132     }
1133
1134     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1135         self.ty.visit_with(visitor) || self.val.visit_with(visitor)
1136     }
1137 }
1138
1139 impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
1140     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
1141         *self
1142     }
1143
1144     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
1145         false
1146     }
1147 }