rustc_middle/ty/
structural_impls.rs

1//! This module contains implementations of the `Lift`, `TypeFoldable` and
2//! `TypeVisitable` traits for various types in the Rust compiler. Most are
3//! written by hand, though we've recently added some macros and proc-macros
4//! to help with the tedium.
5
6use std::fmt::{self, Debug};
7
8use rustc_abi::TyAndLayout;
9use rustc_ast::InlineAsmTemplatePiece;
10use rustc_ast_ir::try_visit;
11use rustc_ast_ir::visit::VisitorResult;
12use rustc_hir::def::Namespace;
13use rustc_hir::def_id::LocalDefId;
14use rustc_span::Span;
15use rustc_span::source_map::Spanned;
16use rustc_type_ir::ConstKind;
17
18use super::print::PrettyPrinter;
19use super::{GenericArg, GenericArgKind, Pattern, Region};
20use crate::mir::PlaceElem;
21use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
22use crate::ty::print::{FmtPrinter, Printer, with_no_trimmed_paths};
23use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
24use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
25
26impl fmt::Debug for ty::TraitDef {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        ty::tls::with(|tcx| {
29            with_no_trimmed_paths!({
30                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
31                    cx.print_def_path(self.def_id, &[])
32                })?;
33                f.write_str(&s)
34            })
35        })
36    }
37}
38
39impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        ty::tls::with(|tcx| {
42            with_no_trimmed_paths!({
43                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
44                    cx.print_def_path(self.did(), &[])
45                })?;
46                f.write_str(&s)
47            })
48        })
49    }
50}
51
52impl fmt::Debug for ty::UpvarId {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        let name = ty::tls::with(|tcx| tcx.hir().name(self.var_path.hir_id));
55        write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id)
56    }
57}
58
59impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(f, "{:?} -> {}", self.kind, self.target)
62    }
63}
64
65impl fmt::Debug for ty::BoundRegionKind {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        match *self {
68            ty::BoundRegionKind::Anon => write!(f, "BrAnon"),
69            ty::BoundRegionKind::Named(did, name) => {
70                if did.is_crate_root() {
71                    write!(f, "BrNamed({name})")
72                } else {
73                    write!(f, "BrNamed({did:?}, {name})")
74                }
75            }
76            ty::BoundRegionKind::ClosureEnv => write!(f, "BrEnv"),
77        }
78    }
79}
80
81impl fmt::Debug for ty::LateParamRegion {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        write!(f, "ReLateParam({:?}, {:?})", self.scope, self.kind)
84    }
85}
86
87impl fmt::Debug for ty::LateParamRegionKind {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        match *self {
90            ty::LateParamRegionKind::Anon(idx) => write!(f, "BrAnon({idx})"),
91            ty::LateParamRegionKind::Named(did, name) => {
92                if did.is_crate_root() {
93                    write!(f, "BrNamed({name})")
94                } else {
95                    write!(f, "BrNamed({did:?}, {name})")
96                }
97            }
98            ty::LateParamRegionKind::ClosureEnv => write!(f, "BrEnv"),
99        }
100    }
101}
102
103impl<'tcx> fmt::Debug for Ty<'tcx> {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        with_no_trimmed_paths!(fmt::Debug::fmt(self.kind(), f))
106    }
107}
108
109impl fmt::Debug for ty::ParamTy {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        write!(f, "{}/#{}", self.name, self.index)
112    }
113}
114
115impl fmt::Debug for ty::ParamConst {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        write!(f, "{}/#{}", self.name, self.index)
118    }
119}
120
121impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
122    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123        write!(f, "{:?}", self.kind())
124    }
125}
126
127impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129        write!(f, "{:?}", self.kind())
130    }
131}
132
133impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        match self.kind {
136            ty::ExprKind::Binop(op) => {
137                let (lhs_ty, rhs_ty, lhs, rhs) = self.binop_args();
138                write!(f, "({op:?}: ({:?}: {:?}), ({:?}: {:?}))", lhs, lhs_ty, rhs, rhs_ty,)
139            }
140            ty::ExprKind::UnOp(op) => {
141                let (rhs_ty, rhs) = self.unop_args();
142                write!(f, "({op:?}: ({:?}: {:?}))", rhs, rhs_ty)
143            }
144            ty::ExprKind::FunctionCall => {
145                let (func_ty, func, args) = self.call_args();
146                let args = args.collect::<Vec<_>>();
147                write!(f, "({:?}: {:?})(", func, func_ty)?;
148                for arg in args.iter().rev().skip(1).rev() {
149                    write!(f, "{:?}, ", arg)?;
150                }
151                if let Some(arg) = args.last() {
152                    write!(f, "{:?}", arg)?;
153                }
154
155                write!(f, ")")
156            }
157            ty::ExprKind::Cast(kind) => {
158                let (value_ty, value, to_ty) = self.cast_args();
159                write!(f, "({kind:?}: ({:?}: {:?}), {:?})", value, value_ty, to_ty)
160            }
161        }
162    }
163}
164
165impl<'tcx> fmt::Debug for ty::Const<'tcx> {
166    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167        // If this is a value, we spend some effort to make it look nice.
168        if let ConstKind::Value(cv) = self.kind() {
169            return ty::tls::with(move |tcx| {
170                let cv = tcx.lift(cv).unwrap();
171                let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
172                cx.pretty_print_const_valtree(cv, /*print_ty*/ true)?;
173                f.write_str(&cx.into_buffer())
174            });
175        }
176        // Fall back to something verbose.
177        write!(f, "{:?}", self.kind())
178    }
179}
180
181impl fmt::Debug for ty::BoundTy {
182    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183        match self.kind {
184            ty::BoundTyKind::Anon => write!(f, "{:?}", self.var),
185            ty::BoundTyKind::Param(_, sym) => write!(f, "{sym:?}"),
186        }
187    }
188}
189
190impl<T: fmt::Debug> fmt::Debug for ty::Placeholder<T> {
191    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192        if self.universe == ty::UniverseIndex::ROOT {
193            write!(f, "!{:?}", self.bound)
194        } else {
195            write!(f, "!{}_{:?}", self.universe.index(), self.bound)
196        }
197    }
198}
199
200impl<'tcx> fmt::Debug for GenericArg<'tcx> {
201    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202        match self.unpack() {
203            GenericArgKind::Lifetime(lt) => lt.fmt(f),
204            GenericArgKind::Type(ty) => ty.fmt(f),
205            GenericArgKind::Const(ct) => ct.fmt(f),
206        }
207    }
208}
209
210impl<'tcx> fmt::Debug for Region<'tcx> {
211    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212        write!(f, "{:?}", self.kind())
213    }
214}
215
216///////////////////////////////////////////////////////////////////////////
217// Atomic structs
218//
219// For things that don't carry any arena-allocated data (and are
220// copy...), just add them to one of these lists as appropriate.
221
222// For things for which the type library provides traversal implementations
223// for all Interners, we only need to provide a Lift implementation.
224TrivialLiftImpls! {
225    (),
226    bool,
227    usize,
228    u64,
229    // tidy-alphabetical-start
230    crate::mir::interpret::AllocId,
231    crate::mir::interpret::Scalar,
232    crate::mir::Promoted,
233    rustc_abi::ExternAbi,
234    rustc_abi::Size,
235    rustc_hir::Safety,
236    rustc_type_ir::BoundConstness,
237    rustc_type_ir::PredicatePolarity,
238    // tidy-alphabetical-end
239}
240
241// For some things about which the type library does not know, or does not
242// provide any traversal implementations, we need to provide a traversal
243// implementation (only for TyCtxt<'_> interners).
244TrivialTypeTraversalImpls! {
245    // tidy-alphabetical-start
246    crate::infer::canonical::Certainty,
247    crate::mir::BasicBlock,
248    crate::mir::BindingForm<'tcx>,
249    crate::mir::BlockTailInfo,
250    crate::mir::BorrowKind,
251    crate::mir::CastKind,
252    crate::mir::ConstValue<'tcx>,
253    crate::mir::CoroutineSavedLocal,
254    crate::mir::FakeReadCause,
255    crate::mir::Local,
256    crate::mir::MirPhase,
257    crate::mir::NullOp<'tcx>,
258    crate::mir::Promoted,
259    crate::mir::RawPtrKind,
260    crate::mir::RetagKind,
261    crate::mir::SourceInfo,
262    crate::mir::SourceScope,
263    crate::mir::SourceScopeLocalData,
264    crate::mir::SwitchTargets,
265    crate::traits::IsConstable,
266    crate::traits::OverflowError,
267    crate::ty::abstract_const::NotConstEvaluatable,
268    crate::ty::adjustment::AutoBorrowMutability,
269    crate::ty::adjustment::PointerCoercion,
270    crate::ty::AdtKind,
271    crate::ty::AssocItem,
272    crate::ty::AssocKind,
273    crate::ty::BoundRegion,
274    crate::ty::BoundVar,
275    crate::ty::Placeholder<crate::ty::BoundRegion>,
276    crate::ty::Placeholder<crate::ty::BoundTy>,
277    crate::ty::Placeholder<ty::BoundVar>,
278    crate::ty::UserTypeAnnotationIndex,
279    crate::ty::ValTree<'tcx>,
280    rustc_abi::FieldIdx,
281    rustc_abi::VariantIdx,
282    rustc_ast::InlineAsmOptions,
283    rustc_ast::InlineAsmTemplatePiece,
284    rustc_hir::CoroutineKind,
285    rustc_hir::def_id::LocalDefId,
286    rustc_hir::HirId,
287    rustc_hir::MatchSource,
288    rustc_span::Ident,
289    rustc_span::Span,
290    rustc_span::Symbol,
291    rustc_target::asm::InlineAsmRegOrRegClass,
292    // tidy-alphabetical-end
293}
294
295// For some things about which the type library does not know, or does not
296// provide any traversal implementations, we need to provide a traversal
297// implementation and a lift implementation (the former only for TyCtxt<'_>
298// interners).
299TrivialTypeTraversalAndLiftImpls! {
300    // tidy-alphabetical-start
301    crate::ty::instance::ReifyReason,
302    crate::ty::ParamConst,
303    crate::ty::ParamTy,
304    rustc_hir::def_id::DefId,
305    // tidy-alphabetical-end
306}
307
308///////////////////////////////////////////////////////////////////////////
309// Lift implementations
310
311impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> {
312    type Lifted = Option<T::Lifted>;
313    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
314        Some(match self {
315            Some(x) => Some(tcx.lift(x)?),
316            None => None,
317        })
318    }
319}
320
321impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> {
322    type Lifted = ty::Term<'tcx>;
323    fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
324        match self.unpack() {
325            TermKind::Ty(ty) => tcx.lift(ty).map(Into::into),
326            TermKind::Const(c) => tcx.lift(c).map(Into::into),
327        }
328    }
329}
330
331///////////////////////////////////////////////////////////////////////////
332// Traversal implementations.
333
334impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
335    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, _visitor: &mut V) -> V::Result {
336        V::Result::output()
337    }
338}
339
340impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
341    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
342        self,
343        folder: &mut F,
344    ) -> Result<Self, F::Error> {
345        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_poly_existential_predicates(v))
346    }
347}
348
349impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Const<'tcx>> {
350    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
351        self,
352        folder: &mut F,
353    ) -> Result<Self, F::Error> {
354        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v))
355    }
356}
357
358impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Pattern<'tcx> {
359    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
360        self,
361        folder: &mut F,
362    ) -> Result<Self, F::Error> {
363        let pat = (*self).clone().try_fold_with(folder)?;
364        Ok(if pat == *self { self } else { folder.cx().mk_pat(pat) })
365    }
366}
367
368impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Pattern<'tcx> {
369    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
370        (**self).visit_with(visitor)
371    }
372}
373
374impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
375    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
376        self,
377        folder: &mut F,
378    ) -> Result<Self, F::Error> {
379        folder.try_fold_ty(self)
380    }
381}
382
383impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
384    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
385        visitor.visit_ty(*self)
386    }
387}
388
389impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
390    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
391        self,
392        folder: &mut F,
393    ) -> Result<Self, F::Error> {
394        let kind = match *self.kind() {
395            ty::RawPtr(ty, mutbl) => ty::RawPtr(ty.try_fold_with(folder)?, mutbl),
396            ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
397            ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
398            ty::Adt(tid, args) => ty::Adt(tid, args.try_fold_with(folder)?),
399            ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
400                trait_ty.try_fold_with(folder)?,
401                region.try_fold_with(folder)?,
402                representation,
403            ),
404            ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
405            ty::FnDef(def_id, args) => ty::FnDef(def_id, args.try_fold_with(folder)?),
406            ty::FnPtr(sig_tys, hdr) => ty::FnPtr(sig_tys.try_fold_with(folder)?, hdr),
407            ty::UnsafeBinder(f) => ty::UnsafeBinder(f.try_fold_with(folder)?),
408            ty::Ref(r, ty, mutbl) => {
409                ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
410            }
411            ty::Coroutine(did, args) => ty::Coroutine(did, args.try_fold_with(folder)?),
412            ty::CoroutineWitness(did, args) => {
413                ty::CoroutineWitness(did, args.try_fold_with(folder)?)
414            }
415            ty::Closure(did, args) => ty::Closure(did, args.try_fold_with(folder)?),
416            ty::CoroutineClosure(did, args) => {
417                ty::CoroutineClosure(did, args.try_fold_with(folder)?)
418            }
419            ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
420            ty::Pat(ty, pat) => ty::Pat(ty.try_fold_with(folder)?, pat.try_fold_with(folder)?),
421
422            ty::Bool
423            | ty::Char
424            | ty::Str
425            | ty::Int(_)
426            | ty::Uint(_)
427            | ty::Float(_)
428            | ty::Error(_)
429            | ty::Infer(_)
430            | ty::Param(..)
431            | ty::Bound(..)
432            | ty::Placeholder(..)
433            | ty::Never
434            | ty::Foreign(..) => return Ok(self),
435        };
436
437        Ok(if *self.kind() == kind { self } else { folder.cx().mk_ty_from_kind(kind) })
438    }
439}
440
441impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
442    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
443        match self.kind() {
444            ty::RawPtr(ty, _mutbl) => ty.visit_with(visitor),
445            ty::Array(typ, sz) => {
446                try_visit!(typ.visit_with(visitor));
447                sz.visit_with(visitor)
448            }
449            ty::Slice(typ) => typ.visit_with(visitor),
450            ty::Adt(_, args) => args.visit_with(visitor),
451            ty::Dynamic(ref trait_ty, ref reg, _) => {
452                try_visit!(trait_ty.visit_with(visitor));
453                reg.visit_with(visitor)
454            }
455            ty::Tuple(ts) => ts.visit_with(visitor),
456            ty::FnDef(_, args) => args.visit_with(visitor),
457            ty::FnPtr(ref sig_tys, _) => sig_tys.visit_with(visitor),
458            ty::UnsafeBinder(ref f) => f.visit_with(visitor),
459            ty::Ref(r, ty, _) => {
460                try_visit!(r.visit_with(visitor));
461                ty.visit_with(visitor)
462            }
463            ty::Coroutine(_did, ref args) => args.visit_with(visitor),
464            ty::CoroutineWitness(_did, ref args) => args.visit_with(visitor),
465            ty::Closure(_did, ref args) => args.visit_with(visitor),
466            ty::CoroutineClosure(_did, ref args) => args.visit_with(visitor),
467            ty::Alias(_, ref data) => data.visit_with(visitor),
468
469            ty::Pat(ty, pat) => {
470                try_visit!(ty.visit_with(visitor));
471                pat.visit_with(visitor)
472            }
473
474            ty::Error(guar) => guar.visit_with(visitor),
475
476            ty::Bool
477            | ty::Char
478            | ty::Str
479            | ty::Int(_)
480            | ty::Uint(_)
481            | ty::Float(_)
482            | ty::Infer(_)
483            | ty::Bound(..)
484            | ty::Placeholder(..)
485            | ty::Param(..)
486            | ty::Never
487            | ty::Foreign(..) => V::Result::output(),
488        }
489    }
490}
491
492impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
493    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
494        self,
495        folder: &mut F,
496    ) -> Result<Self, F::Error> {
497        folder.try_fold_region(self)
498    }
499}
500
501impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
502    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
503        visitor.visit_region(*self)
504    }
505}
506
507impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
508    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
509        self,
510        folder: &mut F,
511    ) -> Result<Self, F::Error> {
512        folder.try_fold_predicate(self)
513    }
514}
515
516// FIXME(clause): This is wonky
517impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
518    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
519        self,
520        folder: &mut F,
521    ) -> Result<Self, F::Error> {
522        Ok(folder.try_fold_predicate(self.as_predicate())?.expect_clause())
523    }
524}
525
526impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
527    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
528        visitor.visit_predicate(*self)
529    }
530}
531
532impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
533    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
534        visitor.visit_predicate(self.as_predicate())
535    }
536}
537
538impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
539    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
540        self,
541        folder: &mut F,
542    ) -> Result<Self, F::Error> {
543        let new = self.kind().try_fold_with(folder)?;
544        Ok(folder.cx().reuse_or_mk_predicate(self, new))
545    }
546}
547
548impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
549    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
550        self.kind().visit_with(visitor)
551    }
552}
553
554impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
555    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
556        visitor.visit_clauses(self)
557    }
558}
559
560impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
561    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
562        self.as_slice().visit_with(visitor)
563    }
564}
565
566impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
567    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
568        self,
569        folder: &mut F,
570    ) -> Result<Self, F::Error> {
571        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_clauses(v))
572    }
573}
574
575impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
576    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
577        self,
578        folder: &mut F,
579    ) -> Result<Self, F::Error> {
580        folder.try_fold_const(self)
581    }
582}
583
584impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
585    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
586        visitor.visit_const(*self)
587    }
588}
589
590impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
591    fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
592        self,
593        folder: &mut F,
594    ) -> Result<Self, F::Error> {
595        let kind = match self.kind() {
596            ConstKind::Param(p) => ConstKind::Param(p.try_fold_with(folder)?),
597            ConstKind::Infer(i) => ConstKind::Infer(i.try_fold_with(folder)?),
598            ConstKind::Bound(d, b) => {
599                ConstKind::Bound(d.try_fold_with(folder)?, b.try_fold_with(folder)?)
600            }
601            ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
602            ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
603            ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?),
604            ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
605            ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
606        };
607        if kind != self.kind() { Ok(folder.cx().mk_ct_from_kind(kind)) } else { Ok(self) }
608    }
609}
610
611impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
612    fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
613        match self.kind() {
614            ConstKind::Param(p) => p.visit_with(visitor),
615            ConstKind::Infer(i) => i.visit_with(visitor),
616            ConstKind::Bound(d, b) => {
617                try_visit!(d.visit_with(visitor));
618                b.visit_with(visitor)
619            }
620            ConstKind::Placeholder(p) => p.visit_with(visitor),
621            ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
622            ConstKind::Value(v) => v.visit_with(visitor),
623            ConstKind::Error(e) => e.visit_with(visitor),
624            ConstKind::Expr(e) => e.visit_with(visitor),
625        }
626    }
627}
628
629impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
630    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
631        visitor.visit_error(*self)
632    }
633}
634
635impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
636    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
637        self,
638        _folder: &mut F,
639    ) -> Result<Self, F::Error> {
640        Ok(self)
641    }
642}
643
644impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst {
645    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
646        self,
647        _folder: &mut F,
648    ) -> Result<Self, F::Error> {
649        Ok(self)
650    }
651}
652
653impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst {
654    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, _visitor: &mut V) -> V::Result {
655        V::Result::output()
656    }
657}
658
659impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
660    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
661        visitor.visit_ty(self.ty)
662    }
663}
664
665impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>> + Debug + Clone> TypeVisitable<TyCtxt<'tcx>>
666    for Spanned<T>
667{
668    fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
669        try_visit!(self.node.visit_with(visitor));
670        self.span.visit_with(visitor)
671    }
672}
673
674impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + Debug + Clone> TypeFoldable<TyCtxt<'tcx>>
675    for Spanned<T>
676{
677    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
678        self,
679        folder: &mut F,
680    ) -> Result<Self, F::Error> {
681        Ok(Spanned {
682            node: self.node.try_fold_with(folder)?,
683            span: self.span.try_fold_with(folder)?,
684        })
685    }
686}
687
688impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] {
689    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
690        self,
691        _folder: &mut F,
692    ) -> Result<Self, F::Error> {
693        Ok(self)
694    }
695}
696
697impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [Span] {
698    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
699        self,
700        _folder: &mut F,
701    ) -> Result<Self, F::Error> {
702        Ok(self)
703    }
704}
705
706impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<LocalDefId> {
707    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
708        self,
709        _folder: &mut F,
710    ) -> Result<Self, F::Error> {
711        Ok(self)
712    }
713}
714
715impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<PlaceElem<'tcx>> {
716    fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
717        self,
718        folder: &mut F,
719    ) -> Result<Self, F::Error> {
720        ty::util::fold_list(self, folder, |tcx, v| tcx.mk_place_elems(v))
721    }
722}