]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/structural_impls.rs
Rollup merge of #92825 - pierwill:rustc-version-force-rename, r=Mark-Simulacrum
[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, 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.ty)
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 }
257
258 ///////////////////////////////////////////////////////////////////////////
259 // Lift implementations
260
261 // FIXME(eddyb) replace all the uses of `Option::map` with `?`.
262 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
263     type Lifted = (A::Lifted, B::Lifted);
264     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
265         Some((tcx.lift(self.0)?, tcx.lift(self.1)?))
266     }
267 }
268
269 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
270     type Lifted = (A::Lifted, B::Lifted, C::Lifted);
271     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
272         Some((tcx.lift(self.0)?, tcx.lift(self.1)?, tcx.lift(self.2)?))
273     }
274 }
275
276 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
277     type Lifted = Option<T::Lifted>;
278     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
279         match self {
280             Some(x) => tcx.lift(x).map(Some),
281             None => Some(None),
282         }
283     }
284 }
285
286 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
287     type Lifted = Result<T::Lifted, E::Lifted>;
288     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
289         match self {
290             Ok(x) => tcx.lift(x).map(Ok),
291             Err(e) => tcx.lift(e).map(Err),
292         }
293     }
294 }
295
296 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
297     type Lifted = Box<T::Lifted>;
298     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
299         tcx.lift(*self).map(Box::new)
300     }
301 }
302
303 impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> {
304     type Lifted = Rc<T::Lifted>;
305     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
306         tcx.lift(self.as_ref().clone()).map(Rc::new)
307     }
308 }
309
310 impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> {
311     type Lifted = Arc<T::Lifted>;
312     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
313         tcx.lift(self.as_ref().clone()).map(Arc::new)
314     }
315 }
316 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
317     type Lifted = Vec<T::Lifted>;
318     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
319         self.into_iter().map(|v| tcx.lift(v)).collect()
320     }
321 }
322
323 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
324     type Lifted = IndexVec<I, T::Lifted>;
325     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
326         self.into_iter().map(|e| tcx.lift(e)).collect()
327     }
328 }
329
330 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
331     type Lifted = ty::TraitRef<'tcx>;
332     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
333         tcx.lift(self.substs).map(|substs| ty::TraitRef { def_id: self.def_id, substs })
334     }
335 }
336
337 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
338     type Lifted = ty::ExistentialTraitRef<'tcx>;
339     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
340         tcx.lift(self.substs).map(|substs| ty::ExistentialTraitRef { def_id: self.def_id, substs })
341     }
342 }
343
344 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
345     type Lifted = ty::ExistentialPredicate<'tcx>;
346     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
347         match self {
348             ty::ExistentialPredicate::Trait(x) => tcx.lift(x).map(ty::ExistentialPredicate::Trait),
349             ty::ExistentialPredicate::Projection(x) => {
350                 tcx.lift(x).map(ty::ExistentialPredicate::Projection)
351             }
352             ty::ExistentialPredicate::AutoTrait(def_id) => {
353                 Some(ty::ExistentialPredicate::AutoTrait(def_id))
354             }
355         }
356     }
357 }
358
359 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
360     type Lifted = ty::TraitPredicate<'tcx>;
361     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
362         tcx.lift(self.trait_ref).map(|trait_ref| ty::TraitPredicate {
363             trait_ref,
364             constness: self.constness,
365             polarity: self.polarity,
366         })
367     }
368 }
369
370 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
371     type Lifted = ty::SubtypePredicate<'tcx>;
372     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::SubtypePredicate<'tcx>> {
373         tcx.lift((self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
374             a_is_expected: self.a_is_expected,
375             a,
376             b,
377         })
378     }
379 }
380
381 impl<'a, 'tcx> Lift<'tcx> for ty::CoercePredicate<'a> {
382     type Lifted = ty::CoercePredicate<'tcx>;
383     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::CoercePredicate<'tcx>> {
384         tcx.lift((self.a, self.b)).map(|(a, b)| ty::CoercePredicate { a, b })
385     }
386 }
387
388 impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
389     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
390     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
391         tcx.lift((self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
392     }
393 }
394
395 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
396     type Lifted = ty::ProjectionTy<'tcx>;
397     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionTy<'tcx>> {
398         tcx.lift(self.substs)
399             .map(|substs| ty::ProjectionTy { item_def_id: self.item_def_id, substs })
400     }
401 }
402
403 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
404     type Lifted = ty::ProjectionPredicate<'tcx>;
405     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
406         tcx.lift((self.projection_ty, self.ty))
407             .map(|(projection_ty, ty)| ty::ProjectionPredicate { projection_ty, ty })
408     }
409 }
410
411 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
412     type Lifted = ty::ExistentialProjection<'tcx>;
413     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
414         tcx.lift(self.substs).map(|substs| ty::ExistentialProjection {
415             substs,
416             ty: tcx.lift(self.ty).expect("type must lift when substs do"),
417             item_def_id: self.item_def_id,
418         })
419     }
420 }
421
422 impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
423     type Lifted = ty::PredicateKind<'tcx>;
424     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
425         match self {
426             ty::PredicateKind::Trait(data) => tcx.lift(data).map(ty::PredicateKind::Trait),
427             ty::PredicateKind::Subtype(data) => tcx.lift(data).map(ty::PredicateKind::Subtype),
428             ty::PredicateKind::Coerce(data) => tcx.lift(data).map(ty::PredicateKind::Coerce),
429             ty::PredicateKind::RegionOutlives(data) => {
430                 tcx.lift(data).map(ty::PredicateKind::RegionOutlives)
431             }
432             ty::PredicateKind::TypeOutlives(data) => {
433                 tcx.lift(data).map(ty::PredicateKind::TypeOutlives)
434             }
435             ty::PredicateKind::Projection(data) => {
436                 tcx.lift(data).map(ty::PredicateKind::Projection)
437             }
438             ty::PredicateKind::WellFormed(ty) => tcx.lift(ty).map(ty::PredicateKind::WellFormed),
439             ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
440                 tcx.lift(closure_substs).map(|closure_substs| {
441                     ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind)
442                 })
443             }
444             ty::PredicateKind::ObjectSafe(trait_def_id) => {
445                 Some(ty::PredicateKind::ObjectSafe(trait_def_id))
446             }
447             ty::PredicateKind::ConstEvaluatable(uv) => {
448                 tcx.lift(uv).map(|uv| ty::PredicateKind::ConstEvaluatable(uv))
449             }
450             ty::PredicateKind::ConstEquate(c1, c2) => {
451                 tcx.lift((c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2))
452             }
453             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
454                 tcx.lift(ty).map(ty::PredicateKind::TypeWellFormedFromEnv)
455             }
456         }
457     }
458 }
459
460 impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<'a, T>
461 where
462     <T as Lift<'tcx>>::Lifted: TypeFoldable<'tcx>,
463 {
464     type Lifted = ty::Binder<'tcx, T::Lifted>;
465     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
466         let bound_vars = tcx.lift(self.bound_vars());
467         tcx.lift(self.skip_binder())
468             .zip(bound_vars)
469             .map(|(value, vars)| ty::Binder::bind_with_vars(value, vars))
470     }
471 }
472
473 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
474     type Lifted = ty::ParamEnv<'tcx>;
475     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
476         tcx.lift(self.caller_bounds())
477             .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
478     }
479 }
480
481 impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
482     type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
483     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
484         tcx.lift(self.param_env).and_then(|param_env| {
485             tcx.lift(self.value).map(|value| ty::ParamEnvAnd { param_env, value })
486         })
487     }
488 }
489
490 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
491     type Lifted = ty::ClosureSubsts<'tcx>;
492     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
493         tcx.lift(self.substs).map(|substs| ty::ClosureSubsts { substs })
494     }
495 }
496
497 impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
498     type Lifted = ty::GeneratorSubsts<'tcx>;
499     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
500         tcx.lift(self.substs).map(|substs| ty::GeneratorSubsts { substs })
501     }
502 }
503
504 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
505     type Lifted = ty::adjustment::Adjustment<'tcx>;
506     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
507         let ty::adjustment::Adjustment { kind, target } = self;
508         tcx.lift(kind).and_then(|kind| {
509             tcx.lift(target).map(|target| ty::adjustment::Adjustment { kind, target })
510         })
511     }
512 }
513
514 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
515     type Lifted = ty::adjustment::Adjust<'tcx>;
516     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
517         match self {
518             ty::adjustment::Adjust::NeverToAny => Some(ty::adjustment::Adjust::NeverToAny),
519             ty::adjustment::Adjust::Pointer(ptr) => Some(ty::adjustment::Adjust::Pointer(ptr)),
520             ty::adjustment::Adjust::Deref(overloaded) => {
521                 tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
522             }
523             ty::adjustment::Adjust::Borrow(autoref) => {
524                 tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow)
525             }
526         }
527     }
528 }
529
530 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
531     type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
532     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
533         tcx.lift(self.region).map(|region| ty::adjustment::OverloadedDeref {
534             region,
535             mutbl: self.mutbl,
536             span: self.span,
537         })
538     }
539 }
540
541 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
542     type Lifted = ty::adjustment::AutoBorrow<'tcx>;
543     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
544         match self {
545             ty::adjustment::AutoBorrow::Ref(r, m) => {
546                 tcx.lift(r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
547             }
548             ty::adjustment::AutoBorrow::RawPtr(m) => Some(ty::adjustment::AutoBorrow::RawPtr(m)),
549         }
550     }
551 }
552
553 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
554     type Lifted = ty::GenSig<'tcx>;
555     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
556         tcx.lift((self.resume_ty, self.yield_ty, self.return_ty))
557             .map(|(resume_ty, yield_ty, return_ty)| ty::GenSig { resume_ty, yield_ty, return_ty })
558     }
559 }
560
561 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
562     type Lifted = ty::FnSig<'tcx>;
563     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
564         tcx.lift(self.inputs_and_output).map(|x| ty::FnSig {
565             inputs_and_output: x,
566             c_variadic: self.c_variadic,
567             unsafety: self.unsafety,
568             abi: self.abi,
569         })
570     }
571 }
572
573 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
574     type Lifted = ty::error::ExpectedFound<T::Lifted>;
575     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
576         let ty::error::ExpectedFound { expected, found } = self;
577         tcx.lift(expected).and_then(|expected| {
578             tcx.lift(found).map(|found| ty::error::ExpectedFound { expected, found })
579         })
580     }
581 }
582
583 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
584     type Lifted = ty::error::TypeError<'tcx>;
585     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
586         use crate::ty::error::TypeError::*;
587
588         Some(match self {
589             Mismatch => Mismatch,
590             ConstnessMismatch(x) => ConstnessMismatch(x),
591             PolarityMismatch(x) => PolarityMismatch(x),
592             UnsafetyMismatch(x) => UnsafetyMismatch(x),
593             AbiMismatch(x) => AbiMismatch(x),
594             Mutability => Mutability,
595             ArgumentMutability(i) => ArgumentMutability(i),
596             TupleSize(x) => TupleSize(x),
597             FixedArraySize(x) => FixedArraySize(x),
598             ArgCount => ArgCount,
599             FieldMisMatch(x, y) => FieldMisMatch(x, y),
600             RegionsDoesNotOutlive(a, b) => {
601                 return tcx.lift((a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b));
602             }
603             RegionsInsufficientlyPolymorphic(a, b) => {
604                 return tcx.lift(b).map(|b| RegionsInsufficientlyPolymorphic(a, b));
605             }
606             RegionsOverlyPolymorphic(a, b) => {
607                 return tcx.lift(b).map(|b| RegionsOverlyPolymorphic(a, b));
608             }
609             RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
610             IntMismatch(x) => IntMismatch(x),
611             FloatMismatch(x) => FloatMismatch(x),
612             Traits(x) => Traits(x),
613             VariadicMismatch(x) => VariadicMismatch(x),
614             CyclicTy(t) => return tcx.lift(t).map(|t| CyclicTy(t)),
615             CyclicConst(ct) => return tcx.lift(ct).map(|ct| CyclicConst(ct)),
616             ProjectionMismatched(x) => ProjectionMismatched(x),
617             ArgumentSorts(x, i) => return tcx.lift(x).map(|x| ArgumentSorts(x, i)),
618             Sorts(x) => return tcx.lift(x).map(Sorts),
619             ExistentialMismatch(x) => return tcx.lift(x).map(ExistentialMismatch),
620             ConstMismatch(x) => return tcx.lift(x).map(ConstMismatch),
621             IntrinsicCast => IntrinsicCast,
622             TargetFeatureCast(x) => TargetFeatureCast(x),
623             ObjectUnsafeCoercion(x) => return tcx.lift(x).map(ObjectUnsafeCoercion),
624         })
625     }
626 }
627
628 impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
629     type Lifted = ty::InstanceDef<'tcx>;
630     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
631         match self {
632             ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)),
633             ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)),
634             ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)),
635             ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
636             ty::InstanceDef::FnPtrShim(def_id, ty) => {
637                 Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?))
638             }
639             ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)),
640             ty::InstanceDef::ClosureOnceShim { call_once, track_caller } => {
641                 Some(ty::InstanceDef::ClosureOnceShim { call_once, track_caller })
642             }
643             ty::InstanceDef::DropGlue(def_id, ty) => {
644                 Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?))
645             }
646             ty::InstanceDef::CloneShim(def_id, ty) => {
647                 Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?))
648             }
649         }
650     }
651 }
652
653 ///////////////////////////////////////////////////////////////////////////
654 // TypeFoldable implementations.
655 //
656 // Ideally, each type should invoke `folder.fold_foo(self)` and
657 // nothing else. In some cases, though, we haven't gotten around to
658 // adding methods on the `folder` yet, and thus the folding is
659 // hard-coded here. This is less-flexible, because folders cannot
660 // override the behavior, but there are a lot of random types and one
661 // can easily refactor the folding into the TypeFolder trait as
662 // needed.
663
664 /// AdtDefs are basically the same as a DefId.
665 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
666     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
667         self,
668         _folder: &mut F,
669     ) -> Result<Self, F::Error> {
670         Ok(self)
671     }
672
673     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
674         ControlFlow::CONTINUE
675     }
676 }
677
678 impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
679     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
680         self,
681         folder: &mut F,
682     ) -> Result<(T, U), F::Error> {
683         Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?))
684     }
685
686     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
687         self.0.visit_with(visitor)?;
688         self.1.visit_with(visitor)
689     }
690 }
691
692 impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
693     for (A, B, C)
694 {
695     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
696         self,
697         folder: &mut F,
698     ) -> Result<(A, B, C), F::Error> {
699         Ok((
700             self.0.try_fold_with(folder)?,
701             self.1.try_fold_with(folder)?,
702             self.2.try_fold_with(folder)?,
703         ))
704     }
705
706     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
707         self.0.visit_with(visitor)?;
708         self.1.visit_with(visitor)?;
709         self.2.visit_with(visitor)
710     }
711 }
712
713 EnumTypeFoldableImpl! {
714     impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
715         (Some)(a),
716         (None),
717     } where T: TypeFoldable<'tcx>
718 }
719
720 EnumTypeFoldableImpl! {
721     impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
722         (Ok)(a),
723         (Err)(a),
724     } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
725 }
726
727 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
728     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
729         mut self,
730         folder: &mut F,
731     ) -> Result<Self, F::Error> {
732         // We merely want to replace the contained `T`, if at all possible,
733         // so that we don't needlessly allocate a new `Rc` or indeed clone
734         // the contained type.
735         unsafe {
736             // First step is to ensure that we have a unique reference to
737             // the contained type, which `Rc::make_mut` will accomplish (by
738             // allocating a new `Rc` and cloning the `T` only if required).
739             // This is done *before* casting to `Rc<ManuallyDrop<T>>` so that
740             // panicking during `make_mut` does not leak the `T`.
741             Rc::make_mut(&mut self);
742
743             // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
744             // is `repr(transparent)`.
745             let ptr = Rc::into_raw(self).cast::<ManuallyDrop<T>>();
746             let mut unique = Rc::from_raw(ptr);
747
748             // Call to `Rc::make_mut` above guarantees that `unique` is the
749             // sole reference to the contained value, so we can avoid doing
750             // a checked `get_mut` here.
751             let slot = Rc::get_mut_unchecked(&mut unique);
752
753             // Semantically move the contained type out from `unique`, fold
754             // it, then move the folded value back into `unique`.  Should
755             // folding fail, `ManuallyDrop` ensures that the "moved-out"
756             // value is not re-dropped.
757             let owned = ManuallyDrop::take(slot);
758             let folded = owned.try_fold_with(folder)?;
759             *slot = ManuallyDrop::new(folded);
760
761             // Cast back to `Rc<T>`.
762             Ok(Rc::from_raw(Rc::into_raw(unique).cast()))
763         }
764     }
765
766     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
767         (**self).visit_with(visitor)
768     }
769 }
770
771 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
772     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
773         mut self,
774         folder: &mut F,
775     ) -> Result<Self, F::Error> {
776         // We merely want to replace the contained `T`, if at all possible,
777         // so that we don't needlessly allocate a new `Arc` or indeed clone
778         // the contained type.
779         unsafe {
780             // First step is to ensure that we have a unique reference to
781             // the contained type, which `Arc::make_mut` will accomplish (by
782             // allocating a new `Arc` and cloning the `T` only if required).
783             // This is done *before* casting to `Arc<ManuallyDrop<T>>` so that
784             // panicking during `make_mut` does not leak the `T`.
785             Arc::make_mut(&mut self);
786
787             // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
788             // is `repr(transparent)`.
789             let ptr = Arc::into_raw(self).cast::<ManuallyDrop<T>>();
790             let mut unique = Arc::from_raw(ptr);
791
792             // Call to `Arc::make_mut` above guarantees that `unique` is the
793             // sole reference to the contained value, so we can avoid doing
794             // a checked `get_mut` here.
795             let slot = Arc::get_mut_unchecked(&mut unique);
796
797             // Semantically move the contained type out from `unique`, fold
798             // it, then move the folded value back into `unique`.  Should
799             // folding fail, `ManuallyDrop` ensures that the "moved-out"
800             // value is not re-dropped.
801             let owned = ManuallyDrop::take(slot);
802             let folded = owned.try_fold_with(folder)?;
803             *slot = ManuallyDrop::new(folded);
804
805             // Cast back to `Arc<T>`.
806             Ok(Arc::from_raw(Arc::into_raw(unique).cast()))
807         }
808     }
809
810     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
811         (**self).visit_with(visitor)
812     }
813 }
814
815 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
816     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
817         self,
818         folder: &mut F,
819     ) -> Result<Self, F::Error> {
820         self.try_map_id(|value| value.try_fold_with(folder))
821     }
822
823     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
824         (**self).visit_with(visitor)
825     }
826 }
827
828 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
829     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
830         self,
831         folder: &mut F,
832     ) -> Result<Self, F::Error> {
833         self.try_map_id(|t| t.try_fold_with(folder))
834     }
835
836     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
837         self.iter().try_for_each(|t| t.visit_with(visitor))
838     }
839 }
840
841 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
842     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
843         self,
844         folder: &mut F,
845     ) -> Result<Self, F::Error> {
846         self.try_map_id(|t| t.try_fold_with(folder))
847     }
848
849     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
850         self.iter().try_for_each(|t| t.visit_with(visitor))
851     }
852 }
853
854 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
855     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
856         self,
857         folder: &mut F,
858     ) -> Result<Self, F::Error> {
859         self.try_map_bound(|ty| ty.try_fold_with(folder))
860     }
861
862     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
863         folder.try_fold_binder(self)
864     }
865
866     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
867         self.as_ref().skip_binder().visit_with(visitor)
868     }
869
870     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
871         visitor.visit_binder(self)
872     }
873 }
874
875 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> {
876     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
877         self,
878         folder: &mut F,
879     ) -> Result<Self, F::Error> {
880         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
881     }
882
883     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
884         self.iter().try_for_each(|p| p.visit_with(visitor))
885     }
886 }
887
888 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
889     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
890         self,
891         folder: &mut F,
892     ) -> Result<Self, F::Error> {
893         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
894     }
895
896     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
897         self.iter().try_for_each(|t| t.visit_with(visitor))
898     }
899 }
900
901 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
902     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
903         self,
904         folder: &mut F,
905     ) -> Result<Self, F::Error> {
906         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
907     }
908
909     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
910         self.iter().try_for_each(|t| t.visit_with(visitor))
911     }
912 }
913
914 impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
915     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
916         self,
917         folder: &mut F,
918     ) -> Result<Self, F::Error> {
919         use crate::ty::InstanceDef::*;
920         Ok(Self {
921             substs: self.substs.try_fold_with(folder)?,
922             def: match self.def {
923                 Item(def) => Item(def.try_fold_with(folder)?),
924                 VtableShim(did) => VtableShim(did.try_fold_with(folder)?),
925                 ReifyShim(did) => ReifyShim(did.try_fold_with(folder)?),
926                 Intrinsic(did) => Intrinsic(did.try_fold_with(folder)?),
927                 FnPtrShim(did, ty) => {
928                     FnPtrShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
929                 }
930                 Virtual(did, i) => Virtual(did.try_fold_with(folder)?, i),
931                 ClosureOnceShim { call_once, track_caller } => {
932                     ClosureOnceShim { call_once: call_once.try_fold_with(folder)?, track_caller }
933                 }
934                 DropGlue(did, ty) => {
935                     DropGlue(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
936                 }
937                 CloneShim(did, ty) => {
938                     CloneShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
939                 }
940             },
941         })
942     }
943
944     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
945         use crate::ty::InstanceDef::*;
946         self.substs.visit_with(visitor)?;
947         match self.def {
948             Item(def) => def.visit_with(visitor),
949             VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
950                 did.visit_with(visitor)
951             }
952             FnPtrShim(did, ty) | CloneShim(did, ty) => {
953                 did.visit_with(visitor)?;
954                 ty.visit_with(visitor)
955             }
956             DropGlue(did, ty) => {
957                 did.visit_with(visitor)?;
958                 ty.visit_with(visitor)
959             }
960             ClosureOnceShim { call_once, track_caller: _ } => call_once.visit_with(visitor),
961         }
962     }
963 }
964
965 impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
966     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
967         self,
968         folder: &mut F,
969     ) -> Result<Self, F::Error> {
970         Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted })
971     }
972
973     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
974         self.instance.visit_with(visitor)
975     }
976 }
977
978 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
979     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
980         self,
981         folder: &mut F,
982     ) -> Result<Self, F::Error> {
983         let kind = match *self.kind() {
984             ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?),
985             ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
986             ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
987             ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
988             ty::Dynamic(trait_ty, region) => {
989                 ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?)
990             }
991             ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
992             ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
993             ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
994             ty::Ref(r, ty, mutbl) => {
995                 ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
996             }
997             ty::Generator(did, substs, movability) => {
998                 ty::Generator(did, substs.try_fold_with(folder)?, movability)
999             }
1000             ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
1001             ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
1002             ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?),
1003             ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?),
1004
1005             ty::Bool
1006             | ty::Char
1007             | ty::Str
1008             | ty::Int(_)
1009             | ty::Uint(_)
1010             | ty::Float(_)
1011             | ty::Error(_)
1012             | ty::Infer(_)
1013             | ty::Param(..)
1014             | ty::Bound(..)
1015             | ty::Placeholder(..)
1016             | ty::Never
1017             | ty::Foreign(..) => return Ok(self),
1018         };
1019
1020         Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) })
1021     }
1022
1023     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
1024         folder.try_fold_ty(self)
1025     }
1026
1027     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1028         match self.kind() {
1029             ty::RawPtr(ref tm) => tm.visit_with(visitor),
1030             ty::Array(typ, sz) => {
1031                 typ.visit_with(visitor)?;
1032                 sz.visit_with(visitor)
1033             }
1034             ty::Slice(typ) => typ.visit_with(visitor),
1035             ty::Adt(_, substs) => substs.visit_with(visitor),
1036             ty::Dynamic(ref trait_ty, ref reg) => {
1037                 trait_ty.visit_with(visitor)?;
1038                 reg.visit_with(visitor)
1039             }
1040             ty::Tuple(ts) => ts.visit_with(visitor),
1041             ty::FnDef(_, substs) => substs.visit_with(visitor),
1042             ty::FnPtr(ref f) => f.visit_with(visitor),
1043             ty::Ref(r, ty, _) => {
1044                 r.visit_with(visitor)?;
1045                 ty.visit_with(visitor)
1046             }
1047             ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
1048             ty::GeneratorWitness(ref types) => types.visit_with(visitor),
1049             ty::Closure(_did, ref substs) => substs.visit_with(visitor),
1050             ty::Projection(ref data) => data.visit_with(visitor),
1051             ty::Opaque(_, ref substs) => substs.visit_with(visitor),
1052
1053             ty::Bool
1054             | ty::Char
1055             | ty::Str
1056             | ty::Int(_)
1057             | ty::Uint(_)
1058             | ty::Float(_)
1059             | ty::Error(_)
1060             | ty::Infer(_)
1061             | ty::Bound(..)
1062             | ty::Placeholder(..)
1063             | ty::Param(..)
1064             | ty::Never
1065             | ty::Foreign(..) => ControlFlow::CONTINUE,
1066         }
1067     }
1068
1069     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1070         visitor.visit_ty(self)
1071     }
1072 }
1073
1074 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
1075     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1076         self,
1077         _folder: &mut F,
1078     ) -> Result<Self, F::Error> {
1079         Ok(self)
1080     }
1081
1082     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
1083         folder.try_fold_region(self)
1084     }
1085
1086     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
1087         ControlFlow::CONTINUE
1088     }
1089
1090     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1091         visitor.visit_region(*self)
1092     }
1093 }
1094
1095 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
1096     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
1097         folder.try_fold_predicate(self)
1098     }
1099
1100     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1101         self,
1102         folder: &mut F,
1103     ) -> Result<Self, F::Error> {
1104         let new = self.inner.kind.try_fold_with(folder)?;
1105         Ok(folder.tcx().reuse_or_mk_predicate(self, new))
1106     }
1107
1108     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1109         self.inner.kind.visit_with(visitor)
1110     }
1111
1112     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1113         visitor.visit_predicate(*self)
1114     }
1115
1116     fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
1117         self.inner.outer_exclusive_binder > binder
1118     }
1119
1120     fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
1121         self.inner.flags.intersects(flags)
1122     }
1123 }
1124
1125 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
1126     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1127         self,
1128         folder: &mut F,
1129     ) -> Result<Self, F::Error> {
1130         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
1131     }
1132
1133     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1134         self.iter().try_for_each(|p| p.visit_with(visitor))
1135     }
1136 }
1137
1138 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
1139     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1140         self,
1141         folder: &mut F,
1142     ) -> Result<Self, F::Error> {
1143         self.try_map_id(|x| x.try_fold_with(folder))
1144     }
1145
1146     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1147         self.iter().try_for_each(|t| t.visit_with(visitor))
1148     }
1149 }
1150
1151 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
1152     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1153         self,
1154         folder: &mut F,
1155     ) -> Result<Self, F::Error> {
1156         let ty = self.ty.try_fold_with(folder)?;
1157         let val = self.val.try_fold_with(folder)?;
1158         if ty != self.ty || val != self.val {
1159             Ok(folder.tcx().mk_const(ty::Const { ty, val }))
1160         } else {
1161             Ok(self)
1162         }
1163     }
1164
1165     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
1166         folder.try_fold_const(self)
1167     }
1168
1169     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1170         self.ty.visit_with(visitor)?;
1171         self.val.visit_with(visitor)
1172     }
1173
1174     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1175         visitor.visit_const(self)
1176     }
1177 }
1178
1179 impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
1180     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1181         self,
1182         folder: &mut F,
1183     ) -> Result<Self, F::Error> {
1184         Ok(match self {
1185             ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?),
1186             ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?),
1187             ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?),
1188             ty::ConstKind::Value(_)
1189             | ty::ConstKind::Bound(..)
1190             | ty::ConstKind::Placeholder(..)
1191             | ty::ConstKind::Error(_) => self,
1192         })
1193     }
1194
1195     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1196         match *self {
1197             ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
1198             ty::ConstKind::Param(p) => p.visit_with(visitor),
1199             ty::ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
1200             ty::ConstKind::Value(_)
1201             | ty::ConstKind::Bound(..)
1202             | ty::ConstKind::Placeholder(_)
1203             | ty::ConstKind::Error(_) => ControlFlow::CONTINUE,
1204         }
1205     }
1206 }
1207
1208 impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
1209     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1210         self,
1211         _folder: &mut F,
1212     ) -> Result<Self, F::Error> {
1213         Ok(self)
1214     }
1215
1216     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
1217         ControlFlow::CONTINUE
1218     }
1219 }
1220
1221 impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
1222     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1223         self,
1224         folder: &mut F,
1225     ) -> Result<Self, F::Error> {
1226         Ok(ty::Unevaluated {
1227             def: self.def,
1228             substs: self.substs.try_fold_with(folder)?,
1229             promoted: self.promoted,
1230         })
1231     }
1232
1233     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1234         visitor.visit_unevaluated_const(*self)
1235     }
1236
1237     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1238         self.substs.visit_with(visitor)
1239     }
1240 }
1241
1242 impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> {
1243     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
1244         self,
1245         folder: &mut F,
1246     ) -> Result<Self, F::Error> {
1247         Ok(ty::Unevaluated {
1248             def: self.def,
1249             substs: self.substs.try_fold_with(folder)?,
1250             promoted: self.promoted,
1251         })
1252     }
1253
1254     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1255         visitor.visit_unevaluated_const(self.expand())
1256     }
1257
1258     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
1259         self.substs.visit_with(visitor)
1260     }
1261 }