]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/structural_impls.rs
45db95e2b0f0f0526f982b90fece6eef2d3e5f79
[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, ConstVid, InferConst};
10 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
11 use crate::ty::print::{FmtPrinter, PrintCx, 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::iter;
18 use std::marker::PhantomData;
19 use std::rc::Rc;
20
21 impl fmt::Debug for ty::GenericParamDef {
22     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23         let type_name = match self.kind {
24             ty::GenericParamDefKind::Lifetime => "Lifetime",
25             ty::GenericParamDefKind::Type {..} => "Type",
26             ty::GenericParamDefKind::Const => "Const",
27         };
28         write!(f, "{}({}, {:?}, {})",
29                type_name,
30                self.name,
31                self.def_id,
32                self.index)
33     }
34 }
35
36 impl fmt::Debug for ty::TraitDef {
37     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38         PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
39             cx.print_def_path(self.def_id, None, iter::empty())?;
40             Ok(())
41         })
42     }
43 }
44
45 impl fmt::Debug for ty::AdtDef {
46     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47         PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
48             cx.print_def_path(self.did, None, iter::empty())?;
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.def,
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         // HACK(eddyb) 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.idx)
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::Def,
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::RegionVid,
329     crate::ty::UniverseIndex,
330     crate::ty::Variance,
331     ::syntax_pos::Span,
332 }
333
334 ///////////////////////////////////////////////////////////////////////////
335 // Lift implementations
336
337 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
338     type Lifted = (A::Lifted, B::Lifted);
339     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
340         tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
341     }
342 }
343
344 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
345     type Lifted = (A::Lifted, B::Lifted, C::Lifted);
346     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
347         tcx.lift(&self.0).and_then(|a| {
348             tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c)))
349         })
350     }
351 }
352
353 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
354     type Lifted = Option<T::Lifted>;
355     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
356         match *self {
357             Some(ref x) => tcx.lift(x).map(Some),
358             None => Some(None)
359         }
360     }
361 }
362
363 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
364     type Lifted = Result<T::Lifted, E::Lifted>;
365     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
366         match *self {
367             Ok(ref x) => tcx.lift(x).map(Ok),
368             Err(ref e) => tcx.lift(e).map(Err)
369         }
370     }
371 }
372
373 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
374     type Lifted = Box<T::Lifted>;
375     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
376         tcx.lift(&**self).map(Box::new)
377     }
378 }
379
380 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
381     type Lifted = Vec<T::Lifted>;
382     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
383         // type annotation needed to inform `projection_must_outlive`
384         let mut result : Vec<<T as Lift<'tcx>>::Lifted>
385             = Vec::with_capacity(self.len());
386         for x in self {
387             if let Some(value) = tcx.lift(x) {
388                 result.push(value);
389             } else {
390                 return None;
391             }
392         }
393         Some(result)
394     }
395 }
396
397 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
398     type Lifted = Vec<T::Lifted>;
399     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
400         tcx.lift(&self[..])
401     }
402 }
403
404 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
405     type Lifted = IndexVec<I, T::Lifted>;
406     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
407         self.iter()
408             .map(|e| tcx.lift(e))
409             .collect()
410     }
411 }
412
413 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
414     type Lifted = ty::TraitRef<'tcx>;
415     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
416         tcx.lift(&self.substs).map(|substs| ty::TraitRef {
417             def_id: self.def_id,
418             substs,
419         })
420     }
421 }
422
423 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
424     type Lifted = ty::ExistentialTraitRef<'tcx>;
425     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
426         tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef {
427             def_id: self.def_id,
428             substs,
429         })
430     }
431 }
432
433 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
434     type Lifted = ty::TraitPredicate<'tcx>;
435     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
436                              -> Option<ty::TraitPredicate<'tcx>> {
437         tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
438             trait_ref,
439         })
440     }
441 }
442
443 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
444     type Lifted = ty::SubtypePredicate<'tcx>;
445     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
446                              -> Option<ty::SubtypePredicate<'tcx>> {
447         tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
448             a_is_expected: self.a_is_expected,
449             a,
450             b,
451         })
452     }
453 }
454
455 impl<'tcx, A: Copy+Lift<'tcx>, B: Copy+Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
456     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
457     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
458         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
459     }
460 }
461
462 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
463     type Lifted = ty::ProjectionTy<'tcx>;
464     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
465                              -> Option<ty::ProjectionTy<'tcx>> {
466         tcx.lift(&self.substs).map(|substs| {
467             ty::ProjectionTy {
468                 item_def_id: self.item_def_id,
469                 substs,
470             }
471         })
472     }
473 }
474
475 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
476     type Lifted = ty::ProjectionPredicate<'tcx>;
477     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
478                              -> Option<ty::ProjectionPredicate<'tcx>> {
479         tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| {
480             ty::ProjectionPredicate {
481                 projection_ty,
482                 ty,
483             }
484         })
485     }
486 }
487
488 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
489     type Lifted = ty::ExistentialProjection<'tcx>;
490     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
491         tcx.lift(&self.substs).map(|substs| {
492             ty::ExistentialProjection {
493                 substs,
494                 ty: tcx.lift(&self.ty).expect("type must lift when substs do"),
495                 item_def_id: self.item_def_id,
496             }
497         })
498     }
499 }
500
501 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
502     type Lifted = ty::Predicate<'tcx>;
503     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
504         match *self {
505             ty::Predicate::Trait(ref binder) => {
506                 tcx.lift(binder).map(ty::Predicate::Trait)
507             }
508             ty::Predicate::Subtype(ref binder) => {
509                 tcx.lift(binder).map(ty::Predicate::Subtype)
510             }
511             ty::Predicate::RegionOutlives(ref binder) => {
512                 tcx.lift(binder).map(ty::Predicate::RegionOutlives)
513             }
514             ty::Predicate::TypeOutlives(ref binder) => {
515                 tcx.lift(binder).map(ty::Predicate::TypeOutlives)
516             }
517             ty::Predicate::Projection(ref binder) => {
518                 tcx.lift(binder).map(ty::Predicate::Projection)
519             }
520             ty::Predicate::WellFormed(ty) => {
521                 tcx.lift(&ty).map(ty::Predicate::WellFormed)
522             }
523             ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
524                 tcx.lift(&closure_substs)
525                    .map(|closure_substs| ty::Predicate::ClosureKind(closure_def_id,
526                                                                     closure_substs,
527                                                                     kind))
528             }
529             ty::Predicate::ObjectSafe(trait_def_id) => {
530                 Some(ty::Predicate::ObjectSafe(trait_def_id))
531             }
532             ty::Predicate::ConstEvaluatable(def_id, substs) => {
533                 tcx.lift(&substs).map(|substs| {
534                     ty::Predicate::ConstEvaluatable(def_id, substs)
535                 })
536             }
537         }
538     }
539 }
540
541 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
542     type Lifted = ty::Binder<T::Lifted>;
543     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
544         tcx.lift(self.skip_binder()).map(ty::Binder::bind)
545     }
546 }
547
548 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
549     type Lifted = ty::ParamEnv<'tcx>;
550     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
551         tcx.lift(&self.caller_bounds).map(|caller_bounds| {
552             ty::ParamEnv {
553                 reveal: self.reveal,
554                 caller_bounds,
555                 def_id: self.def_id,
556             }
557         })
558     }
559 }
560
561 impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
562     type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
563     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
564         tcx.lift(&self.param_env).and_then(|param_env| {
565             tcx.lift(&self.value).map(|value| {
566                 ty::ParamEnvAnd {
567                     param_env,
568                     value,
569                 }
570             })
571         })
572     }
573 }
574
575 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
576     type Lifted = ty::ClosureSubsts<'tcx>;
577     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
578         tcx.lift(&self.substs).map(|substs| {
579             ty::ClosureSubsts { substs }
580         })
581     }
582 }
583
584 impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
585     type Lifted = ty::GeneratorSubsts<'tcx>;
586     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
587         tcx.lift(&self.substs).map(|substs| {
588             ty::GeneratorSubsts { substs }
589         })
590     }
591 }
592
593 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
594     type Lifted = ty::adjustment::Adjustment<'tcx>;
595     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
596         tcx.lift(&self.kind).and_then(|kind| {
597             tcx.lift(&self.target).map(|target| {
598                 ty::adjustment::Adjustment { kind, target }
599             })
600         })
601     }
602 }
603
604 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
605     type Lifted = ty::adjustment::Adjust<'tcx>;
606     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
607         match *self {
608             ty::adjustment::Adjust::NeverToAny =>
609                 Some(ty::adjustment::Adjust::NeverToAny),
610             ty::adjustment::Adjust::ReifyFnPointer =>
611                 Some(ty::adjustment::Adjust::ReifyFnPointer),
612             ty::adjustment::Adjust::UnsafeFnPointer =>
613                 Some(ty::adjustment::Adjust::UnsafeFnPointer),
614             ty::adjustment::Adjust::ClosureFnPointer =>
615                 Some(ty::adjustment::Adjust::ClosureFnPointer),
616             ty::adjustment::Adjust::MutToConstPointer =>
617                 Some(ty::adjustment::Adjust::MutToConstPointer),
618             ty::adjustment::Adjust::Unsize =>
619                 Some(ty::adjustment::Adjust::Unsize),
620             ty::adjustment::Adjust::Deref(ref overloaded) => {
621                 tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
622             }
623             ty::adjustment::Adjust::Borrow(ref autoref) => {
624                 tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow)
625             }
626         }
627     }
628 }
629
630 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
631     type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
632     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
633         tcx.lift(&self.region).map(|region| {
634             ty::adjustment::OverloadedDeref {
635                 region,
636                 mutbl: self.mutbl,
637             }
638         })
639     }
640 }
641
642 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
643     type Lifted = ty::adjustment::AutoBorrow<'tcx>;
644     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
645         match *self {
646             ty::adjustment::AutoBorrow::Ref(r, m) => {
647                 tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
648             }
649             ty::adjustment::AutoBorrow::RawPtr(m) => {
650                 Some(ty::adjustment::AutoBorrow::RawPtr(m))
651             }
652         }
653     }
654 }
655
656 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
657     type Lifted = ty::GenSig<'tcx>;
658     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
659         tcx.lift(&(self.yield_ty, self.return_ty))
660            .map(|(yield_ty, return_ty)| {
661                ty::GenSig {
662                    yield_ty,
663                    return_ty,
664                }
665            })
666     }
667 }
668
669 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
670     type Lifted = ty::FnSig<'tcx>;
671     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
672         tcx.lift(&self.inputs_and_output).map(|x| {
673             ty::FnSig {
674                 inputs_and_output: x,
675                 c_variadic: self.c_variadic,
676                 unsafety: self.unsafety,
677                 abi: self.abi,
678             }
679         })
680     }
681 }
682
683 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
684     type Lifted = ty::error::ExpectedFound<T::Lifted>;
685     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
686         tcx.lift(&self.expected).and_then(|expected| {
687             tcx.lift(&self.found).map(|found| {
688                 ty::error::ExpectedFound {
689                     expected,
690                     found,
691                 }
692             })
693         })
694     }
695 }
696
697 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
698     type Lifted = ty::error::TypeError<'tcx>;
699     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
700         use crate::ty::error::TypeError::*;
701
702         Some(match *self {
703             Mismatch => Mismatch,
704             UnsafetyMismatch(x) => UnsafetyMismatch(x),
705             AbiMismatch(x) => AbiMismatch(x),
706             Mutability => Mutability,
707             TupleSize(x) => TupleSize(x),
708             FixedArraySize(x) => FixedArraySize(x),
709             ArgCount => ArgCount,
710             RegionsDoesNotOutlive(a, b) => {
711                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b))
712             }
713             RegionsInsufficientlyPolymorphic(a, b) => {
714                 return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b))
715             }
716             RegionsOverlyPolymorphic(a, b) => {
717                 return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b))
718             }
719             RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
720             IntMismatch(x) => IntMismatch(x),
721             FloatMismatch(x) => FloatMismatch(x),
722             Traits(x) => Traits(x),
723             VariadicMismatch(x) => VariadicMismatch(x),
724             CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)),
725             ProjectionMismatched(x) => ProjectionMismatched(x),
726             ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
727             Sorts(ref x) => return tcx.lift(x).map(Sorts),
728             ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch)
729         })
730     }
731 }
732
733 impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
734     type Lifted = ty::InstanceDef<'tcx>;
735     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
736         match *self {
737             ty::InstanceDef::Item(def_id) =>
738                 Some(ty::InstanceDef::Item(def_id)),
739             ty::InstanceDef::VtableShim(def_id) =>
740                 Some(ty::InstanceDef::VtableShim(def_id)),
741             ty::InstanceDef::Intrinsic(def_id) =>
742                 Some(ty::InstanceDef::Intrinsic(def_id)),
743             ty::InstanceDef::FnPtrShim(def_id, ref ty) =>
744                 Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)),
745             ty::InstanceDef::Virtual(def_id, n) =>
746                 Some(ty::InstanceDef::Virtual(def_id, n)),
747             ty::InstanceDef::ClosureOnceShim { call_once } =>
748                 Some(ty::InstanceDef::ClosureOnceShim { call_once }),
749             ty::InstanceDef::DropGlue(def_id, ref ty) =>
750                 Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)),
751             ty::InstanceDef::CloneShim(def_id, ref ty) =>
752                 Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)),
753         }
754     }
755 }
756
757 BraceStructLiftImpl! {
758     impl<'a, 'tcx> Lift<'tcx> for ty::TypeAndMut<'a> {
759         type Lifted = ty::TypeAndMut<'tcx>;
760         ty, mutbl
761     }
762 }
763
764 BraceStructLiftImpl! {
765     impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> {
766         type Lifted = ty::Instance<'tcx>;
767         def, substs
768     }
769 }
770
771 BraceStructLiftImpl! {
772     impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> {
773         type Lifted = interpret::GlobalId<'tcx>;
774         instance, promoted
775     }
776 }
777
778 // FIXME(eddyb) this is like what some of the macros above generate,
779 // except that macros *also* generate a foldable impl, which we don't
780 // want (with it we'd risk bypassing `fold_region` / `fold_const`).
781 impl<'tcx> Lift<'tcx> for ty::RegionKind {
782     type Lifted = ty::RegionKind;
783     fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
784         Some(self.clone())
785     }
786 }
787
788 impl<'a, 'tcx> Lift<'tcx> for ty::LazyConst<'a> {
789     type Lifted = ty::LazyConst<'tcx>;
790     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
791         match self {
792             ty::LazyConst::Evaluated(v) => Some(ty::LazyConst::Evaluated(tcx.lift(v)?)),
793             ty::LazyConst::Unevaluated(def_id, substs) => {
794                 Some(ty::LazyConst::Unevaluated(*def_id, tcx.lift(substs)?))
795             }
796         }
797     }
798 }
799
800 BraceStructLiftImpl! {
801     impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
802         type Lifted = ty::Const<'tcx>;
803         val, ty
804     }
805 }
806
807 impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
808     type Lifted = ConstValue<'tcx>;
809     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
810         match *self {
811             ConstValue::Param(param) => Some(ConstValue::Param(param)),
812             ConstValue::Infer(infer) => {
813                 Some(ConstValue::Infer(match infer {
814                     InferConst::Var(vid) => InferConst::Var(vid.lift_to_tcx(tcx)?),
815                     InferConst::Fresh(i) => InferConst::Fresh(i),
816                     InferConst::Canonical(debrujin, var) => InferConst::Canonical(debrujin, var),
817                 }))
818             }
819             ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
820             ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
821             ConstValue::ByRef(ptr, alloc) => Some(ConstValue::ByRef(
822                 ptr, alloc.lift_to_tcx(tcx)?,
823             )),
824         }
825     }
826 }
827
828 impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
829     type Lifted = ConstVid<'tcx>;
830     fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
831         Some(ConstVid {
832             index: self.index,
833             phantom: PhantomData,
834         })
835     }
836 }
837
838 ///////////////////////////////////////////////////////////////////////////
839 // TypeFoldable implementations.
840 //
841 // Ideally, each type should invoke `folder.fold_foo(self)` and
842 // nothing else. In some cases, though, we haven't gotten around to
843 // adding methods on the `folder` yet, and thus the folding is
844 // hard-coded here. This is less-flexible, because folders cannot
845 // override the behavior, but there are a lot of random types and one
846 // can easily refactor the folding into the TypeFolder trait as
847 // needed.
848
849 /// AdtDefs are basically the same as a DefId.
850 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
851     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
852         *self
853     }
854
855     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
856         false
857     }
858 }
859
860 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
861     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
862         (self.0.fold_with(folder), self.1.fold_with(folder))
863     }
864
865     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
866         self.0.visit_with(visitor) || self.1.visit_with(visitor)
867     }
868 }
869
870 EnumTypeFoldableImpl! {
871     impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
872         (Some)(a),
873         (None),
874     } where T: TypeFoldable<'tcx>
875 }
876
877 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
878     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
879         Rc::new((**self).fold_with(folder))
880     }
881
882     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
883         (**self).visit_with(visitor)
884     }
885 }
886
887 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
888     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
889         let content: T = (**self).fold_with(folder);
890         box content
891     }
892
893     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
894         (**self).visit_with(visitor)
895     }
896 }
897
898 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
899     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
900         self.iter().map(|t| t.fold_with(folder)).collect()
901     }
902
903     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
904         self.iter().any(|t| t.visit_with(visitor))
905     }
906 }
907
908 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
909     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
910         self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice()
911     }
912
913     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
914         self.iter().any(|t| t.visit_with(visitor))
915     }
916 }
917
918 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
919     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
920         self.map_bound_ref(|ty| ty.fold_with(folder))
921     }
922
923     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
924         folder.fold_binder(self)
925     }
926
927     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
928         self.skip_binder().visit_with(visitor)
929     }
930
931     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
932         visitor.visit_binder(self)
933     }
934 }
935
936 BraceStructTypeFoldableImpl! {
937     impl<'tcx> TypeFoldable<'tcx> for ty::ParamEnv<'tcx> { reveal, caller_bounds, def_id }
938 }
939
940 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
941     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
942         let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
943         folder.tcx().intern_existential_predicates(&v)
944     }
945
946     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
947         self.iter().any(|p| p.visit_with(visitor))
948     }
949 }
950
951 EnumTypeFoldableImpl! {
952     impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> {
953         (ty::ExistentialPredicate::Trait)(a),
954         (ty::ExistentialPredicate::Projection)(a),
955         (ty::ExistentialPredicate::AutoTrait)(a),
956     }
957 }
958
959 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
960     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
961         let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
962         folder.tcx().intern_type_list(&v)
963     }
964
965     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
966         self.iter().any(|t| t.visit_with(visitor))
967     }
968 }
969
970 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind<'tcx>> {
971     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
972         let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
973         folder.tcx().intern_projs(&v)
974     }
975
976     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
977         self.iter().any(|t| t.visit_with(visitor))
978     }
979 }
980
981 impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
982     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
983         use crate::ty::InstanceDef::*;
984         Self {
985             substs: self.substs.fold_with(folder),
986             def: match self.def {
987                 Item(did) => Item(did.fold_with(folder)),
988                 VtableShim(did) => VtableShim(did.fold_with(folder)),
989                 Intrinsic(did) => Intrinsic(did.fold_with(folder)),
990                 FnPtrShim(did, ty) => FnPtrShim(
991                     did.fold_with(folder),
992                     ty.fold_with(folder),
993                 ),
994                 Virtual(did, i) => Virtual(
995                     did.fold_with(folder),
996                     i,
997                 ),
998                 ClosureOnceShim { call_once } => ClosureOnceShim {
999                     call_once: call_once.fold_with(folder),
1000                 },
1001                 DropGlue(did, ty) => DropGlue(
1002                     did.fold_with(folder),
1003                     ty.fold_with(folder),
1004                 ),
1005                 CloneShim(did, ty) => CloneShim(
1006                     did.fold_with(folder),
1007                     ty.fold_with(folder),
1008                 ),
1009             },
1010         }
1011     }
1012
1013     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1014         use crate::ty::InstanceDef::*;
1015         self.substs.visit_with(visitor) ||
1016         match self.def {
1017             Item(did) | VtableShim(did) | Intrinsic(did) | Virtual(did, _) => {
1018                 did.visit_with(visitor)
1019             },
1020             FnPtrShim(did, ty) | CloneShim(did, ty) => {
1021                 did.visit_with(visitor) || ty.visit_with(visitor)
1022             },
1023             DropGlue(did, ty) => {
1024                 did.visit_with(visitor) || ty.visit_with(visitor)
1025             },
1026             ClosureOnceShim { call_once } => call_once.visit_with(visitor),
1027         }
1028     }
1029 }
1030
1031 impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
1032     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1033         Self {
1034             instance: self.instance.fold_with(folder),
1035             promoted: self.promoted
1036         }
1037     }
1038
1039     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1040         self.instance.visit_with(visitor)
1041     }
1042 }
1043
1044 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
1045     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1046         let sty = match self.sty {
1047             ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
1048             ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
1049             ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
1050             ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)),
1051             ty::Dynamic(ref trait_ty, ref region) =>
1052                 ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
1053             ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)),
1054             ty::FnDef(def_id, substs) => {
1055                 ty::FnDef(def_id, substs.fold_with(folder))
1056             }
1057             ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)),
1058             ty::Ref(ref r, ty, mutbl) => {
1059                 ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl)
1060             }
1061             ty::Generator(did, substs, movability) => {
1062                 ty::Generator(
1063                     did,
1064                     substs.fold_with(folder),
1065                     movability)
1066             }
1067             ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)),
1068             ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)),
1069             ty::Projection(ref data) => ty::Projection(data.fold_with(folder)),
1070             ty::UnnormalizedProjection(ref data) => {
1071                 ty::UnnormalizedProjection(data.fold_with(folder))
1072             }
1073             ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)),
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::Param(..) |
1084             ty::Bound(..) |
1085             ty::Placeholder(..) |
1086             ty::Never |
1087             ty::Foreign(..) => return self
1088         };
1089
1090         if self.sty == sty {
1091             self
1092         } else {
1093             folder.tcx().mk_ty(sty)
1094         }
1095     }
1096
1097     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1098         folder.fold_ty(*self)
1099     }
1100
1101     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1102         match self.sty {
1103             ty::RawPtr(ref tm) => tm.visit_with(visitor),
1104             ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor),
1105             ty::Slice(typ) => typ.visit_with(visitor),
1106             ty::Adt(_, substs) => substs.visit_with(visitor),
1107             ty::Dynamic(ref trait_ty, ref reg) =>
1108                 trait_ty.visit_with(visitor) || reg.visit_with(visitor),
1109             ty::Tuple(ts) => ts.visit_with(visitor),
1110             ty::FnDef(_, substs) => substs.visit_with(visitor),
1111             ty::FnPtr(ref f) => f.visit_with(visitor),
1112             ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor),
1113             ty::Generator(_did, ref substs, _) => {
1114                 substs.visit_with(visitor)
1115             }
1116             ty::GeneratorWitness(ref types) => types.visit_with(visitor),
1117             ty::Closure(_did, ref substs) => substs.visit_with(visitor),
1118             ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => {
1119                 data.visit_with(visitor)
1120             }
1121             ty::Opaque(_, ref substs) => substs.visit_with(visitor),
1122
1123             ty::Bool |
1124             ty::Char |
1125             ty::Str |
1126             ty::Int(_) |
1127             ty::Uint(_) |
1128             ty::Float(_) |
1129             ty::Error |
1130             ty::Infer(_) |
1131             ty::Bound(..) |
1132             ty::Placeholder(..) |
1133             ty::Param(..) |
1134             ty::Never |
1135             ty::Foreign(..) => false,
1136         }
1137     }
1138
1139     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1140         visitor.visit_ty(self)
1141     }
1142 }
1143
1144 BraceStructTypeFoldableImpl! {
1145     impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
1146         ty, mutbl
1147     }
1148 }
1149
1150 BraceStructTypeFoldableImpl! {
1151     impl<'tcx> TypeFoldable<'tcx> for ty::GenSig<'tcx> {
1152         yield_ty, return_ty
1153     }
1154 }
1155
1156 BraceStructTypeFoldableImpl! {
1157     impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> {
1158         inputs_and_output, c_variadic, unsafety, abi
1159     }
1160 }
1161
1162 BraceStructTypeFoldableImpl! {
1163     impl<'tcx> TypeFoldable<'tcx> for ty::TraitRef<'tcx> { def_id, substs }
1164 }
1165
1166 BraceStructTypeFoldableImpl! {
1167     impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialTraitRef<'tcx> { def_id, substs }
1168 }
1169
1170 BraceStructTypeFoldableImpl! {
1171     impl<'tcx> TypeFoldable<'tcx> for ty::ImplHeader<'tcx> {
1172         impl_def_id,
1173         self_ty,
1174         trait_ref,
1175         predicates,
1176     }
1177 }
1178
1179 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
1180     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
1181         *self
1182     }
1183
1184     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1185         folder.fold_region(*self)
1186     }
1187
1188     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
1189         false
1190     }
1191
1192     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1193         visitor.visit_region(*self)
1194     }
1195 }
1196
1197 BraceStructTypeFoldableImpl! {
1198     impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> {
1199         substs,
1200     }
1201 }
1202
1203 BraceStructTypeFoldableImpl! {
1204     impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> {
1205         substs,
1206     }
1207 }
1208
1209 BraceStructTypeFoldableImpl! {
1210     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjustment<'tcx> {
1211         kind,
1212         target,
1213     }
1214 }
1215
1216 EnumTypeFoldableImpl! {
1217     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> {
1218         (ty::adjustment::Adjust::NeverToAny),
1219         (ty::adjustment::Adjust::ReifyFnPointer),
1220         (ty::adjustment::Adjust::UnsafeFnPointer),
1221         (ty::adjustment::Adjust::ClosureFnPointer),
1222         (ty::adjustment::Adjust::MutToConstPointer),
1223         (ty::adjustment::Adjust::Unsize),
1224         (ty::adjustment::Adjust::Deref)(a),
1225         (ty::adjustment::Adjust::Borrow)(a),
1226     }
1227 }
1228
1229 BraceStructTypeFoldableImpl! {
1230     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> {
1231         region, mutbl,
1232     }
1233 }
1234
1235 EnumTypeFoldableImpl! {
1236     impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> {
1237         (ty::adjustment::AutoBorrow::Ref)(a, b),
1238         (ty::adjustment::AutoBorrow::RawPtr)(m),
1239     }
1240 }
1241
1242 BraceStructTypeFoldableImpl! {
1243     impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
1244         parent, predicates
1245     }
1246 }
1247
1248 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
1249     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1250         let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
1251         folder.tcx().intern_predicates(&v)
1252     }
1253
1254     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1255         self.iter().any(|p| p.visit_with(visitor))
1256     }
1257 }
1258
1259 EnumTypeFoldableImpl! {
1260     impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
1261         (ty::Predicate::Trait)(a),
1262         (ty::Predicate::Subtype)(a),
1263         (ty::Predicate::RegionOutlives)(a),
1264         (ty::Predicate::TypeOutlives)(a),
1265         (ty::Predicate::Projection)(a),
1266         (ty::Predicate::WellFormed)(a),
1267         (ty::Predicate::ClosureKind)(a, b, c),
1268         (ty::Predicate::ObjectSafe)(a),
1269         (ty::Predicate::ConstEvaluatable)(a, b),
1270     }
1271 }
1272
1273 BraceStructTypeFoldableImpl! {
1274     impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionPredicate<'tcx> {
1275         projection_ty, ty
1276     }
1277 }
1278
1279 BraceStructTypeFoldableImpl! {
1280     impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialProjection<'tcx> {
1281         ty, substs, item_def_id
1282     }
1283 }
1284
1285 BraceStructTypeFoldableImpl! {
1286     impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
1287         substs, item_def_id
1288     }
1289 }
1290
1291 BraceStructTypeFoldableImpl! {
1292     impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
1293         predicates
1294     }
1295 }
1296
1297 BraceStructTypeFoldableImpl! {
1298     impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> {
1299         param_env, value
1300     } where T: TypeFoldable<'tcx>
1301 }
1302
1303 BraceStructTypeFoldableImpl! {
1304     impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> {
1305         a_is_expected, a, b
1306     }
1307 }
1308
1309 BraceStructTypeFoldableImpl! {
1310     impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> {
1311         trait_ref
1312     }
1313 }
1314
1315 TupleStructTypeFoldableImpl! {
1316     impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate<T,U> {
1317         a, b
1318     } where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>,
1319 }
1320
1321 BraceStructTypeFoldableImpl! {
1322     impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> {
1323         def, span, ty
1324     }
1325 }
1326
1327 BraceStructTypeFoldableImpl! {
1328     impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound<T> {
1329         expected, found
1330     } where T: TypeFoldable<'tcx>
1331 }
1332
1333 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
1334     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1335         self.iter().map(|x| x.fold_with(folder)).collect()
1336     }
1337
1338     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1339         self.iter().any(|t| t.visit_with(visitor))
1340     }
1341 }
1342
1343 EnumTypeFoldableImpl! {
1344     impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
1345         (ty::error::TypeError::Mismatch),
1346         (ty::error::TypeError::UnsafetyMismatch)(x),
1347         (ty::error::TypeError::AbiMismatch)(x),
1348         (ty::error::TypeError::Mutability),
1349         (ty::error::TypeError::TupleSize)(x),
1350         (ty::error::TypeError::FixedArraySize)(x),
1351         (ty::error::TypeError::ArgCount),
1352         (ty::error::TypeError::RegionsDoesNotOutlive)(a, b),
1353         (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b),
1354         (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b),
1355         (ty::error::TypeError::RegionsPlaceholderMismatch),
1356         (ty::error::TypeError::IntMismatch)(x),
1357         (ty::error::TypeError::FloatMismatch)(x),
1358         (ty::error::TypeError::Traits)(x),
1359         (ty::error::TypeError::VariadicMismatch)(x),
1360         (ty::error::TypeError::CyclicTy)(t),
1361         (ty::error::TypeError::ProjectionMismatched)(x),
1362         (ty::error::TypeError::ProjectionBoundsLength)(x),
1363         (ty::error::TypeError::Sorts)(x),
1364         (ty::error::TypeError::ExistentialMismatch)(x),
1365     }
1366 }
1367
1368 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> {
1369     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1370         let new = match self {
1371             ty::LazyConst::Evaluated(v) => ty::LazyConst::Evaluated(v.fold_with(folder)),
1372             ty::LazyConst::Unevaluated(def_id, substs) => {
1373                 ty::LazyConst::Unevaluated(*def_id, substs.fold_with(folder))
1374             }
1375         };
1376         folder.tcx().mk_lazy_const(new)
1377     }
1378
1379     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1380         folder.fold_const(*self)
1381     }
1382
1383     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1384         match *self {
1385             ty::LazyConst::Evaluated(c) => c.visit_with(visitor),
1386             ty::LazyConst::Unevaluated(_, substs) => substs.visit_with(visitor),
1387         }
1388     }
1389
1390     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1391         visitor.visit_const(self)
1392     }
1393 }
1394
1395 impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
1396     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
1397         let ty = self.ty.fold_with(folder);
1398         let val = self.val.fold_with(folder);
1399         ty::Const {
1400             ty,
1401             val
1402         }
1403     }
1404
1405     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1406         self.ty.visit_with(visitor) || self.val.visit_with(visitor)
1407     }
1408 }
1409
1410 impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
1411     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
1412         *self
1413     }
1414
1415     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
1416         false
1417     }
1418 }