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, |cx| {
29 cx.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, |cx| {
42 cx.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 cx = FmtPrinter::new(tcx, Namespace::ValueNS);
174 cx.pretty_print_const_valtree(cv, true)?;
175 f.write_str(&cx.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 rustc_abi::ExternAbi,
236 rustc_abi::Size,
237 rustc_hir::Safety,
238 rustc_middle::mir::ConstValue,
239 rustc_type_ir::BoundConstness,
240 rustc_type_ir::PredicatePolarity,
241 }
243
244TrivialTypeTraversalImpls! {
248 crate::infer::canonical::Certainty,
250 crate::mir::BasicBlock,
251 crate::mir::BindingForm<'tcx>,
252 crate::mir::BlockTailInfo,
253 crate::mir::BorrowKind,
254 crate::mir::CastKind,
255 crate::mir::ConstValue,
256 crate::mir::CoroutineSavedLocal,
257 crate::mir::FakeReadCause,
258 crate::mir::Local,
259 crate::mir::MirPhase,
260 crate::mir::NullOp<'tcx>,
261 crate::mir::Promoted,
262 crate::mir::RawPtrKind,
263 crate::mir::RetagKind,
264 crate::mir::SourceInfo,
265 crate::mir::SourceScope,
266 crate::mir::SourceScopeLocalData,
267 crate::mir::SwitchTargets,
268 crate::traits::IsConstable,
269 crate::traits::OverflowError,
270 crate::ty::AdtKind,
271 crate::ty::AssocItem,
272 crate::ty::AssocKind,
273 crate::ty::BoundRegion,
274 crate::ty::BoundVar,
275 crate::ty::InferConst,
276 crate::ty::Placeholder<crate::ty::BoundRegion>,
277 crate::ty::Placeholder<ty::BoundVar>,
278 crate::ty::UserTypeAnnotationIndex,
279 crate::ty::ValTree<'tcx>,
280 crate::ty::abstract_const::NotConstEvaluatable,
281 crate::ty::adjustment::AutoBorrowMutability,
282 crate::ty::adjustment::PointerCoercion,
283 rustc_abi::FieldIdx,
284 rustc_abi::VariantIdx,
285 rustc_ast::InlineAsmOptions,
286 rustc_ast::InlineAsmTemplatePiece,
287 rustc_hir::CoroutineKind,
288 rustc_hir::HirId,
289 rustc_hir::MatchSource,
290 rustc_hir::RangeEnd,
291 rustc_hir::def_id::LocalDefId,
292 rustc_span::Ident,
293 rustc_span::Span,
294 rustc_span::Symbol,
295 rustc_target::asm::InlineAsmRegOrRegClass,
296 }
298
299TrivialTypeTraversalAndLiftImpls! {
304 crate::ty::ParamConst,
306 crate::ty::ParamTy,
307 crate::ty::Placeholder<crate::ty::BoundTy>,
308 crate::ty::instance::ReifyReason,
309 rustc_hir::def_id::DefId,
310 }
312
313impl<'tcx> Lift<TyCtxt<'tcx>> for PhantomData<&()> {
317 type Lifted = PhantomData<&'tcx ()>;
318 fn lift_to_interner(self, _: TyCtxt<'tcx>) -> Option<Self::Lifted> {
319 Some(PhantomData)
320 }
321}
322
323impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> {
324 type Lifted = Option<T::Lifted>;
325 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
326 Some(match self {
327 Some(x) => Some(tcx.lift(x)?),
328 None => None,
329 })
330 }
331}
332
333impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> {
334 type Lifted = ty::Term<'tcx>;
335 fn lift_to_interner(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
336 match self.kind() {
337 TermKind::Ty(ty) => tcx.lift(ty).map(Into::into),
338 TermKind::Const(c) => tcx.lift(c).map(Into::into),
339 }
340 }
341}
342
343impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> {
347 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, _visitor: &mut V) -> V::Result {
348 V::Result::output()
349 }
350}
351
352impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Pattern<'tcx> {
353 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
354 self,
355 folder: &mut F,
356 ) -> Result<Self, F::Error> {
357 let pat = (*self).clone().try_fold_with(folder)?;
358 Ok(if pat == *self { self } else { folder.cx().mk_pat(pat) })
359 }
360
361 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
362 let pat = (*self).clone().fold_with(folder);
363 if pat == *self { self } else { folder.cx().mk_pat(pat) }
364 }
365}
366
367impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Pattern<'tcx> {
368 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
369 (**self).visit_with(visitor)
370 }
371}
372
373impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
374 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
375 self,
376 folder: &mut F,
377 ) -> Result<Self, F::Error> {
378 folder.try_fold_ty(self)
379 }
380
381 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
382 folder.fold_ty(self)
383 }
384}
385
386impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
387 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
388 visitor.visit_ty(*self)
389 }
390}
391
392impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
393 fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
394 self,
395 folder: &mut F,
396 ) -> Result<Self, F::Error> {
397 let kind = match *self.kind() {
398 ty::RawPtr(ty, mutbl) => ty::RawPtr(ty.try_fold_with(folder)?, mutbl),
399 ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
400 ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
401 ty::Adt(tid, args) => ty::Adt(tid, args.try_fold_with(folder)?),
402 ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
403 trait_ty.try_fold_with(folder)?,
404 region.try_fold_with(folder)?,
405 representation,
406 ),
407 ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
408 ty::FnDef(def_id, args) => ty::FnDef(def_id, args.try_fold_with(folder)?),
409 ty::FnPtr(sig_tys, hdr) => ty::FnPtr(sig_tys.try_fold_with(folder)?, hdr),
410 ty::UnsafeBinder(f) => ty::UnsafeBinder(f.try_fold_with(folder)?),
411 ty::Ref(r, ty, mutbl) => {
412 ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
413 }
414 ty::Coroutine(did, args) => ty::Coroutine(did, args.try_fold_with(folder)?),
415 ty::CoroutineWitness(did, args) => {
416 ty::CoroutineWitness(did, args.try_fold_with(folder)?)
417 }
418 ty::Closure(did, args) => ty::Closure(did, args.try_fold_with(folder)?),
419 ty::CoroutineClosure(did, args) => {
420 ty::CoroutineClosure(did, args.try_fold_with(folder)?)
421 }
422 ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
423 ty::Pat(ty, pat) => ty::Pat(ty.try_fold_with(folder)?, pat.try_fold_with(folder)?),
424
425 ty::Bool
426 | ty::Char
427 | ty::Str
428 | ty::Int(_)
429 | ty::Uint(_)
430 | ty::Float(_)
431 | ty::Error(_)
432 | ty::Infer(_)
433 | ty::Param(..)
434 | ty::Bound(..)
435 | ty::Placeholder(..)
436 | ty::Never
437 | ty::Foreign(..) => return Ok(self),
438 };
439
440 Ok(if *self.kind() == kind { self } else { folder.cx().mk_ty_from_kind(kind) })
441 }
442
443 fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
444 let kind = match *self.kind() {
445 ty::RawPtr(ty, mutbl) => ty::RawPtr(ty.fold_with(folder), mutbl),
446 ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
447 ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
448 ty::Adt(tid, args) => ty::Adt(tid, args.fold_with(folder)),
449 ty::Dynamic(trait_ty, region, representation) => {
450 ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder), representation)
451 }
452 ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)),
453 ty::FnDef(def_id, args) => ty::FnDef(def_id, args.fold_with(folder)),
454 ty::FnPtr(sig_tys, hdr) => ty::FnPtr(sig_tys.fold_with(folder), hdr),
455 ty::UnsafeBinder(f) => ty::UnsafeBinder(f.fold_with(folder)),
456 ty::Ref(r, ty, mutbl) => ty::Ref(r.fold_with(folder), ty.fold_with(folder), mutbl),
457 ty::Coroutine(did, args) => ty::Coroutine(did, args.fold_with(folder)),
458 ty::CoroutineWitness(did, args) => ty::CoroutineWitness(did, args.fold_with(folder)),
459 ty::Closure(did, args) => ty::Closure(did, args.fold_with(folder)),
460 ty::CoroutineClosure(did, args) => ty::CoroutineClosure(did, args.fold_with(folder)),
461 ty::Alias(kind, data) => ty::Alias(kind, data.fold_with(folder)),
462 ty::Pat(ty, pat) => ty::Pat(ty.fold_with(folder), pat.fold_with(folder)),
463
464 ty::Bool
465 | ty::Char
466 | ty::Str
467 | ty::Int(_)
468 | ty::Uint(_)
469 | ty::Float(_)
470 | ty::Error(_)
471 | ty::Infer(_)
472 | ty::Param(..)
473 | ty::Bound(..)
474 | ty::Placeholder(..)
475 | ty::Never
476 | ty::Foreign(..) => return self,
477 };
478
479 if *self.kind() == kind { self } else { folder.cx().mk_ty_from_kind(kind) }
480 }
481}
482
483impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
484 fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
485 match self.kind() {
486 ty::RawPtr(ty, _mutbl) => ty.visit_with(visitor),
487 ty::Array(typ, sz) => {
488 try_visit!(typ.visit_with(visitor));
489 sz.visit_with(visitor)
490 }
491 ty::Slice(typ) => typ.visit_with(visitor),
492 ty::Adt(_, args) => args.visit_with(visitor),
493 ty::Dynamic(trait_ty, reg, _) => {
494 try_visit!(trait_ty.visit_with(visitor));
495 reg.visit_with(visitor)
496 }
497 ty::Tuple(ts) => ts.visit_with(visitor),
498 ty::FnDef(_, args) => args.visit_with(visitor),
499 ty::FnPtr(sig_tys, _) => sig_tys.visit_with(visitor),
500 ty::UnsafeBinder(f) => f.visit_with(visitor),
501 ty::Ref(r, ty, _) => {
502 try_visit!(r.visit_with(visitor));
503 ty.visit_with(visitor)
504 }
505 ty::Coroutine(_did, args) => args.visit_with(visitor),
506 ty::CoroutineWitness(_did, args) => args.visit_with(visitor),
507 ty::Closure(_did, args) => args.visit_with(visitor),
508 ty::CoroutineClosure(_did, args) => args.visit_with(visitor),
509 ty::Alias(_, data) => data.visit_with(visitor),
510
511 ty::Pat(ty, pat) => {
512 try_visit!(ty.visit_with(visitor));
513 pat.visit_with(visitor)
514 }
515
516 ty::Error(guar) => guar.visit_with(visitor),
517
518 ty::Bool
519 | ty::Char
520 | ty::Str
521 | ty::Int(_)
522 | ty::Uint(_)
523 | ty::Float(_)
524 | ty::Infer(_)
525 | ty::Bound(..)
526 | ty::Placeholder(..)
527 | ty::Param(..)
528 | ty::Never
529 | ty::Foreign(..) => V::Result::output(),
530 }
531 }
532}
533
534impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> {
535 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
536 self,
537 folder: &mut F,
538 ) -> Result<Self, F::Error> {
539 folder.try_fold_region(self)
540 }
541
542 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
543 folder.fold_region(self)
544 }
545}
546
547impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> {
548 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
549 visitor.visit_region(*self)
550 }
551}
552
553impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
554 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
555 self,
556 folder: &mut F,
557 ) -> Result<Self, F::Error> {
558 folder.try_fold_predicate(self)
559 }
560
561 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
562 folder.fold_predicate(self)
563 }
564}
565
566impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
568 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
569 self,
570 folder: &mut F,
571 ) -> Result<Self, F::Error> {
572 Ok(folder.try_fold_predicate(self.as_predicate())?.expect_clause())
573 }
574
575 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
576 folder.fold_predicate(self.as_predicate()).expect_clause()
577 }
578}
579
580impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
581 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
582 self,
583 folder: &mut F,
584 ) -> Result<Self, F::Error> {
585 folder.try_fold_clauses(self)
586 }
587
588 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
589 folder.fold_clauses(self)
590 }
591}
592
593impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
594 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
595 visitor.visit_predicate(*self)
596 }
597}
598
599impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clause<'tcx> {
600 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
601 visitor.visit_predicate(self.as_predicate())
602 }
603}
604
605impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
606 fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
607 self,
608 folder: &mut F,
609 ) -> Result<Self, F::Error> {
610 let new = self.kind().try_fold_with(folder)?;
611 Ok(folder.cx().reuse_or_mk_predicate(self, new))
612 }
613
614 fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
615 let new = self.kind().fold_with(folder);
616 folder.cx().reuse_or_mk_predicate(self, new)
617 }
618}
619
620impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> {
621 fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
622 self.kind().visit_with(visitor)
623 }
624}
625
626impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
627 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
628 visitor.visit_clauses(self)
629 }
630}
631
632impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
633 fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
634 self.as_slice().visit_with(visitor)
635 }
636}
637
638impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Clauses<'tcx> {
639 fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
640 self,
641 folder: &mut F,
642 ) -> Result<Self, F::Error> {
643 ty::util::try_fold_list(self, folder, |tcx, v| tcx.mk_clauses(v))
644 }
645
646 fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
647 ty::util::fold_list(self, folder, |tcx, v| tcx.mk_clauses(v))
648 }
649}
650
651impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
652 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
653 self,
654 folder: &mut F,
655 ) -> Result<Self, F::Error> {
656 folder.try_fold_const(self)
657 }
658
659 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
660 folder.fold_const(self)
661 }
662}
663
664impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
665 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
666 visitor.visit_const(*self)
667 }
668}
669
670impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
671 fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
672 self,
673 folder: &mut F,
674 ) -> Result<Self, F::Error> {
675 let kind = match self.kind() {
676 ConstKind::Param(p) => ConstKind::Param(p.try_fold_with(folder)?),
677 ConstKind::Infer(i) => ConstKind::Infer(i.try_fold_with(folder)?),
678 ConstKind::Bound(d, b) => {
679 ConstKind::Bound(d.try_fold_with(folder)?, b.try_fold_with(folder)?)
680 }
681 ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
682 ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
683 ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?),
684 ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
685 ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
686 };
687 if kind != self.kind() { Ok(folder.cx().mk_ct_from_kind(kind)) } else { Ok(self) }
688 }
689
690 fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
691 let kind = match self.kind() {
692 ConstKind::Param(p) => ConstKind::Param(p.fold_with(folder)),
693 ConstKind::Infer(i) => ConstKind::Infer(i.fold_with(folder)),
694 ConstKind::Bound(d, b) => ConstKind::Bound(d.fold_with(folder), b.fold_with(folder)),
695 ConstKind::Placeholder(p) => ConstKind::Placeholder(p.fold_with(folder)),
696 ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.fold_with(folder)),
697 ConstKind::Value(v) => ConstKind::Value(v.fold_with(folder)),
698 ConstKind::Error(e) => ConstKind::Error(e.fold_with(folder)),
699 ConstKind::Expr(e) => ConstKind::Expr(e.fold_with(folder)),
700 };
701 if kind != self.kind() { folder.cx().mk_ct_from_kind(kind) } else { self }
702 }
703}
704
705impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
706 fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
707 match self.kind() {
708 ConstKind::Param(p) => p.visit_with(visitor),
709 ConstKind::Infer(i) => i.visit_with(visitor),
710 ConstKind::Bound(d, b) => {
711 try_visit!(d.visit_with(visitor));
712 b.visit_with(visitor)
713 }
714 ConstKind::Placeholder(p) => p.visit_with(visitor),
715 ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
716 ConstKind::Value(v) => v.visit_with(visitor),
717 ConstKind::Error(e) => e.visit_with(visitor),
718 ConstKind::Expr(e) => e.visit_with(visitor),
719 }
720 }
721}
722
723impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
724 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
725 visitor.visit_error(*self)
726 }
727}
728
729impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for rustc_span::ErrorGuaranteed {
730 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
731 self,
732 _folder: &mut F,
733 ) -> Result<Self, F::Error> {
734 Ok(self)
735 }
736
737 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, _folder: &mut F) -> Self {
738 self
739 }
740}
741
742impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> {
743 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
744 visitor.visit_ty(self.ty)
745 }
746}
747
748impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>> + Debug + Clone> TypeVisitable<TyCtxt<'tcx>>
749 for Spanned<T>
750{
751 fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
752 try_visit!(self.node.visit_with(visitor));
753 self.span.visit_with(visitor)
754 }
755}
756
757impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + Debug + Clone> TypeFoldable<TyCtxt<'tcx>>
758 for Spanned<T>
759{
760 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
761 self,
762 folder: &mut F,
763 ) -> Result<Self, F::Error> {
764 Ok(Spanned {
765 node: self.node.try_fold_with(folder)?,
766 span: self.span.try_fold_with(folder)?,
767 })
768 }
769
770 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
771 Spanned { node: self.node.fold_with(folder), span: self.span.fold_with(folder) }
772 }
773}
774
775impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<LocalDefId> {
776 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
777 self,
778 _folder: &mut F,
779 ) -> Result<Self, F::Error> {
780 Ok(self)
781 }
782
783 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, _folder: &mut F) -> Self {
784 self
785 }
786}
787
788macro_rules! list_fold {
789 ($($ty:ty : $mk:ident),+ $(,)?) => {
790 $(
791 impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for $ty {
792 fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
793 self,
794 folder: &mut F,
795 ) -> Result<Self, F::Error> {
796 ty::util::try_fold_list(self, folder, |tcx, v| tcx.$mk(v))
797 }
798
799 fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(
800 self,
801 folder: &mut F,
802 ) -> Self {
803 ty::util::fold_list(self, folder, |tcx, v| tcx.$mk(v))
804 }
805 }
806 )*
807 }
808}
809
810list_fold! {
811 &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> : mk_poly_existential_predicates,
812 &'tcx ty::List<PlaceElem<'tcx>> : mk_place_elems,
813 &'tcx ty::List<ty::Pattern<'tcx>> : mk_patterns,
814 &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>> : mk_outlives,
815}