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