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