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