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