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