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