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