]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/structural_impls.rs
Unify Opaque/Projection handling in region outlives code
[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, 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 ///////////////////////////////////////////////////////////////////////////
184 // Atomic structs
185 //
186 // For things that don't carry any arena-allocated data (and are
187 // copy...), just add them to this list.
188
189 TrivialTypeTraversalAndLiftImpls! {
190     (),
191     bool,
192     usize,
193     ::rustc_target::abi::VariantIdx,
194     u32,
195     u64,
196     String,
197     crate::middle::region::Scope,
198     crate::ty::FloatTy,
199     ::rustc_ast::InlineAsmOptions,
200     ::rustc_ast::InlineAsmTemplatePiece,
201     ::rustc_ast::NodeId,
202     ::rustc_span::symbol::Symbol,
203     ::rustc_hir::def::Res,
204     ::rustc_hir::def_id::DefId,
205     ::rustc_hir::def_id::LocalDefId,
206     ::rustc_hir::HirId,
207     ::rustc_hir::MatchSource,
208     ::rustc_hir::Mutability,
209     ::rustc_hir::Unsafety,
210     ::rustc_target::asm::InlineAsmRegOrRegClass,
211     ::rustc_target::spec::abi::Abi,
212     crate::mir::coverage::ExpressionOperandId,
213     crate::mir::coverage::CounterValueReference,
214     crate::mir::coverage::InjectedExpressionId,
215     crate::mir::coverage::InjectedExpressionIndex,
216     crate::mir::coverage::MappedExpressionIndex,
217     crate::mir::Local,
218     crate::mir::Promoted,
219     crate::traits::Reveal,
220     crate::ty::adjustment::AutoBorrowMutability,
221     crate::ty::AdtKind,
222     crate::ty::BoundConstness,
223     // Including `BoundRegionKind` is a *bit* dubious, but direct
224     // references to bound region appear in `ty::Error`, and aren't
225     // really meant to be folded. In general, we can only fold a fully
226     // general `Region`.
227     crate::ty::BoundRegionKind,
228     crate::ty::AssocItem,
229     crate::ty::AssocKind,
230     crate::ty::AliasKind,
231     crate::ty::Placeholder<crate::ty::BoundRegionKind>,
232     crate::ty::ClosureKind,
233     crate::ty::FreeRegion,
234     crate::ty::InferTy,
235     crate::ty::IntVarValue,
236     crate::ty::ParamConst,
237     crate::ty::ParamTy,
238     crate::ty::adjustment::PointerCast,
239     crate::ty::RegionVid,
240     crate::ty::UniverseIndex,
241     crate::ty::Variance,
242     ::rustc_span::Span,
243     ::rustc_errors::ErrorGuaranteed,
244     Field,
245     interpret::Scalar,
246     rustc_target::abi::Size,
247     rustc_type_ir::DebruijnIndex,
248     ty::BoundVar,
249     ty::Placeholder<ty::BoundVar>,
250 }
251
252 TrivialTypeTraversalAndLiftImpls! {
253     for<'tcx> {
254         ty::ValTree<'tcx>,
255     }
256 }
257
258 ///////////////////////////////////////////////////////////////////////////
259 // Lift implementations
260
261 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
262     type Lifted = (A::Lifted, B::Lifted);
263     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
264         Some((tcx.lift(self.0)?, tcx.lift(self.1)?))
265     }
266 }
267
268 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
269     type Lifted = (A::Lifted, B::Lifted, C::Lifted);
270     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
271         Some((tcx.lift(self.0)?, tcx.lift(self.1)?, tcx.lift(self.2)?))
272     }
273 }
274
275 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
276     type Lifted = Option<T::Lifted>;
277     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
278         Some(match self {
279             Some(x) => Some(tcx.lift(x)?),
280             None => None,
281         })
282     }
283 }
284
285 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
286     type Lifted = Result<T::Lifted, E::Lifted>;
287     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
288         match self {
289             Ok(x) => tcx.lift(x).map(Ok),
290             Err(e) => tcx.lift(e).map(Err),
291         }
292     }
293 }
294
295 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
296     type Lifted = Box<T::Lifted>;
297     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
298         Some(Box::new(tcx.lift(*self)?))
299     }
300 }
301
302 impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Rc<T> {
303     type Lifted = Rc<T::Lifted>;
304     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
305         Some(Rc::new(tcx.lift(self.as_ref().clone())?))
306     }
307 }
308
309 impl<'tcx, T: Lift<'tcx> + Clone> Lift<'tcx> for Arc<T> {
310     type Lifted = Arc<T::Lifted>;
311     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
312         Some(Arc::new(tcx.lift(self.as_ref().clone())?))
313     }
314 }
315 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
316     type Lifted = Vec<T::Lifted>;
317     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
318         self.into_iter().map(|v| tcx.lift(v)).collect()
319     }
320 }
321
322 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
323     type Lifted = IndexVec<I, T::Lifted>;
324     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
325         self.into_iter().map(|e| tcx.lift(e)).collect()
326     }
327 }
328
329 impl<'a, 'tcx> Lift<'tcx> for Term<'a> {
330     type Lifted = ty::Term<'tcx>;
331     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
332         Some(
333             match self.unpack() {
334                 TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
335                 TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
336             }
337             .pack(),
338         )
339     }
340 }
341 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
342     type Lifted = ty::ParamEnv<'tcx>;
343     fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
344         tcx.lift(self.caller_bounds())
345             .map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
346     }
347 }
348
349 ///////////////////////////////////////////////////////////////////////////
350 // TypeFoldable implementations.
351
352 /// AdtDefs are basically the same as a DefId.
353 impl<'tcx> TypeFoldable<'tcx> for ty::AdtDef<'tcx> {
354     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
355         Ok(self)
356     }
357 }
358
359 impl<'tcx> TypeVisitable<'tcx> for ty::AdtDef<'tcx> {
360     fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
361         ControlFlow::CONTINUE
362     }
363 }
364
365 impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
366     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
367         self,
368         folder: &mut F,
369     ) -> Result<(T, U), F::Error> {
370         Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?))
371     }
372 }
373
374 impl<'tcx, T: TypeVisitable<'tcx>, U: TypeVisitable<'tcx>> TypeVisitable<'tcx> for (T, U) {
375     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
376         self.0.visit_with(visitor)?;
377         self.1.visit_with(visitor)
378     }
379 }
380
381 impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
382     for (A, B, C)
383 {
384     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
385         self,
386         folder: &mut F,
387     ) -> Result<(A, B, C), F::Error> {
388         Ok((
389             self.0.try_fold_with(folder)?,
390             self.1.try_fold_with(folder)?,
391             self.2.try_fold_with(folder)?,
392         ))
393     }
394 }
395
396 impl<'tcx, A: TypeVisitable<'tcx>, B: TypeVisitable<'tcx>, C: TypeVisitable<'tcx>>
397     TypeVisitable<'tcx> for (A, B, C)
398 {
399     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
400         self.0.visit_with(visitor)?;
401         self.1.visit_with(visitor)?;
402         self.2.visit_with(visitor)
403     }
404 }
405
406 EnumTypeTraversalImpl! {
407     impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
408         (Some)(a),
409         (None),
410     } where T: TypeFoldable<'tcx>
411 }
412 EnumTypeTraversalImpl! {
413     impl<'tcx, T> TypeVisitable<'tcx> for Option<T> {
414         (Some)(a),
415         (None),
416     } where T: TypeVisitable<'tcx>
417 }
418
419 EnumTypeTraversalImpl! {
420     impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
421         (Ok)(a),
422         (Err)(a),
423     } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
424 }
425 EnumTypeTraversalImpl! {
426     impl<'tcx, T, E> TypeVisitable<'tcx> for Result<T, E> {
427         (Ok)(a),
428         (Err)(a),
429     } where T: TypeVisitable<'tcx>, E: TypeVisitable<'tcx>,
430 }
431
432 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
433     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
434         mut self,
435         folder: &mut F,
436     ) -> Result<Self, F::Error> {
437         // We merely want to replace the contained `T`, if at all possible,
438         // so that we don't needlessly allocate a new `Rc` or indeed clone
439         // the contained type.
440         unsafe {
441             // First step is to ensure that we have a unique reference to
442             // the contained type, which `Rc::make_mut` will accomplish (by
443             // allocating a new `Rc` and cloning the `T` only if required).
444             // This is done *before* casting to `Rc<ManuallyDrop<T>>` so that
445             // panicking during `make_mut` does not leak the `T`.
446             Rc::make_mut(&mut self);
447
448             // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
449             // is `repr(transparent)`.
450             let ptr = Rc::into_raw(self).cast::<ManuallyDrop<T>>();
451             let mut unique = Rc::from_raw(ptr);
452
453             // Call to `Rc::make_mut` above guarantees that `unique` is the
454             // sole reference to the contained value, so we can avoid doing
455             // a checked `get_mut` here.
456             let slot = Rc::get_mut_unchecked(&mut unique);
457
458             // Semantically move the contained type out from `unique`, fold
459             // it, then move the folded value back into `unique`.  Should
460             // folding fail, `ManuallyDrop` ensures that the "moved-out"
461             // value is not re-dropped.
462             let owned = ManuallyDrop::take(slot);
463             let folded = owned.try_fold_with(folder)?;
464             *slot = ManuallyDrop::new(folded);
465
466             // Cast back to `Rc<T>`.
467             Ok(Rc::from_raw(Rc::into_raw(unique).cast()))
468         }
469     }
470 }
471
472 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Rc<T> {
473     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
474         (**self).visit_with(visitor)
475     }
476 }
477
478 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
479     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(
480         mut self,
481         folder: &mut F,
482     ) -> Result<Self, F::Error> {
483         // We merely want to replace the contained `T`, if at all possible,
484         // so that we don't needlessly allocate a new `Arc` or indeed clone
485         // the contained type.
486         unsafe {
487             // First step is to ensure that we have a unique reference to
488             // the contained type, which `Arc::make_mut` will accomplish (by
489             // allocating a new `Arc` and cloning the `T` only if required).
490             // This is done *before* casting to `Arc<ManuallyDrop<T>>` so that
491             // panicking during `make_mut` does not leak the `T`.
492             Arc::make_mut(&mut self);
493
494             // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
495             // is `repr(transparent)`.
496             let ptr = Arc::into_raw(self).cast::<ManuallyDrop<T>>();
497             let mut unique = Arc::from_raw(ptr);
498
499             // Call to `Arc::make_mut` above guarantees that `unique` is the
500             // sole reference to the contained value, so we can avoid doing
501             // a checked `get_mut` here.
502             let slot = Arc::get_mut_unchecked(&mut unique);
503
504             // Semantically move the contained type out from `unique`, fold
505             // it, then move the folded value back into `unique`.  Should
506             // folding fail, `ManuallyDrop` ensures that the "moved-out"
507             // value is not re-dropped.
508             let owned = ManuallyDrop::take(slot);
509             let folded = owned.try_fold_with(folder)?;
510             *slot = ManuallyDrop::new(folded);
511
512             // Cast back to `Arc<T>`.
513             Ok(Arc::from_raw(Arc::into_raw(unique).cast()))
514         }
515     }
516 }
517
518 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Arc<T> {
519     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
520         (**self).visit_with(visitor)
521     }
522 }
523
524 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
525     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
526         self.try_map_id(|value| value.try_fold_with(folder))
527     }
528 }
529
530 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<T> {
531     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
532         (**self).visit_with(visitor)
533     }
534 }
535
536 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
537     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
538         self.try_map_id(|t| t.try_fold_with(folder))
539     }
540 }
541
542 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec<T> {
543     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
544         self.iter().try_for_each(|t| t.visit_with(visitor))
545     }
546 }
547
548 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] {
549     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
550         self.iter().try_for_each(|t| t.visit_with(visitor))
551     }
552 }
553
554 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
555     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
556         self.try_map_id(|t| t.try_fold_with(folder))
557     }
558 }
559
560 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Box<[T]> {
561     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
562         self.iter().try_for_each(|t| t.visit_with(visitor))
563     }
564 }
565
566 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
567     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
568         folder.try_fold_binder(self)
569     }
570 }
571
572 impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for ty::Binder<'tcx, T> {
573     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
574         visitor.visit_binder(self)
575     }
576 }
577
578 impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<'tcx> for ty::Binder<'tcx, T> {
579     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
580         self,
581         folder: &mut F,
582     ) -> Result<Self, F::Error> {
583         self.try_map_bound(|ty| ty.try_fold_with(folder))
584     }
585 }
586
587 impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<'tcx> for ty::Binder<'tcx, T> {
588     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
589         self.as_ref().skip_binder().visit_with(visitor)
590     }
591 }
592
593 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
594     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
595         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
596     }
597 }
598
599 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Const<'tcx>> {
600     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
601         ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v.iter()))
602     }
603 }
604
605 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
606     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
607         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
608     }
609 }
610
611 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
612     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
613         folder.try_fold_ty(self)
614     }
615 }
616
617 impl<'tcx> TypeVisitable<'tcx> for Ty<'tcx> {
618     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
619         visitor.visit_ty(*self)
620     }
621 }
622
623 impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
624     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
625         self,
626         folder: &mut F,
627     ) -> Result<Self, F::Error> {
628         let kind = match *self.kind() {
629             ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?),
630             ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
631             ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
632             ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
633             ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
634                 trait_ty.try_fold_with(folder)?,
635                 region.try_fold_with(folder)?,
636                 representation,
637             ),
638             ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
639             ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
640             ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
641             ty::Ref(r, ty, mutbl) => {
642                 ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
643             }
644             ty::Generator(did, substs, movability) => {
645                 ty::Generator(did, substs.try_fold_with(folder)?, movability)
646             }
647             ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
648             ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
649             ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
650
651             ty::Bool
652             | ty::Char
653             | ty::Str
654             | ty::Int(_)
655             | ty::Uint(_)
656             | ty::Float(_)
657             | ty::Error(_)
658             | ty::Infer(_)
659             | ty::Param(..)
660             | ty::Bound(..)
661             | ty::Placeholder(..)
662             | ty::Never
663             | ty::Foreign(..) => return Ok(self),
664         };
665
666         Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) })
667     }
668 }
669
670 impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> {
671     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
672         match self.kind() {
673             ty::RawPtr(ref tm) => tm.visit_with(visitor),
674             ty::Array(typ, sz) => {
675                 typ.visit_with(visitor)?;
676                 sz.visit_with(visitor)
677             }
678             ty::Slice(typ) => typ.visit_with(visitor),
679             ty::Adt(_, substs) => substs.visit_with(visitor),
680             ty::Dynamic(ref trait_ty, ref reg, _) => {
681                 trait_ty.visit_with(visitor)?;
682                 reg.visit_with(visitor)
683             }
684             ty::Tuple(ts) => ts.visit_with(visitor),
685             ty::FnDef(_, substs) => substs.visit_with(visitor),
686             ty::FnPtr(ref f) => f.visit_with(visitor),
687             ty::Ref(r, ty, _) => {
688                 r.visit_with(visitor)?;
689                 ty.visit_with(visitor)
690             }
691             ty::Generator(_did, ref substs, _) => substs.visit_with(visitor),
692             ty::GeneratorWitness(ref types) => types.visit_with(visitor),
693             ty::Closure(_did, ref substs) => substs.visit_with(visitor),
694             ty::Alias(_, ref data) => data.visit_with(visitor),
695
696             ty::Bool
697             | ty::Char
698             | ty::Str
699             | ty::Int(_)
700             | ty::Uint(_)
701             | ty::Float(_)
702             | ty::Error(_)
703             | ty::Infer(_)
704             | ty::Bound(..)
705             | ty::Placeholder(..)
706             | ty::Param(..)
707             | ty::Never
708             | ty::Foreign(..) => ControlFlow::CONTINUE,
709         }
710     }
711 }
712
713 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
714     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
715         folder.try_fold_region(self)
716     }
717 }
718
719 impl<'tcx> TypeVisitable<'tcx> for ty::Region<'tcx> {
720     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
721         visitor.visit_region(*self)
722     }
723 }
724
725 impl<'tcx> TypeSuperFoldable<'tcx> for ty::Region<'tcx> {
726     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
727         self,
728         _folder: &mut F,
729     ) -> Result<Self, F::Error> {
730         Ok(self)
731     }
732 }
733
734 impl<'tcx> TypeSuperVisitable<'tcx> for ty::Region<'tcx> {
735     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
736         ControlFlow::CONTINUE
737     }
738 }
739
740 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
741     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
742         folder.try_fold_predicate(self)
743     }
744 }
745
746 impl<'tcx> TypeVisitable<'tcx> for ty::Predicate<'tcx> {
747     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
748         visitor.visit_predicate(*self)
749     }
750
751     #[inline]
752     fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
753         self.outer_exclusive_binder() > binder
754     }
755
756     #[inline]
757     fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
758         self.flags().intersects(flags)
759     }
760 }
761
762 impl<'tcx> TypeSuperFoldable<'tcx> for ty::Predicate<'tcx> {
763     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
764         self,
765         folder: &mut F,
766     ) -> Result<Self, F::Error> {
767         let new = self.kind().try_fold_with(folder)?;
768         Ok(folder.tcx().reuse_or_mk_predicate(self, new))
769     }
770 }
771
772 impl<'tcx> TypeSuperVisitable<'tcx> for ty::Predicate<'tcx> {
773     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
774         self.kind().visit_with(visitor)
775     }
776 }
777
778 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
779     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
780         ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
781     }
782 }
783
784 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
785     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
786         self.try_map_id(|x| x.try_fold_with(folder))
787     }
788 }
789
790 impl<'tcx, T: TypeVisitable<'tcx>, I: Idx> TypeVisitable<'tcx> for IndexVec<I, T> {
791     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
792         self.iter().try_for_each(|t| t.visit_with(visitor))
793     }
794 }
795
796 impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
797     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
798         folder.try_fold_const(self)
799     }
800 }
801
802 impl<'tcx> TypeVisitable<'tcx> for ty::Const<'tcx> {
803     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
804         visitor.visit_const(*self)
805     }
806 }
807
808 impl<'tcx> TypeSuperFoldable<'tcx> for ty::Const<'tcx> {
809     fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
810         self,
811         folder: &mut F,
812     ) -> Result<Self, F::Error> {
813         let ty = self.ty().try_fold_with(folder)?;
814         let kind = self.kind().try_fold_with(folder)?;
815         if ty != self.ty() || kind != self.kind() {
816             Ok(folder.tcx().mk_const(kind, ty))
817         } else {
818             Ok(self)
819         }
820     }
821 }
822
823 impl<'tcx> TypeSuperVisitable<'tcx> for ty::Const<'tcx> {
824     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
825         self.ty().visit_with(visitor)?;
826         self.kind().visit_with(visitor)
827     }
828 }
829
830 impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
831     fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
832         Ok(self)
833     }
834 }
835
836 impl<'tcx> TypeVisitable<'tcx> for InferConst<'tcx> {
837     fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
838         ControlFlow::CONTINUE
839     }
840 }
841
842 impl<'tcx> TypeSuperVisitable<'tcx> for ty::UnevaluatedConst<'tcx> {
843     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
844         self.substs.visit_with(visitor)
845     }
846 }