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_hir::def::Namespace;
11use rustc_hir::def_id::LocalDefId;
12use rustc_span::Span;
13use rustc_span::source_map::Spanned;
14use rustc_type_ir::{ConstKind, VisitorResult, try_visit};
15
16use super::print::PrettyPrinter;
17use super::{GenericArg, GenericArgKind, Pattern, Region};
18use crate::mir::PlaceElem;
19use crate::ty::print::{FmtPrinter, Printer, with_no_trimmed_paths};
20use crate::ty::{
21    self, FallibleTypeFolder, InferConst, Lift, Term, TermKind, Ty, TyCtxt, TypeFoldable,
22    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
23};
24
25impl fmt::Debug for ty::TraitDef {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        ty::tls::with(|tcx| {
28            with_no_trimmed_paths!({
29                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
30                    cx.print_def_path(self.def_id, &[])
31                })?;
32                f.write_str(&s)
33            })
34        })
35    }
36}
37
38impl<'tcx> fmt::Debug for ty::AdtDef<'tcx> {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        ty::tls::with(|tcx| {
41            with_no_trimmed_paths!({
42                let s = FmtPrinter::print_string(tcx, Namespace::TypeNS, |cx| {
43                    cx.print_def_path(self.did(), &[])
44                })?;
45                f.write_str(&s)
46            })
47        })
48    }
49}
50
51impl fmt::Debug for ty::UpvarId {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        let name = ty::tls::with(|tcx| tcx.hir_name(self.var_path.hir_id));
54        write!(f, "UpvarId({:?};`{}`;{:?})", self.var_path.hir_id, name, self.closure_expr_id)
55    }
56}
57
58impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        write!(f, "{:?} -> {}", self.kind, self.target)
61    }
62}
63
64impl fmt::Debug for ty::BoundRegionKind {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        match *self {
67            ty::BoundRegionKind::Anon => write!(f, "BrAnon"),
68            ty::BoundRegionKind::Named(did, name) => {
69                if did.is_crate_root() {
70                    write!(f, "BrNamed({name})")
71                } else {
72                    write!(f, "BrNamed({did:?}, {name})")
73                }
74            }
75            ty::BoundRegionKind::ClosureEnv => write!(f, "BrEnv"),
76        }
77    }
78}
79
80impl fmt::Debug for ty::LateParamRegion {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        write!(f, "ReLateParam({:?}, {:?})", self.scope, self.kind)
83    }
84}
85
86impl fmt::Debug for ty::LateParamRegionKind {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        match *self {
89            ty::LateParamRegionKind::Anon(idx) => write!(f, "BrAnon({idx})"),
90            ty::LateParamRegionKind::Named(did, name) => {
91                if did.is_crate_root() {
92                    write!(f, "BrNamed({name})")
93                } else {
94                    write!(f, "BrNamed({did:?}, {name})")
95                }
96            }
97            ty::LateParamRegionKind::ClosureEnv => write!(f, "BrEnv"),
98        }
99    }
100}
101
102impl<'tcx> fmt::Debug for Ty<'tcx> {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        with_no_trimmed_paths!(fmt::Debug::fmt(self.kind(), f))
105    }
106}
107
108impl fmt::Debug for ty::ParamTy {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        write!(f, "{}/#{}", self.name, self.index)
111    }
112}
113
114impl fmt::Debug for ty::ParamConst {
115    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116        write!(f, "{}/#{}", self.name, self.index)
117    }
118}
119
120impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
121    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122        write!(f, "{:?}", self.kind())
123    }
124}
125
126impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
127    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128        write!(f, "{:?}", self.kind())
129    }
130}
131
132impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> {
133    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134        match self.kind {
135            ty::ExprKind::Binop(op) => {
136                let (lhs_ty, rhs_ty, lhs, rhs) = self.binop_args();
137                write!(f, "({op:?}: ({:?}: {:?}), ({:?}: {:?}))", lhs, lhs_ty, rhs, rhs_ty,)
138            }
139            ty::ExprKind::UnOp(op) => {
140                let (rhs_ty, rhs) = self.unop_args();
141                write!(f, "({op:?}: ({:?}: {:?}))", rhs, rhs_ty)
142            }
143            ty::ExprKind::FunctionCall => {
144                let (func_ty, func, args) = self.call_args();
145                let args = args.collect::<Vec<_>>();
146                write!(f, "({:?}: {:?})(", func, func_ty)?;
147                for arg in args.iter().rev().skip(1).rev() {
148                    write!(f, "{:?}, ", arg)?;
149                }
150                if let Some(arg) = args.last() {
151                    write!(f, "{:?}", arg)?;
152                }
153
154                write!(f, ")")
155            }
156            ty::ExprKind::Cast(kind) => {
157                let (value_ty, value, to_ty) = self.cast_args();
158                write!(f, "({kind:?}: ({:?}: {:?}), {:?})", value, value_ty, to_ty)
159            }
160        }
161    }
162}
163
164impl<'tcx> fmt::Debug for ty::Const<'tcx> {
165    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166        // If this is a value, we spend some effort to make it look nice.
167        if let ConstKind::Value(cv) = self.kind() {
168            return ty::tls::with(move |tcx| {
169                let cv = tcx.lift(cv).unwrap();
170                let mut cx = FmtPrinter::new(tcx, Namespace::ValueNS);
171                cx.pretty_print_const_valtree(cv, /*print_ty*/ true)?;
172                f.write_str(&cx.into_buffer())
173            });
174        }
175        // Fall back to something verbose.
176        write!(f, "{:?}", self.kind())
177    }
178}
179
180impl fmt::Debug for ty::BoundTy {
181    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182        match self.kind {
183            ty::BoundTyKind::Anon => write!(f, "{:?}", self.var),
184            ty::BoundTyKind::Param(_, sym) => write!(f, "{sym:?}"),
185        }
186    }
187}
188
189impl<T: fmt::Debug> fmt::Debug for ty::Placeholder<T> {
190    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191        if self.universe == ty::UniverseIndex::ROOT {
192            write!(f, "!{:?}", self.bound)
193        } else {
194            write!(f, "!{}_{:?}", self.universe.index(), self.bound)
195        }
196    }
197}
198
199impl<'tcx> fmt::Debug for GenericArg<'tcx> {
200    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201        match self.unpack() {
202            GenericArgKind::Lifetime(lt) => lt.fmt(f),
203            GenericArgKind::Type(ty) => ty.fmt(f),
204            GenericArgKind::Const(ct) => ct.fmt(f),
205        }
206    }
207}
208
209impl<'tcx> fmt::Debug for Region<'tcx> {
210    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211        write!(f, "{:?}", self.kind())
212    }
213}
214
215///////////////////////////////////////////////////////////////////////////
216// Atomic structs
217//
218// For things that don't carry any arena-allocated data (and are
219// copy...), just add them to one of these lists as appropriate.
220
221// For things for which the type library provides traversal implementations
222// for all Interners, we only need to provide a Lift implementation.
223TrivialLiftImpls! {
224    (),
225    bool,
226    usize,
227    u64,
228    // tidy-alphabetical-start
229    crate::mir::interpret::AllocId,
230    crate::mir::interpret::Scalar,
231    crate::mir::Promoted,
232    rustc_abi::ExternAbi,
233    rustc_abi::Size,
234    rustc_hir::Safety,
235    rustc_type_ir::BoundConstness,
236    rustc_type_ir::PredicatePolarity,
237    // tidy-alphabetical-end
238}
239
240// For some things about which the type library does not know, or does not
241// provide any traversal implementations, we need to provide a traversal
242// implementation (only for TyCtxt<'_> interners).
243TrivialTypeTraversalImpls! {
244    // tidy-alphabetical-start
245    crate::infer::canonical::Certainty,
246    crate::mir::BasicBlock,
247    crate::mir::BindingForm<'tcx>,
248    crate::mir::BlockTailInfo,
249    crate::mir::BorrowKind,
250    crate::mir::CastKind,
251    crate::mir::ConstValue<'tcx>,
252    crate::mir::CoroutineSavedLocal,
253    crate::mir::FakeReadCause,
254    crate::mir::Local,
255    crate::mir::MirPhase,
256    crate::mir::NullOp<'tcx>,
257    crate::mir::Promoted,
258    crate::mir::RawPtrKind,
259    crate::mir::RetagKind,
260    crate::mir::SourceInfo,
261    crate::mir::SourceScope,
262    crate::mir::SourceScopeLocalData,
263    crate::mir::SwitchTargets,
264    crate::traits::IsConstable,
265    crate::traits::OverflowError,
266    crate::ty::abstract_const::NotConstEvaluatable,
267    crate::ty::adjustment::AutoBorrowMutability,
268    crate::ty::adjustment::PointerCoercion,
269    crate::ty::AdtKind,
270    crate::ty::AssocItem,
271    crate::ty::AssocKind,
272    crate::ty::BoundRegion,
273    crate::ty::BoundVar,
274    crate::ty::Placeholder<crate::ty::BoundRegion>,
275    crate::ty::Placeholder<crate::ty::BoundTy>,
276    crate::ty::Placeholder<ty::BoundVar>,
277    crate::ty::UserTypeAnnotationIndex,
278    crate::ty::ValTree<'tcx>,
279    rustc_abi::FieldIdx,
280    rustc_abi::VariantIdx,
281    rustc_ast::InlineAsmOptions,
282    rustc_ast::InlineAsmTemplatePiece,
283    rustc_hir::CoroutineKind,
284    rustc_hir::def_id::LocalDefId,
285    rustc_hir::HirId,
286    rustc_hir::MatchSource,
287    rustc_hir::RangeEnd,
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(trait_ty, 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(sig_tys, _) => sig_tys.visit_with(visitor),
458            ty::UnsafeBinder(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, args) => args.visit_with(visitor),
464            ty::CoroutineWitness(_did, args) => args.visit_with(visitor),
465            ty::Closure(_did, args) => args.visit_with(visitor),
466            ty::CoroutineClosure(_did, args) => args.visit_with(visitor),
467            ty::Alias(_, 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}