]> git.lizzy.rs Git - rust.git/blob - src/librustc/ty/structural_impls.rs
Rollup merge of #68288 - RalfJung:fmt, r=oli-obk
[rust.git] / src / librustc / 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::{TypeFoldable, TypeFolder, TypeVisitor};
8 use crate::ty::print::{FmtPrinter, Printer};
9 use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
10 use rustc_hir::def::Namespace;
11 use rustc_hir::def_id::CRATE_DEF_INDEX;
12 use rustc_index::vec::{Idx, IndexVec};
13
14 use smallvec::SmallVec;
15 use std::fmt;
16 use std::rc::Rc;
17 use std::sync::Arc;
18
19 impl fmt::Debug for ty::GenericParamDef {
20     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21         let type_name = match self.kind {
22             ty::GenericParamDefKind::Lifetime => "Lifetime",
23             ty::GenericParamDefKind::Type { .. } => "Type",
24             ty::GenericParamDefKind::Const => "Const",
25         };
26         write!(f, "{}({}, {:?}, {})", type_name, self.name, self.def_id, self.index)
27     }
28 }
29
30 impl fmt::Debug for ty::TraitDef {
31     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32         ty::tls::with(|tcx| {
33             FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.def_id, &[])?;
34             Ok(())
35         })
36     }
37 }
38
39 impl fmt::Debug for ty::AdtDef {
40     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41         ty::tls::with(|tcx| {
42             FmtPrinter::new(tcx, f, Namespace::TypeNS).print_def_path(self.did, &[])?;
43             Ok(())
44         })
45     }
46 }
47
48 impl fmt::Debug for ty::UpvarId {
49     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50         let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id));
51         write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id)
52     }
53 }
54
55 impl fmt::Debug for ty::UpvarBorrow<'tcx> {
56     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57         write!(f, "UpvarBorrow({:?}, {:?})", self.kind, self.region)
58     }
59 }
60
61 impl fmt::Debug for ty::ExistentialTraitRef<'tcx> {
62     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63         fmt::Display::fmt(self, f)
64     }
65 }
66
67 impl fmt::Debug for ty::adjustment::Adjustment<'tcx> {
68     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69         write!(f, "{:?} -> {}", self.kind, self.target)
70     }
71 }
72
73 impl fmt::Debug for ty::BoundRegion {
74     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75         match *self {
76             ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
77             ty::BrNamed(did, name) => {
78                 if did.index == CRATE_DEF_INDEX {
79                     write!(f, "BrNamed({})", name)
80                 } else {
81                     write!(f, "BrNamed({:?}, {})", did, name)
82                 }
83             }
84             ty::BrEnv => write!(f, "BrEnv"),
85         }
86     }
87 }
88
89 impl fmt::Debug for ty::RegionKind {
90     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91         match *self {
92             ty::ReEarlyBound(ref data) => write!(f, "ReEarlyBound({}, {})", data.index, data.name),
93
94             ty::ReClosureBound(ref vid) => write!(f, "ReClosureBound({:?})", vid),
95
96             ty::ReLateBound(binder_id, ref bound_region) => {
97                 write!(f, "ReLateBound({:?}, {:?})", binder_id, bound_region)
98             }
99
100             ty::ReFree(ref fr) => fr.fmt(f),
101
102             ty::ReScope(id) => write!(f, "ReScope({:?})", id),
103
104             ty::ReStatic => write!(f, "ReStatic"),
105
106             ty::ReVar(ref vid) => vid.fmt(f),
107
108             ty::RePlaceholder(placeholder) => write!(f, "RePlaceholder({:?})", placeholder),
109
110             ty::ReEmpty => write!(f, "ReEmpty"),
111
112             ty::ReErased => write!(f, "ReErased"),
113         }
114     }
115 }
116
117 impl fmt::Debug for ty::FreeRegion {
118     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119         write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
120     }
121 }
122
123 impl fmt::Debug for ty::Variance {
124     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125         f.write_str(match *self {
126             ty::Covariant => "+",
127             ty::Contravariant => "-",
128             ty::Invariant => "o",
129             ty::Bivariant => "*",
130         })
131     }
132 }
133
134 impl fmt::Debug for ty::FnSig<'tcx> {
135     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136         write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
137     }
138 }
139
140 impl fmt::Debug for ty::TyVid {
141     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142         write!(f, "_#{}t", self.index)
143     }
144 }
145
146 impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
147     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148         write!(f, "_#{}c", self.index)
149     }
150 }
151
152 impl fmt::Debug for ty::IntVid {
153     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154         write!(f, "_#{}i", self.index)
155     }
156 }
157
158 impl fmt::Debug for ty::FloatVid {
159     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160         write!(f, "_#{}f", self.index)
161     }
162 }
163
164 impl fmt::Debug for ty::RegionVid {
165     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166         write!(f, "'_#{}r", self.index())
167     }
168 }
169
170 impl fmt::Debug for ty::InferTy {
171     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172         match *self {
173             ty::TyVar(ref v) => v.fmt(f),
174             ty::IntVar(ref v) => v.fmt(f),
175             ty::FloatVar(ref v) => v.fmt(f),
176             ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
177             ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
178             ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v),
179         }
180     }
181 }
182
183 impl fmt::Debug for ty::IntVarValue {
184     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185         match *self {
186             ty::IntType(ref v) => v.fmt(f),
187             ty::UintType(ref v) => v.fmt(f),
188         }
189     }
190 }
191
192 impl fmt::Debug for ty::FloatVarValue {
193     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194         self.0.fmt(f)
195     }
196 }
197
198 impl fmt::Debug for ty::TraitRef<'tcx> {
199     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200         fmt::Display::fmt(self, f)
201     }
202 }
203
204 impl fmt::Debug for Ty<'tcx> {
205     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206         fmt::Display::fmt(self, f)
207     }
208 }
209
210 impl fmt::Debug for ty::ParamTy {
211     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212         write!(f, "{}/#{}", self.name, self.index)
213     }
214 }
215
216 impl fmt::Debug for ty::ParamConst {
217     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218         write!(f, "{}/#{}", self.name, self.index)
219     }
220 }
221
222 impl fmt::Debug for ty::TraitPredicate<'tcx> {
223     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224         write!(f, "TraitPredicate({:?})", self.trait_ref)
225     }
226 }
227
228 impl fmt::Debug for ty::ProjectionPredicate<'tcx> {
229     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230         write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.ty)
231     }
232 }
233
234 impl fmt::Debug for ty::Predicate<'tcx> {
235     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236         match *self {
237             ty::Predicate::Trait(ref a) => a.fmt(f),
238             ty::Predicate::Subtype(ref pair) => pair.fmt(f),
239             ty::Predicate::RegionOutlives(ref pair) => pair.fmt(f),
240             ty::Predicate::TypeOutlives(ref pair) => pair.fmt(f),
241             ty::Predicate::Projection(ref pair) => pair.fmt(f),
242             ty::Predicate::WellFormed(ty) => write!(f, "WellFormed({:?})", ty),
243             ty::Predicate::ObjectSafe(trait_def_id) => write!(f, "ObjectSafe({:?})", trait_def_id),
244             ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
245                 write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
246             }
247             ty::Predicate::ConstEvaluatable(def_id, substs) => {
248                 write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
249             }
250         }
251     }
252 }
253
254 ///////////////////////////////////////////////////////////////////////////
255 // Atomic structs
256 //
257 // For things that don't carry any arena-allocated data (and are
258 // copy...), just add them to this list.
259
260 CloneTypeFoldableAndLiftImpls! {
261     (),
262     bool,
263     usize,
264     crate::ty::layout::VariantIdx,
265     u64,
266     String,
267     crate::middle::region::Scope,
268     ::syntax::ast::FloatTy,
269     ::syntax::ast::NodeId,
270     ::rustc_span::symbol::Symbol,
271     ::rustc_hir::def::Res,
272     ::rustc_hir::def_id::DefId,
273     ::rustc_hir::InlineAsmInner,
274     ::rustc_hir::MatchSource,
275     ::rustc_hir::Mutability,
276     ::rustc_hir::Unsafety,
277     ::rustc_target::spec::abi::Abi,
278     crate::mir::Local,
279     crate::mir::Promoted,
280     crate::traits::Reveal,
281     crate::ty::adjustment::AutoBorrowMutability,
282     crate::ty::AdtKind,
283     // Including `BoundRegion` is a *bit* dubious, but direct
284     // references to bound region appear in `ty::Error`, and aren't
285     // really meant to be folded. In general, we can only fold a fully
286     // general `Region`.
287     crate::ty::BoundRegion,
288     crate::ty::Placeholder<crate::ty::BoundRegion>,
289     crate::ty::ClosureKind,
290     crate::ty::FreeRegion,
291     crate::ty::InferTy,
292     crate::ty::IntVarValue,
293     crate::ty::ParamConst,
294     crate::ty::ParamTy,
295     crate::ty::adjustment::PointerCast,
296     crate::ty::RegionVid,
297     crate::ty::UniverseIndex,
298     crate::ty::Variance,
299     ::rustc_span::Span,
300 }
301
302 ///////////////////////////////////////////////////////////////////////////
303 // Lift implementations
304
305 // FIXME(eddyb) replace all the uses of `Option::map` with `?`.
306 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
307     type Lifted = (A::Lifted, B::Lifted);
308     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
309         tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
310     }
311 }
312
313 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
314     type Lifted = (A::Lifted, B::Lifted, C::Lifted);
315     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
316         tcx.lift(&self.0)
317             .and_then(|a| tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c))))
318     }
319 }
320
321 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
322     type Lifted = Option<T::Lifted>;
323     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
324         match *self {
325             Some(ref x) => tcx.lift(x).map(Some),
326             None => Some(None),
327         }
328     }
329 }
330
331 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
332     type Lifted = Result<T::Lifted, E::Lifted>;
333     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
334         match *self {
335             Ok(ref x) => tcx.lift(x).map(Ok),
336             Err(ref e) => tcx.lift(e).map(Err),
337         }
338     }
339 }
340
341 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
342     type Lifted = Box<T::Lifted>;
343     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
344         tcx.lift(&**self).map(Box::new)
345     }
346 }
347
348 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Rc<T> {
349     type Lifted = Rc<T::Lifted>;
350     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
351         tcx.lift(&**self).map(Rc::new)
352     }
353 }
354
355 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Arc<T> {
356     type Lifted = Arc<T::Lifted>;
357     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
358         tcx.lift(&**self).map(Arc::new)
359     }
360 }
361
362 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
363     type Lifted = Vec<T::Lifted>;
364     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
365         // type annotation needed to inform `projection_must_outlive`
366         let mut result: Vec<<T as Lift<'tcx>>::Lifted> = Vec::with_capacity(self.len());
367         for x in self {
368             if let Some(value) = tcx.lift(x) {
369                 result.push(value);
370             } else {
371                 return None;
372             }
373         }
374         Some(result)
375     }
376 }
377
378 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
379     type Lifted = Vec<T::Lifted>;
380     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
381         tcx.lift(&self[..])
382     }
383 }
384
385 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
386     type Lifted = IndexVec<I, T::Lifted>;
387     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
388         self.iter().map(|e| tcx.lift(e)).collect()
389     }
390 }
391
392 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
393     type Lifted = ty::TraitRef<'tcx>;
394     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
395         tcx.lift(&self.substs).map(|substs| ty::TraitRef { def_id: self.def_id, substs })
396     }
397 }
398
399 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
400     type Lifted = ty::ExistentialTraitRef<'tcx>;
401     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
402         tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef { def_id: self.def_id, substs })
403     }
404 }
405
406 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
407     type Lifted = ty::ExistentialPredicate<'tcx>;
408     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
409         match self {
410             ty::ExistentialPredicate::Trait(x) => tcx.lift(x).map(ty::ExistentialPredicate::Trait),
411             ty::ExistentialPredicate::Projection(x) => {
412                 tcx.lift(x).map(ty::ExistentialPredicate::Projection)
413             }
414             ty::ExistentialPredicate::AutoTrait(def_id) => {
415                 Some(ty::ExistentialPredicate::AutoTrait(*def_id))
416             }
417         }
418     }
419 }
420
421 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
422     type Lifted = ty::TraitPredicate<'tcx>;
423     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
424         tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate { trait_ref })
425     }
426 }
427
428 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
429     type Lifted = ty::SubtypePredicate<'tcx>;
430     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::SubtypePredicate<'tcx>> {
431         tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
432             a_is_expected: self.a_is_expected,
433             a,
434             b,
435         })
436     }
437 }
438
439 impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
440     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
441     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
442         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
443     }
444 }
445
446 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
447     type Lifted = ty::ProjectionTy<'tcx>;
448     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionTy<'tcx>> {
449         tcx.lift(&self.substs)
450             .map(|substs| ty::ProjectionTy { item_def_id: self.item_def_id, substs })
451     }
452 }
453
454 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
455     type Lifted = ty::ProjectionPredicate<'tcx>;
456     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
457         tcx.lift(&(self.projection_ty, self.ty))
458             .map(|(projection_ty, ty)| ty::ProjectionPredicate { projection_ty, ty })
459     }
460 }
461
462 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
463     type Lifted = ty::ExistentialProjection<'tcx>;
464     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
465         tcx.lift(&self.substs).map(|substs| ty::ExistentialProjection {
466             substs,
467             ty: tcx.lift(&self.ty).expect("type must lift when substs do"),
468             item_def_id: self.item_def_id,
469         })
470     }
471 }
472
473 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
474     type Lifted = ty::Predicate<'tcx>;
475     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
476         match *self {
477             ty::Predicate::Trait(ref binder) => tcx.lift(binder).map(ty::Predicate::Trait),
478             ty::Predicate::Subtype(ref binder) => tcx.lift(binder).map(ty::Predicate::Subtype),
479             ty::Predicate::RegionOutlives(ref binder) => {
480                 tcx.lift(binder).map(ty::Predicate::RegionOutlives)
481             }
482             ty::Predicate::TypeOutlives(ref binder) => {
483                 tcx.lift(binder).map(ty::Predicate::TypeOutlives)
484             }
485             ty::Predicate::Projection(ref binder) => {
486                 tcx.lift(binder).map(ty::Predicate::Projection)
487             }
488             ty::Predicate::WellFormed(ty) => tcx.lift(&ty).map(ty::Predicate::WellFormed),
489             ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
490                 tcx.lift(&closure_substs).map(|closure_substs| {
491                     ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind)
492                 })
493             }
494             ty::Predicate::ObjectSafe(trait_def_id) => {
495                 Some(ty::Predicate::ObjectSafe(trait_def_id))
496             }
497             ty::Predicate::ConstEvaluatable(def_id, substs) => {
498                 tcx.lift(&substs).map(|substs| ty::Predicate::ConstEvaluatable(def_id, substs))
499             }
500         }
501     }
502 }
503
504 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
505     type Lifted = ty::Binder<T::Lifted>;
506     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
507         tcx.lift(self.skip_binder()).map(ty::Binder::bind)
508     }
509 }
510
511 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
512     type Lifted = ty::ParamEnv<'tcx>;
513     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
514         tcx.lift(&self.caller_bounds).map(|caller_bounds| ty::ParamEnv {
515             reveal: self.reveal,
516             caller_bounds,
517             def_id: self.def_id,
518         })
519     }
520 }
521
522 impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
523     type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
524     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
525         tcx.lift(&self.param_env).and_then(|param_env| {
526             tcx.lift(&self.value).map(|value| ty::ParamEnvAnd { param_env, value })
527         })
528     }
529 }
530
531 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
532     type Lifted = ty::ClosureSubsts<'tcx>;
533     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
534         tcx.lift(&self.substs).map(|substs| ty::ClosureSubsts { substs })
535     }
536 }
537
538 impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
539     type Lifted = ty::GeneratorSubsts<'tcx>;
540     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
541         tcx.lift(&self.substs).map(|substs| ty::GeneratorSubsts { substs })
542     }
543 }
544
545 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
546     type Lifted = ty::adjustment::Adjustment<'tcx>;
547     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
548         tcx.lift(&self.kind).and_then(|kind| {
549             tcx.lift(&self.target).map(|target| ty::adjustment::Adjustment { kind, target })
550         })
551     }
552 }
553
554 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
555     type Lifted = ty::adjustment::Adjust<'tcx>;
556     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
557         match *self {
558             ty::adjustment::Adjust::NeverToAny => Some(ty::adjustment::Adjust::NeverToAny),
559             ty::adjustment::Adjust::Pointer(ptr) => Some(ty::adjustment::Adjust::Pointer(ptr)),
560             ty::adjustment::Adjust::Deref(ref overloaded) => {
561                 tcx.lift(overloaded).map(ty::adjustment::Adjust::Deref)
562             }
563             ty::adjustment::Adjust::Borrow(ref autoref) => {
564                 tcx.lift(autoref).map(ty::adjustment::Adjust::Borrow)
565             }
566         }
567     }
568 }
569
570 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
571     type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
572     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
573         tcx.lift(&self.region)
574             .map(|region| ty::adjustment::OverloadedDeref { region, mutbl: self.mutbl })
575     }
576 }
577
578 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
579     type Lifted = ty::adjustment::AutoBorrow<'tcx>;
580     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
581         match *self {
582             ty::adjustment::AutoBorrow::Ref(r, m) => {
583                 tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
584             }
585             ty::adjustment::AutoBorrow::RawPtr(m) => Some(ty::adjustment::AutoBorrow::RawPtr(m)),
586         }
587     }
588 }
589
590 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
591     type Lifted = ty::GenSig<'tcx>;
592     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
593         tcx.lift(&(self.yield_ty, self.return_ty))
594             .map(|(yield_ty, return_ty)| ty::GenSig { yield_ty, return_ty })
595     }
596 }
597
598 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
599     type Lifted = ty::FnSig<'tcx>;
600     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
601         tcx.lift(&self.inputs_and_output).map(|x| ty::FnSig {
602             inputs_and_output: x,
603             c_variadic: self.c_variadic,
604             unsafety: self.unsafety,
605             abi: self.abi,
606         })
607     }
608 }
609
610 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
611     type Lifted = ty::error::ExpectedFound<T::Lifted>;
612     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
613         tcx.lift(&self.expected).and_then(|expected| {
614             tcx.lift(&self.found).map(|found| ty::error::ExpectedFound { expected, found })
615         })
616     }
617 }
618
619 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
620     type Lifted = ty::error::TypeError<'tcx>;
621     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
622         use crate::ty::error::TypeError::*;
623
624         Some(match *self {
625             Mismatch => Mismatch,
626             UnsafetyMismatch(x) => UnsafetyMismatch(x),
627             AbiMismatch(x) => AbiMismatch(x),
628             Mutability => Mutability,
629             TupleSize(x) => TupleSize(x),
630             FixedArraySize(x) => FixedArraySize(x),
631             ArgCount => ArgCount,
632             RegionsDoesNotOutlive(a, b) => {
633                 return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b));
634             }
635             RegionsInsufficientlyPolymorphic(a, b) => {
636                 return tcx.lift(&b).map(|b| RegionsInsufficientlyPolymorphic(a, b));
637             }
638             RegionsOverlyPolymorphic(a, b) => {
639                 return tcx.lift(&b).map(|b| RegionsOverlyPolymorphic(a, b));
640             }
641             RegionsPlaceholderMismatch => RegionsPlaceholderMismatch,
642             IntMismatch(x) => IntMismatch(x),
643             FloatMismatch(x) => FloatMismatch(x),
644             Traits(x) => Traits(x),
645             VariadicMismatch(x) => VariadicMismatch(x),
646             CyclicTy(t) => return tcx.lift(&t).map(|t| CyclicTy(t)),
647             ProjectionMismatched(x) => ProjectionMismatched(x),
648             ProjectionBoundsLength(x) => ProjectionBoundsLength(x),
649             Sorts(ref x) => return tcx.lift(x).map(Sorts),
650             ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
651             ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
652             IntrinsicCast => IntrinsicCast,
653             ObjectUnsafeCoercion(ref x) => return tcx.lift(x).map(ObjectUnsafeCoercion),
654         })
655     }
656 }
657
658 impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
659     type Lifted = ty::InstanceDef<'tcx>;
660     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
661         match *self {
662             ty::InstanceDef::Item(def_id) => Some(ty::InstanceDef::Item(def_id)),
663             ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)),
664             ty::InstanceDef::ReifyShim(def_id) => Some(ty::InstanceDef::ReifyShim(def_id)),
665             ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)),
666             ty::InstanceDef::FnPtrShim(def_id, ref ty) => {
667                 Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?))
668             }
669             ty::InstanceDef::Virtual(def_id, n) => Some(ty::InstanceDef::Virtual(def_id, n)),
670             ty::InstanceDef::ClosureOnceShim { call_once } => {
671                 Some(ty::InstanceDef::ClosureOnceShim { call_once })
672             }
673             ty::InstanceDef::DropGlue(def_id, ref ty) => {
674                 Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?))
675             }
676             ty::InstanceDef::CloneShim(def_id, ref ty) => {
677                 Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?))
678             }
679         }
680     }
681 }
682
683 ///////////////////////////////////////////////////////////////////////////
684 // TypeFoldable implementations.
685 //
686 // Ideally, each type should invoke `folder.fold_foo(self)` and
687 // nothing else. In some cases, though, we haven't gotten around to
688 // adding methods on the `folder` yet, and thus the folding is
689 // hard-coded here. This is less-flexible, because folders cannot
690 // override the behavior, but there are a lot of random types and one
691 // can easily refactor the folding into the TypeFolder trait as
692 // needed.
693
694 /// AdtDefs are basically the same as a DefId.
695 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
696     fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
697         *self
698     }
699
700     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
701         false
702     }
703 }
704
705 impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
706     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> (T, U) {
707         (self.0.fold_with(folder), self.1.fold_with(folder))
708     }
709
710     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
711         self.0.visit_with(visitor) || self.1.visit_with(visitor)
712     }
713 }
714
715 EnumTypeFoldableImpl! {
716     impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
717         (Some)(a),
718         (None),
719     } where T: TypeFoldable<'tcx>
720 }
721
722 EnumTypeFoldableImpl! {
723     impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
724         (Ok)(a),
725         (Err)(a),
726     } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
727 }
728
729 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
730     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
731         Rc::new((**self).fold_with(folder))
732     }
733
734     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
735         (**self).visit_with(visitor)
736     }
737 }
738
739 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
740     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
741         Arc::new((**self).fold_with(folder))
742     }
743
744     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
745         (**self).visit_with(visitor)
746     }
747 }
748
749 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
750     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
751         let content: T = (**self).fold_with(folder);
752         box content
753     }
754
755     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
756         (**self).visit_with(visitor)
757     }
758 }
759
760 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
761     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
762         self.iter().map(|t| t.fold_with(folder)).collect()
763     }
764
765     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
766         self.iter().any(|t| t.visit_with(visitor))
767     }
768 }
769
770 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
771     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
772         self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice()
773     }
774
775     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
776         self.iter().any(|t| t.visit_with(visitor))
777     }
778 }
779
780 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
781     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
782         self.map_bound_ref(|ty| ty.fold_with(folder))
783     }
784
785     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
786         folder.fold_binder(self)
787     }
788
789     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
790         self.skip_binder().visit_with(visitor)
791     }
792
793     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
794         visitor.visit_binder(self)
795     }
796 }
797
798 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
799     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
800         let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
801         folder.tcx().intern_existential_predicates(&v)
802     }
803
804     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
805         self.iter().any(|p| p.visit_with(visitor))
806     }
807 }
808
809 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
810     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
811         let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
812         folder.tcx().intern_type_list(&v)
813     }
814
815     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
816         self.iter().any(|t| t.visit_with(visitor))
817     }
818 }
819
820 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
821     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
822         let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
823         folder.tcx().intern_projs(&v)
824     }
825
826     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
827         self.iter().any(|t| t.visit_with(visitor))
828     }
829 }
830
831 impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
832     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
833         use crate::ty::InstanceDef::*;
834         Self {
835             substs: self.substs.fold_with(folder),
836             def: match self.def {
837                 Item(did) => Item(did.fold_with(folder)),
838                 VtableShim(did) => VtableShim(did.fold_with(folder)),
839                 ReifyShim(did) => ReifyShim(did.fold_with(folder)),
840                 Intrinsic(did) => Intrinsic(did.fold_with(folder)),
841                 FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)),
842                 Virtual(did, i) => Virtual(did.fold_with(folder), i),
843                 ClosureOnceShim { call_once } => {
844                     ClosureOnceShim { call_once: call_once.fold_with(folder) }
845                 }
846                 DropGlue(did, ty) => DropGlue(did.fold_with(folder), ty.fold_with(folder)),
847                 CloneShim(did, ty) => CloneShim(did.fold_with(folder), ty.fold_with(folder)),
848             },
849         }
850     }
851
852     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
853         use crate::ty::InstanceDef::*;
854         self.substs.visit_with(visitor)
855             || match self.def {
856                 Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
857                     did.visit_with(visitor)
858                 }
859                 FnPtrShim(did, ty) | CloneShim(did, ty) => {
860                     did.visit_with(visitor) || ty.visit_with(visitor)
861                 }
862                 DropGlue(did, ty) => did.visit_with(visitor) || ty.visit_with(visitor),
863                 ClosureOnceShim { call_once } => call_once.visit_with(visitor),
864             }
865     }
866 }
867
868 impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
869     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
870         Self { instance: self.instance.fold_with(folder), promoted: self.promoted }
871     }
872
873     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
874         self.instance.visit_with(visitor)
875     }
876 }
877
878 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
879     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
880         let kind = match self.kind {
881             ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
882             ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
883             ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
884             ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)),
885             ty::Dynamic(ref trait_ty, ref region) => {
886                 ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder))
887             }
888             ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)),
889             ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.fold_with(folder)),
890             ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)),
891             ty::Ref(ref r, ty, mutbl) => ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl),
892             ty::Generator(did, substs, movability) => {
893                 ty::Generator(did, substs.fold_with(folder), movability)
894             }
895             ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)),
896             ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)),
897             ty::Projection(ref data) => ty::Projection(data.fold_with(folder)),
898             ty::UnnormalizedProjection(ref data) => {
899                 ty::UnnormalizedProjection(data.fold_with(folder))
900             }
901             ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)),
902
903             ty::Bool
904             | ty::Char
905             | ty::Str
906             | ty::Int(_)
907             | ty::Uint(_)
908             | ty::Float(_)
909             | ty::Error
910             | ty::Infer(_)
911             | ty::Param(..)
912             | ty::Bound(..)
913             | ty::Placeholder(..)
914             | ty::Never
915             | ty::Foreign(..) => return self,
916         };
917
918         if self.kind == kind { self } else { folder.tcx().mk_ty(kind) }
919     }
920
921     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
922         folder.fold_ty(*self)
923     }
924
925     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
926         match self.kind {
927             ty::RawPtr(ref tm) => tm.visit_with(visitor),
928             ty::Array(typ, sz) => typ.visit_with(visitor) || sz.visit_with(visitor),
929             ty::Slice(typ) => typ.visit_with(visitor),
930             ty::Adt(_, substs) => substs.visit_with(visitor),
931             ty::Dynamic(ref trait_ty, ref reg) => {
932                 trait_ty.visit_with(visitor) || reg.visit_with(visitor)
933             }
934             ty::Tuple(ts) => ts.visit_with(visitor),
935             ty::FnDef(_, substs) => substs.visit_with(visitor),
936             ty::FnPtr(ref f) => f.visit_with(visitor),
937             ty::Ref(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor),
938             ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
939             ty::GeneratorWitness(ref types) => types.visit_with(visitor),
940             ty::Closure(_did, ref substs) => substs.visit_with(visitor),
941             ty::Projection(ref data) | ty::UnnormalizedProjection(ref data) => {
942                 data.visit_with(visitor)
943             }
944             ty::Opaque(_, ref substs) => substs.visit_with(visitor),
945
946             ty::Bool
947             | ty::Char
948             | ty::Str
949             | ty::Int(_)
950             | ty::Uint(_)
951             | ty::Float(_)
952             | ty::Error
953             | ty::Infer(_)
954             | ty::Bound(..)
955             | ty::Placeholder(..)
956             | ty::Param(..)
957             | ty::Never
958             | ty::Foreign(..) => false,
959         }
960     }
961
962     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
963         visitor.visit_ty(self)
964     }
965 }
966
967 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
968     fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
969         *self
970     }
971
972     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
973         folder.fold_region(*self)
974     }
975
976     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
977         false
978     }
979
980     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
981         visitor.visit_region(*self)
982     }
983 }
984
985 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
986     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
987         // This code is hot enough that it's worth specializing for a list of
988         // length 0. (No other length is common enough to be worth singling
989         // out).
990         if self.len() == 0 {
991             self
992         } else {
993             // Don't bother interning if nothing changed, which is the common
994             // case.
995             let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
996             if v[..] == self[..] { self } else { folder.tcx().intern_predicates(&v) }
997         }
998     }
999
1000     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1001         self.iter().any(|p| p.visit_with(visitor))
1002     }
1003 }
1004
1005 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
1006     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
1007         self.iter().map(|x| x.fold_with(folder)).collect()
1008     }
1009
1010     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1011         self.iter().any(|t| t.visit_with(visitor))
1012     }
1013 }
1014
1015 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
1016     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
1017         let ty = self.ty.fold_with(folder);
1018         let val = self.val.fold_with(folder);
1019         folder.tcx().mk_const(ty::Const { ty, val })
1020     }
1021
1022     fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
1023         folder.fold_const(*self)
1024     }
1025
1026     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1027         self.ty.visit_with(visitor) || self.val.visit_with(visitor)
1028     }
1029
1030     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1031         visitor.visit_const(self)
1032     }
1033 }
1034
1035 impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
1036     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
1037         match *self {
1038             ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)),
1039             ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)),
1040             ty::ConstKind::Unevaluated(did, substs, promoted) => {
1041                 ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted)
1042             }
1043             ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => {
1044                 *self
1045             }
1046         }
1047     }
1048
1049     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
1050         match *self {
1051             ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
1052             ty::ConstKind::Param(p) => p.visit_with(visitor),
1053             ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor),
1054             ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
1055                 false
1056             }
1057         }
1058     }
1059 }
1060
1061 impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
1062     fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
1063         *self
1064     }
1065
1066     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
1067         false
1068     }
1069 }