]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/structural_impls.rs
Rollup merge of #107109 - est31:thin_box_link, r=Mark-Simulacrum
[rust.git] / compiler / rustc_middle / src / 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::{Field, ProjectionKind};
7 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
8 use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
9 use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
10 use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
11 use rustc_data_structures::functor::IdFunctor;
12 use rustc_hir::def::Namespace;
13 use rustc_index::vec::{Idx, IndexVec};
14
15 use std::fmt;
16 use std::mem::ManuallyDrop;
17 use std::ops::ControlFlow;
18 use std::rc::Rc;
19 use std::sync::Arc;
20
21 impl fmt::Debug for ty::TraitDef {
22     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23         ty::tls::with(|tcx| {
24             with_no_trimmed_paths!({
25                 f.write_str(
26                     &FmtPrinter::new(tcx, Namespace::TypeNS)
27                         .print_def_path(self.def_id, &[])?
28                         .into_buffer(),
29                 )
30             })
31         })
32     }
33 }
34
35 impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
36     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37         ty::tls::with(|tcx| {
38             with_no_trimmed_paths!({
39                 f.write_str(
40                     &FmtPrinter::new(tcx, Namespace::TypeNS)
41                         .print_def_path(self.did(), &[])?
42                         .into_buffer(),
43                 )
44             })
45         })
46     }
47 }
48
49 impl fmt::Debug for ty::UpvarId {
50     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51         let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id));
52         write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id)
53     }
54 }
55
56 impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
57     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58         with_no_trimmed_paths!(fmt::Display::fmt(self, f))
59     }
60 }
61
62 impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
63     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64         write!(f, "{:?} -> {}", self.kind, self.target)
65     }
66 }
67
68 impl fmt::Debug for ty::BoundRegionKind {
69     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70         match *self {
71             ty::BrAnon(n, span) => write!(f, "BrAnon({n:?}, {span:?})"),
72             ty::BrNamed(did, name) => {
73                 if did.is_crate_root() {
74                     write!(f, "BrNamed({})", name)
75                 } else {
76                     write!(f, "BrNamed({:?}, {})", did, name)
77                 }
78             }
79             ty::BrEnv => write!(f, "BrEnv"),
80         }
81     }
82 }
83
84 impl fmt::Debug for ty::FreeRegion {
85     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86         write!(f, "ReFree({:?}, {:?})", self.scope, self.bound_region)
87     }
88 }
89
90 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
91     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92         write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
93     }
94 }
95
96 impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
97     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98         write!(f, "_#{}c", self.index)
99     }
100 }
101
102 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
103     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104         with_no_trimmed_paths!(fmt::Display::fmt(self, f))
105     }
106 }
107
108 impl<'tcx> fmt::Debug for Ty<'tcx> {
109     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110         with_no_trimmed_paths!(fmt::Display::fmt(self, f))
111     }
112 }
113
114 impl fmt::Debug for ty::ParamTy {
115     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116         write!(f, "{}/#{}", self.name, self.index)
117     }
118 }
119
120 impl fmt::Debug for ty::ParamConst {
121     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122         write!(f, "{}/#{}", self.name, self.index)
123     }
124 }
125
126 impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
127     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128         if let ty::BoundConstness::ConstIfConst = self.constness {
129             write!(f, "~const ")?;
130         }
131         write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
132     }
133 }
134
135 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
136     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137         write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term)
138     }
139 }
140
141 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
142     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143         write!(f, "{:?}", self.kind())
144     }
145 }
146
147 impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
148     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149         match *self {
150             ty::Clause::Trait(ref a) => a.fmt(f),
151             ty::Clause::RegionOutlives(ref pair) => pair.fmt(f),
152             ty::Clause::TypeOutlives(ref pair) => pair.fmt(f),
153             ty::Clause::Projection(ref pair) => pair.fmt(f),
154         }
155     }
156 }
157
158 impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
159     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160         match *self {
161             ty::PredicateKind::Clause(ref a) => a.fmt(f),
162             ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
163             ty::PredicateKind::Coerce(ref pair) => pair.fmt(f),
164             ty::PredicateKind::WellFormed(data) => write!(f, "WellFormed({:?})", data),
165             ty::PredicateKind::ObjectSafe(trait_def_id) => {
166                 write!(f, "ObjectSafe({:?})", trait_def_id)
167             }
168             ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
169                 write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
170             }
171             ty::PredicateKind::ConstEvaluatable(ct) => {
172                 write!(f, "ConstEvaluatable({ct:?})")
173             }
174             ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
175             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
176                 write!(f, "TypeWellFormedFromEnv({:?})", ty)
177             }
178             ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"),
179         }
180     }
181 }
182
183 impl<'tcx> fmt::Debug for AliasTy<'tcx> {
184     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185         f.debug_struct("AliasTy")
186             .field("substs", &self.substs)
187             .field("def_id", &self.def_id)
188             .finish()
189     }
190 }
191
192 ///////////////////////////////////////////////////////////////////////////
193 // Atomic structs
194 //
195 // For things that don't carry any arena-allocated data (and are
196 // copy...), just add them to this list.
197
198 TrivialTypeTraversalAndLiftImpls! {
199     (),
200     bool,
201     usize,
202     ::rustc_target::abi::VariantIdx,
203     u32,
204     u64,
205     String,
206     crate::middle::region::Scope,
207     crate::ty::FloatTy,
208     ::rustc_ast::InlineAsmOptions,
209     ::rustc_ast::InlineAsmTemplatePiece,
210     ::rustc_ast::NodeId,
211     ::rustc_span::symbol::Symbol,
212     ::rustc_hir::def::Res,
213     ::rustc_hir::def_id::DefId,
214     ::rustc_hir::def_id::LocalDefId,
215     ::rustc_hir::HirId,
216     ::rustc_hir::MatchSource,
217     ::rustc_hir::Mutability,
218     ::rustc_hir::Unsafety,
219     ::rustc_target::asm::InlineAsmRegOrRegClass,
220     ::rustc_target::spec::abi::Abi,
221     crate::mir::coverage::ExpressionOperandId,
222     crate::mir::coverage::CounterValueReference,
223     crate::mir::coverage::InjectedExpressionId,
224     crate::mir::coverage::InjectedExpressionIndex,
225     crate::mir::coverage::MappedExpressionIndex,
226     crate::mir::Local,
227     crate::mir::Promoted,
228     crate::traits::Reveal,
229     crate::ty::adjustment::AutoBorrowMutability,
230     crate::ty::AdtKind,
231     crate::ty::BoundConstness,
232     // Including `BoundRegionKind` is a *bit* dubious, but direct
233     // references to bound region appear in `ty::Error`, and aren't
234     // really meant to be folded. In general, we can only fold a fully
235     // general `Region`.
236     crate::ty::BoundRegionKind,
237     crate::ty::AssocItem,
238     crate::ty::AssocKind,
239     crate::ty::AliasKind,
240     crate::ty::Placeholder<crate::ty::BoundRegionKind>,
241     crate::ty::ClosureKind,
242     crate::ty::FreeRegion,
243     crate::ty::InferTy,
244     crate::ty::IntVarValue,
245     crate::ty::ParamConst,
246     crate::ty::ParamTy,
247     crate::ty::adjustment::PointerCast,
248     crate::ty::RegionVid,
249     crate::ty::UniverseIndex,
250     crate::ty::Variance,
251     ::rustc_span::Span,
252     ::rustc_errors::ErrorGuaranteed,
253     Field,
254     interpret::Scalar,
255     rustc_target::abi::Size,
256     rustc_type_ir::DebruijnIndex,
257     ty::BoundVar,
258     ty::Placeholder<ty::BoundVar>,
259 }
260
261 TrivialTypeTraversalAndLiftImpls! {
262     for<'tcx> {
263         ty::ValTree<'tcx>,
264     }
265 }
266
267 ///////////////////////////////////////////////////////////////////////////
268 // Lift implementations
269
270 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
271     type Lifted = (A::Lifted, B::Lifted);
272     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
273         Some((tcx.lift(self.0)?, tcx.lift(self.1)?))
274     }
275 }
276
277 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
278     type Lifted = (A::Lifted, B::Lifted, C::Lifted);
279     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
280         Some((tcx.lift(self.0)?, tcx.lift(self.1)?, tcx.lift(self.2)?))
281     }
282 }
283
284 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
285     type Lifted = Option<T::Lifted>;
286     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
287         Some(match self {
288             Some(x) => Some(tcx.lift(x)?),
289             None => None,
290         })
291     }
292 }
293
294 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
295     type Lifted = Result<T::Lifted, E::Lifted>;
296     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
297         match self {
298             Ok(x) => tcx.lift(x).map(Ok),
299             Err(e) => tcx.lift(e).map(Err),
300         }
301     }
302 }
303
304 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
305     type Lifted = Box<T::Lifted>;
306     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
307         Some(Box::new(tcx.lift(*self)?))
308     }
309 }
310
311 impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> {
312     type Lifted = Rc<T::Lifted>;
313     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
314         Some(Rc::new(tcx.lift(self.as_ref().clone())?))
315     }
316 }
317
318 impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> {
319     type Lifted = Arc<T::Lifted>;
320     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
321         Some(Arc::new(tcx.lift(self.as_ref().clone())?))
322     }
323 }
324 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
325     type Lifted = Vec<T::Lifted>;
326     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
327         self.into_iter().map(|v| tcx.lift(v)).collect()
328     }
329 }
330
331 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
332     type Lifted = IndexVec<I, T::Lifted>;
333     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
334         self.into_iter().map(|e| tcx.lift(e)).collect()
335     }
336 }
337
338 impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
339     type Lifted = ty::Term<'tcx>;
340     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
341         Some(
342             match self.unpack() {
343                 TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
344                 TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
345             }
346             .pack(),
347         )
348     }
349 }
350 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
351     type Lifted = ty::ParamEnv<'tcx>;
352     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
353         tcx.lift(self.caller_bounds())
354             .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
355     }
356 }
357
358 ///////////////////////////////////////////////////////////////////////////
359 // TypeFoldable implementations.
360
361 /// AdtDefs are basically the same as a DefId.
362 impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> {
363     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
364         Ok(self)
365     }
366 }
367
368 impl<'tcx> TypeVisitable<'tcx> for ty::AdtDef<'tcx> {
369     fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
370         ControlFlow::Continue(())
371     }
372 }
373
374 impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
375     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
376         self,
377         folder: &mut F,
378     ) -> Result<(T, U), F::Error> {
379         Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?))
380     }
381 }
382
383 impl<'tcx, T: TypeVisitable<'tcx>, U: TypeVisitable<'tcx>> TypeVisitable<'tcx> for (T, U) {
384     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
385         self.0.visit_with(visitor)?;
386         self.1.visit_with(visitor)
387     }
388 }
389
390 impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
391     for (A, B, C)
392 {
393     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
394         self,
395         folder: &mut F,
396     ) -> Result<(A, B, C), F::Error> {
397         Ok((
398             self.0.try_fold_with(folder)?,
399             self.1.try_fold_with(folder)?,
400             self.2.try_fold_with(folder)?,
401         ))
402     }
403 }
404
405 impl<'tcx, A: TypeVisitable<'tcx>, B: TypeVisitable<'tcx>, C: TypeVisitable<'tcx>>
406     TypeVisitable<'tcx> for (A, B, C)
407 {
408     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
409         self.0.visit_with(visitor)?;
410         self.1.visit_with(visitor)?;
411         self.2.visit_with(visitor)
412     }
413 }
414
415 EnumTypeTraversalImpl! {
416     impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
417         (Some)(a),
418         (None),
419     } where T: TypeFoldable<'tcx>
420 }
421 EnumTypeTraversalImpl! {
422     impl<'tcx, T> TypeVisitable<'tcx> for Option<T> {
423         (Some)(a),
424         (None),
425     } where T: TypeVisitable<'tcx>
426 }
427
428 EnumTypeTraversalImpl! {
429     impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
430         (Ok)(a),
431         (Err)(a),
432     } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
433 }
434 EnumTypeTraversalImpl! {
435     impl<'tcx, T, E> TypeVisitable<'tcx> for Result<T, E> {
436         (Ok)(a),
437         (Err)(a),
438     } where T: TypeVisitable<'tcx>, E: TypeVisitable<'tcx>,
439 }
440
441 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
442     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
443         mut self,
444         folder: &mut F,
445     ) -> Result<Self, F::Error> {
446         // We merely want to replace the contained `T`, if at all possible,
447         // so that we don't needlessly allocate a new `Rc` or indeed clone
448         // the contained type.
449         unsafe {
450             // First step is to ensure that we have a unique reference to
451             // the contained type, which `Rc::make_mut` will accomplish (by
452             // allocating a new `Rc` and cloning the `T` only if required).
453             // This is done *before* casting to `Rc<ManuallyDrop<T>>` so that
454             // panicking during `make_mut` does not leak the `T`.
455             Rc::make_mut(&mut self);
456
457             // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
458             // is `repr(transparent)`.
459             let ptr = Rc::into_raw(self).cast::<ManuallyDrop<T>>();
460             let mut unique = Rc::from_raw(ptr);
461
462             // Call to `Rc::make_mut` above guarantees that `unique` is the
463             // sole reference to the contained value, so we can avoid doing
464             // a checked `get_mut` here.
465             let slot = Rc::get_mut_unchecked(&mut unique);
466
467             // Semantically move the contained type out from `unique`, fold
468             // it, then move the folded value back into `unique`. Should
469             // folding fail, `ManuallyDrop` ensures that the "moved-out"
470             // value is not re-dropped.
471             let owned = ManuallyDrop::take(slot);
472             let folded = owned.try_fold_with(folder)?;
473             *slot = ManuallyDrop::new(folded);
474
475             // Cast back to `Rc<T>`.
476             Ok(Rc::from_raw(Rc::into_raw(unique).cast()))
477         }
478     }
479 }
480
481 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Rc<T> {
482     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
483         (**self).visit_with(visitor)
484     }
485 }
486
487 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
488     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
489         mut self,
490         folder: &mut F,
491     ) -> Result<Self, F::Error> {
492         // We merely want to replace the contained `T`, if at all possible,
493         // so that we don't needlessly allocate a new `Arc` or indeed clone
494         // the contained type.
495         unsafe {
496             // First step is to ensure that we have a unique reference to
497             // the contained type, which `Arc::make_mut` will accomplish (by
498             // allocating a new `Arc` and cloning the `T` only if required).
499             // This is done *before* casting to `Arc<ManuallyDrop<T>>` so that
500             // panicking during `make_mut` does not leak the `T`.
501             Arc::make_mut(&mut self);
502
503             // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
504             // is `repr(transparent)`.
505             let ptr = Arc::into_raw(self).cast::<ManuallyDrop<T>>();
506             let mut unique = Arc::from_raw(ptr);
507
508             // Call to `Arc::make_mut` above guarantees that `unique` is the
509             // sole reference to the contained value, so we can avoid doing
510             // a checked `get_mut` here.
511             let slot = Arc::get_mut_unchecked(&mut unique);
512
513             // Semantically move the contained type out from `unique`, fold
514             // it, then move the folded value back into `unique`. Should
515             // folding fail, `ManuallyDrop` ensures that the "moved-out"
516             // value is not re-dropped.
517             let owned = ManuallyDrop::take(slot);
518             let folded = owned.try_fold_with(folder)?;
519             *slot = ManuallyDrop::new(folded);
520
521             // Cast back to `Arc<T>`.
522             Ok(Arc::from_raw(Arc::into_raw(unique).cast()))
523         }
524     }
525 }
526
527 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Arc<T> {
528     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
529         (**self).visit_with(visitor)
530     }
531 }
532
533 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
534     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
535         self.try_map_id(|value| value.try_fold_with(folder))
536     }
537 }
538
539 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<T> {
540     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
541         (**self).visit_with(visitor)
542     }
543 }
544
545 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
546     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
547         self.try_map_id(|t| t.try_fold_with(folder))
548     }
549 }
550
551 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec<T> {
552     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
553         self.iter().try_for_each(|t| t.visit_with(visitor))
554     }
555 }
556
557 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] {
558     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
559         self.iter().try_for_each(|t| t.visit_with(visitor))
560     }
561 }
562
563 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
564     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
565         self.try_map_id(|t| t.try_fold_with(folder))
566     }
567 }
568
569 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<[T]> {
570     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
571         self.iter().try_for_each(|t| t.visit_with(visitor))
572     }
573 }
574
575 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
576     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
577         folder.try_fold_binder(self)
578     }
579 }
580
581 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for ty::Binder<'tcx, T> {
582     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
583         visitor.visit_binder(self)
584     }
585 }
586
587 impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T> {
588     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
589         self,
590         folder: &mut F,
591     ) -> Result<Self, F::Error> {
592         self.try_map_bound(|ty| ty.try_fold_with(folder))
593     }
594 }
595
596 impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<'tcx> for ty::Binder<'tcx, T> {
597     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
598         self.as_ref().skip_binder().visit_with(visitor)
599     }
600 }
601
602 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
603     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
604         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
605     }
606 }
607
608 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Const<'tcx>> {
609     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
610         ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v.iter()))
611     }
612 }
613
614 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
615     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
616         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
617     }
618 }
619
620 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
621     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
622         folder.try_fold_ty(self)
623     }
624 }
625
626 impl<'tcx> TypeVisitable<'tcx> for Ty<'tcx> {
627     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
628         visitor.visit_ty(*self)
629     }
630 }
631
632 impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
633     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
634         self,
635         folder: &mut F,
636     ) -> Result<Self, F::Error> {
637         let kind = match *self.kind() {
638             ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?),
639             ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
640             ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
641             ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
642             ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
643                 trait_ty.try_fold_with(folder)?,
644                 region.try_fold_with(folder)?,
645                 representation,
646             ),
647             ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
648             ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
649             ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
650             ty::Ref(r, ty, mutbl) => {
651                 ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
652             }
653             ty::Generator(did, substs, movability) => {
654                 ty::Generator(did, substs.try_fold_with(folder)?, movability)
655             }
656             ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
657             ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
658             ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
659
660             ty::Bool
661             | ty::Char
662             | ty::Str
663             | ty::Int(_)
664             | ty::Uint(_)
665             | ty::Float(_)
666             | ty::Error(_)
667             | ty::Infer(_)
668             | ty::Param(..)
669             | ty::Bound(..)
670             | ty::Placeholder(..)
671             | ty::Never
672             | ty::Foreign(..) => return Ok(self),
673         };
674
675         Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) })
676     }
677 }
678
679 impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> {
680     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
681         match self.kind() {
682             ty::RawPtr(ref tm) => tm.visit_with(visitor),
683             ty::Array(typ, sz) => {
684                 typ.visit_with(visitor)?;
685                 sz.visit_with(visitor)
686             }
687             ty::Slice(typ) => typ.visit_with(visitor),
688             ty::Adt(_, substs) => substs.visit_with(visitor),
689             ty::Dynamic(ref trait_ty, ref reg, _) => {
690                 trait_ty.visit_with(visitor)?;
691                 reg.visit_with(visitor)
692             }
693             ty::Tuple(ts) => ts.visit_with(visitor),
694             ty::FnDef(_, substs) => substs.visit_with(visitor),
695             ty::FnPtr(ref f) => f.visit_with(visitor),
696             ty::Ref(r, ty, _) => {
697                 r.visit_with(visitor)?;
698                 ty.visit_with(visitor)
699             }
700             ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
701             ty::GeneratorWitness(ref types) => types.visit_with(visitor),
702             ty::Closure(_did, ref substs) => substs.visit_with(visitor),
703             ty::Alias(_, ref data) => data.visit_with(visitor),
704
705             ty::Bool
706             | ty::Char
707             | ty::Str
708             | ty::Int(_)
709             | ty::Uint(_)
710             | ty::Float(_)
711             | ty::Error(_)
712             | ty::Infer(_)
713             | ty::Bound(..)
714             | ty::Placeholder(..)
715             | ty::Param(..)
716             | ty::Never
717             | ty::Foreign(..) => ControlFlow::Continue(()),
718         }
719     }
720 }
721
722 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
723     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
724         folder.try_fold_region(self)
725     }
726 }
727
728 impl<'tcx> TypeVisitable<'tcx> for ty::Region<'tcx> {
729     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
730         visitor.visit_region(*self)
731     }
732 }
733
734 impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> {
735     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
736         self,
737         _folder: &mut F,
738     ) -> Result<Self, F::Error> {
739         Ok(self)
740     }
741 }
742
743 impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> {
744     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
745         ControlFlow::Continue(())
746     }
747 }
748
749 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
750     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
751         folder.try_fold_predicate(self)
752     }
753 }
754
755 impl<'tcx> TypeVisitable<'tcx> for ty::Predicate<'tcx> {
756     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
757         visitor.visit_predicate(*self)
758     }
759
760     #[inline]
761     fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
762         self.outer_exclusive_binder() > binder
763     }
764
765     #[inline]
766     fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
767         self.flags().intersects(flags)
768     }
769 }
770
771 impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> {
772     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
773         self,
774         folder: &mut F,
775     ) -> Result<Self, F::Error> {
776         let new = self.kind().try_fold_with(folder)?;
777         Ok(folder.tcx().reuse_or_mk_predicate(self, new))
778     }
779 }
780
781 impl<'tcx> TypeSuperVisitable<'tcx> for ty::Predicate<'tcx> {
782     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
783         self.kind().visit_with(visitor)
784     }
785 }
786
787 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
788     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
789         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
790     }
791 }
792
793 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
794     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
795         self.try_map_id(|x| x.try_fold_with(folder))
796     }
797 }
798
799 impl<'tcx, T: TypeVisitable<'tcx>, I: Idx> TypeVisitable<'tcx> for IndexVec<I, T> {
800     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
801         self.iter().try_for_each(|t| t.visit_with(visitor))
802     }
803 }
804
805 impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
806     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
807         folder.try_fold_const(self)
808     }
809 }
810
811 impl<'tcx> TypeVisitable<'tcx> for ty::Const<'tcx> {
812     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
813         visitor.visit_const(*self)
814     }
815 }
816
817 impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> {
818     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
819         self,
820         folder: &mut F,
821     ) -> Result<Self, F::Error> {
822         let ty = self.ty().try_fold_with(folder)?;
823         let kind = self.kind().try_fold_with(folder)?;
824         if ty != self.ty() || kind != self.kind() {
825             Ok(folder.tcx().mk_const(kind, ty))
826         } else {
827             Ok(self)
828         }
829     }
830 }
831
832 impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> {
833     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
834         self.ty().visit_with(visitor)?;
835         self.kind().visit_with(visitor)
836     }
837 }
838
839 impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
840     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
841         Ok(self)
842     }
843 }
844
845 impl<'tcx> TypeVisitable<'tcx> for InferConst<'tcx> {
846     fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
847         ControlFlow::Continue(())
848     }
849 }
850
851 impl<'tcx> TypeSuperVisitable<'tcx> for ty::UnevaluatedConst<'tcx> {
852     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
853         self.substs.visit_with(visitor)
854     }
855 }