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