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