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