2 use crate::hir::def::Namespace;
3 use crate::hir::def_id::DefId;
4 use crate::ty::subst::{Kind, SubstsRef, UnpackedKind};
5 use crate::ty::{self, ParamConst, Ty};
6 use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer};
7 use crate::mir::interpret::ConstValue;
9 use std::fmt::{self, Write as _};
12 use rustc_target::spec::abi::Abi;
14 macro_rules! gen_display_debug_body {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
18 $with(&cx.tcx.lift(self).expect("could not lift for printing"), cx)?;
24 macro_rules! gen_display_debug {
25 ( ($($x:tt)+) $target:ty, display yes ) => {
26 impl<$($x)+> fmt::Display for $target {
27 gen_display_debug_body! { Print::print_display }
30 ( () $target:ty, display yes ) => {
31 impl fmt::Display for $target {
32 gen_display_debug_body! { Print::print_display }
35 ( ($($x:tt)+) $target:ty, debug yes ) => {
36 impl<$($x)+> fmt::Debug for $target {
37 gen_display_debug_body! { Print::print_debug }
40 ( () $target:ty, debug yes ) => {
41 impl fmt::Debug for $target {
42 gen_display_debug_body! { Print::print_debug }
45 ( $generic:tt $target:ty, $t:ident no ) => {};
47 macro_rules! gen_print_impl {
48 ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
49 impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target {
51 type Error = fmt::Error;
52 fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
56 define_scoped_cx!($cx);
58 if $cx.config.is_debug $dbg
65 ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
66 impl<P: PrettyPrinter> Print<'tcx, P> for $target {
68 type Error = fmt::Error;
69 fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
73 define_scoped_cx!($cx);
75 if $cx.config.is_debug $dbg
82 ( $generic:tt $target:ty,
83 $vars:tt $gendisp:ident $disp:block $gendbg:ident $dbg:block ) => {
84 gen_print_impl! { $generic $target, $vars $disp $dbg }
85 gen_display_debug! { $generic $target, display $gendisp }
86 gen_display_debug! { $generic $target, debug $gendbg }
89 macro_rules! define_print {
90 ( $generic:tt $target:ty,
91 $vars:tt { display $disp:block debug $dbg:block } ) => {
92 gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
94 ( $generic:tt $target:ty,
95 $vars:tt { debug $dbg:block display $disp:block } ) => {
96 gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
98 ( $generic:tt $target:ty,
99 $vars:tt { debug $dbg:block } ) => {
100 gen_print_impl! { $generic $target, $vars no {
101 bug!(concat!("display not implemented for ", stringify!($target)));
104 ( $generic:tt $target:ty,
105 ($self:ident, $cx:ident) { display $disp:block } ) => {
106 gen_print_impl! { $generic $target, ($self, $cx) yes $disp no {
107 write!($cx.printer, "{:?}", $self)?
111 macro_rules! define_print_multi {
112 ( [ $($generic:tt $target:ty),* ] $vars:tt $def:tt ) => {
113 $(define_print! { $generic $target, $vars $def })*
118 scoped_cx!() = scoped_cx!().nest($closure)?
121 macro_rules! print_inner {
122 (write ($($data:expr),+)) => {
123 write!(scoped_cx!().printer, $($data),+)?
125 ($kind:ident ($data:expr)) => {
126 nest!(|cx| $data.$kind(cx))
130 ($($kind:ident $data:tt),+) => {
132 $(print_inner!($kind $data));+
136 macro_rules! define_scoped_cx {
138 #[allow(unused_macros)]
139 macro_rules! scoped_cx {
145 pub fn parameterized<F: fmt::Write>(
148 substs: SubstsRef<'_>,
151 PrintCx::with_tls_tcx(FmtPrinter::new(f, ns), |cx| {
152 let substs = cx.tcx.lift(&substs).expect("could not lift for printing");
153 cx.print_def_path(did, Some(substs), iter::empty())?;
159 ('tcx) &'tcx ty::List<ty::ExistentialPredicate<'tcx>>, (self, cx) {
161 // Generate the main trait ref, including associated types.
162 let mut first = true;
164 if let Some(principal) = self.principal() {
165 let mut resugared_principal = false;
167 // Special-case `Fn(...) -> ...` and resugar it.
168 let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id);
169 if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() {
170 if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
171 let mut projections = self.projection_bounds();
172 if let (Some(proj), None) = (projections.next(), projections.next()) {
173 nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty()));
174 nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty));
175 resugared_principal = true;
180 if !resugared_principal {
181 // Use a type that can't appear in defaults of type parameters.
182 let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
183 let principal = principal.with_self_ty(cx.tcx, dummy_self);
184 nest!(|cx| cx.print_def_path(
186 Some(principal.substs),
187 self.projection_bounds(),
194 // FIXME(eddyb) avoid printing twice (needed to ensure
195 // that the auto traits are sorted *and* printed via cx).
196 let mut auto_traits: Vec<_> = self.auto_traits().map(|did| {
197 (cx.tcx.def_path_str(did), did)
200 // The auto traits come ordered by `DefPathHash`. While
201 // `DefPathHash` is *stable* in the sense that it depends on
202 // neither the host nor the phase of the moon, it depends
203 // "pseudorandomly" on the compiler version and the target.
205 // To avoid that causing instabilities in compiletest
206 // output, sort the auto-traits alphabetically.
209 for (_, def_id) in auto_traits {
215 nest!(|cx| cx.print_def_path(def_id, None, iter::empty()));
221 impl fmt::Debug for ty::GenericParamDef {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 let type_name = match self.kind {
224 ty::GenericParamDefKind::Lifetime => "Lifetime",
225 ty::GenericParamDefKind::Type { .. } => "Type",
226 ty::GenericParamDefKind::Const => "Const",
228 write!(f, "{}({}, {:?}, {})",
236 impl fmt::Debug for ty::TraitDef {
237 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
239 cx.print_def_path(self.def_id, None, iter::empty())?;
245 impl fmt::Debug for ty::AdtDef {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
248 cx.print_def_path(self.did, None, iter::empty())?;
254 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
256 write!(f, "ClosureUpvar({:?},{:?})",
262 impl fmt::Debug for ty::UpvarId {
263 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
264 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |mut cx| {
265 define_scoped_cx!(cx);
266 p!(write("UpvarId({:?};`{}`;{:?})",
267 self.var_path.hir_id,
268 cx.tcx.hir().name_by_hir_id(self.var_path.hir_id),
269 self.closure_expr_id));
275 impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> {
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 write!(f, "UpvarBorrow({:?}, {:?})",
278 self.kind, self.region)
283 ('tcx) &'tcx ty::List<Ty<'tcx>>, (self, cx) {
286 let mut tys = self.iter();
287 if let Some(&ty) = tys.next() {
290 p!(write(", "), print(ty));
299 ('tcx) ty::TypeAndMut<'tcx>, (self, cx) {
302 write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
309 ('tcx) ty::ExistentialTraitRef<'tcx>, (self, cx) {
311 let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
313 let trait_ref = *ty::Binder::bind(*self)
314 .with_self_ty(cx.tcx, dummy_self)
316 p!(print_display(trait_ref))
319 p!(print_display(self))
325 ('tcx) ty::adjustment::Adjustment<'tcx>, (self, cx) {
327 p!(write("{:?} -> ", self.kind), print(self.target))
332 impl fmt::Debug for ty::BoundRegion {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
335 ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
336 ty::BrFresh(n) => write!(f, "BrFresh({:?})", n),
337 ty::BrNamed(did, name) => {
338 write!(f, "BrNamed({:?}:{:?}, {})",
339 did.krate, did.index, name)
341 ty::BrEnv => write!(f, "BrEnv"),
347 () ty::RegionKind, (self, cx) {
349 return cx.print_region(self);
353 ty::ReEarlyBound(ref data) => {
354 p!(write("ReEarlyBound({}, {})",
359 ty::ReClosureBound(ref vid) => {
360 p!(write("ReClosureBound({:?})", vid))
363 ty::ReLateBound(binder_id, ref bound_region) => {
364 p!(write("ReLateBound({:?}, {:?})", binder_id, bound_region))
367 ty::ReFree(ref fr) => p!(print_debug(fr)),
370 p!(write("ReScope({:?})", id))
373 ty::ReStatic => p!(write("ReStatic")),
375 ty::ReVar(ref vid) => {
376 p!(write("{:?}", vid));
379 ty::RePlaceholder(placeholder) => {
380 p!(write("RePlaceholder({:?})", placeholder))
383 ty::ReEmpty => p!(write("ReEmpty")),
385 ty::ReErased => p!(write("ReErased"))
392 () ty::FreeRegion, (self, cx) {
394 p!(write("ReFree({:?}, {:?})", self.scope, self.bound_region))
400 () ty::Variance, (self, cx) {
402 cx.printer.write_str(match *self {
403 ty::Covariant => "+",
404 ty::Contravariant => "-",
405 ty::Invariant => "o",
406 ty::Bivariant => "*",
413 ('tcx) ty::FnSig<'tcx>, (self, cx) {
415 if self.unsafety == hir::Unsafety::Unsafe {
416 p!(write("unsafe "));
419 if self.abi != Abi::Rust {
420 p!(write("extern {} ", self.abi));
424 nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
427 p!(write("({:?}; c_variadic: {})->{:?}",
428 self.inputs(), self.c_variadic, self.output()))
433 impl fmt::Debug for ty::TyVid {
434 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
435 write!(f, "_#{}t", self.index)
439 impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
440 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
441 write!(f, "_#{}f", self.index)
445 impl fmt::Debug for ty::IntVid {
446 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
447 write!(f, "_#{}i", self.index)
451 impl fmt::Debug for ty::FloatVid {
452 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
453 write!(f, "_#{}f", self.index)
457 impl fmt::Debug for ty::RegionVid {
458 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
459 write!(f, "'_#{}r", self.index())
464 () ty::InferTy, (self, cx) {
466 if cx.tcx.sess.verbose() {
467 return self.print_debug(cx);
470 ty::TyVar(_) => p!(write("_")),
471 ty::IntVar(_) => p!(write("{}", "{integer}")),
472 ty::FloatVar(_) => p!(write("{}", "{float}")),
473 ty::FreshTy(v) => p!(write("FreshTy({})", v)),
474 ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
475 ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
480 ty::TyVar(ref v) => p!(write("{:?}", v)),
481 ty::IntVar(ref v) => p!(write("{:?}", v)),
482 ty::FloatVar(ref v) => p!(write("{:?}", v)),
483 ty::FreshTy(v) => p!(write("FreshTy({:?})", v)),
484 ty::FreshIntTy(v) => p!(write("FreshIntTy({:?})", v)),
485 ty::FreshFloatTy(v) => p!(write("FreshFloatTy({:?})", v))
491 impl fmt::Debug for ty::IntVarValue {
492 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
494 ty::IntType(ref v) => v.fmt(f),
495 ty::UintType(ref v) => v.fmt(f),
500 impl fmt::Debug for ty::FloatVarValue {
501 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
506 // The generic impl doesn't work yet because projections are not
507 // normalized under HRTB.
508 /*impl<T> fmt::Display for ty::Binder<T>
509 where T: fmt::Display + for<'a> ty::Lift<'a>,
510 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
512 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
513 PrintCx::with_tls_tcx(|cx| cx.pretty_in_binder(cx.tcx.lift(self)
514 .expect("could not lift for printing")))
518 define_print_multi! {
520 ('tcx) ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
521 ('tcx) ty::Binder<ty::TraitRef<'tcx>>,
522 ('tcx) ty::Binder<ty::FnSig<'tcx>>,
523 ('tcx) ty::Binder<ty::TraitPredicate<'tcx>>,
524 ('tcx) ty::Binder<ty::SubtypePredicate<'tcx>>,
525 ('tcx) ty::Binder<ty::ProjectionPredicate<'tcx>>,
526 ('tcx) ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
527 ('tcx) ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>
531 nest!(|cx| cx.pretty_in_binder(self))
537 ('tcx) ty::TraitRef<'tcx>, (self, cx) {
539 nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty()));
542 nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self)));
548 ('tcx) Ty<'tcx>, (self, cx) {
550 return cx.print_type(self);
553 p!(print_display(self))
559 ('tcx) ConstValue<'tcx>, (self, cx) {
562 ConstValue::Infer(..) => p!(write("_")),
563 ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
564 _ => p!(write("{:?}", self)),
571 ('tcx) ty::Const<'tcx>, (self, cx) {
573 p!(write("{} : {}", self.val, self.ty))
579 ('tcx) ty::LazyConst<'tcx>, (self, cx) {
582 // FIXME(const_generics) this should print at least the type.
583 ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
584 ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
591 () ty::ParamTy, (self, cx) {
593 p!(write("{}", self.name))
596 p!(write("{}/#{}", self.name, self.idx))
602 () ty::ParamConst, (self, cx) {
604 p!(write("{}", self.name))
607 p!(write("{}/#{}", self.name, self.index))
612 // Similar problem to `Binder<T>`, can't define a generic impl.
613 define_print_multi! {
615 ('tcx) ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
616 ('tcx) ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
620 p!(print(self.0), write(" : "), print(self.1))
626 ('tcx) ty::SubtypePredicate<'tcx>, (self, cx) {
628 p!(print(self.a), write(" <: "), print(self.b))
634 ('tcx) ty::TraitPredicate<'tcx>, (self, cx) {
636 p!(write("TraitPredicate({:?})",
640 p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
646 ('tcx) ty::ProjectionPredicate<'tcx>, (self, cx) {
649 write("ProjectionPredicate("),
650 print(self.projection_ty),
656 p!(print(self.projection_ty), write(" == "), print(self.ty))
662 ('tcx) ty::ProjectionTy<'tcx>, (self, cx) {
664 nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty()));
670 () ty::ClosureKind, (self, cx) {
673 ty::ClosureKind::Fn => p!(write("Fn")),
674 ty::ClosureKind::FnMut => p!(write("FnMut")),
675 ty::ClosureKind::FnOnce => p!(write("FnOnce")),
682 ('tcx) ty::Predicate<'tcx>, (self, cx) {
685 ty::Predicate::Trait(ref data) => p!(print(data)),
686 ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
687 ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
688 ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
689 ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
690 ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
691 ty::Predicate::ObjectSafe(trait_def_id) => {
692 p!(write("the trait `"));
693 nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty()));
694 p!(write("` is object-safe"))
696 ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
697 p!(write("the closure `"));
698 nest!(|cx| cx.print_value_path(closure_def_id, None));
699 p!(write("` implements the trait `{}`", kind))
701 ty::Predicate::ConstEvaluatable(def_id, substs) => {
702 p!(write("the constant `"));
703 nest!(|cx| cx.print_value_path(def_id, Some(substs)));
704 p!(write("` can be evaluated"))
710 ty::Predicate::Trait(ref a) => p!(print(a)),
711 ty::Predicate::Subtype(ref pair) => p!(print(pair)),
712 ty::Predicate::RegionOutlives(ref pair) => p!(print(pair)),
713 ty::Predicate::TypeOutlives(ref pair) => p!(print(pair)),
714 ty::Predicate::Projection(ref pair) => p!(print(pair)),
715 ty::Predicate::WellFormed(ty) => p!(print(ty)),
716 ty::Predicate::ObjectSafe(trait_def_id) => {
717 p!(write("ObjectSafe({:?})", trait_def_id))
719 ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
720 p!(write("ClosureKind({:?}, {:?}, {:?})",
721 closure_def_id, closure_substs, kind))
723 ty::Predicate::ConstEvaluatable(def_id, substs) => {
724 p!(write("ConstEvaluatable({:?}, {:?})", def_id, substs))
732 ('tcx) Kind<'tcx>, (self, cx) {
734 match self.unpack() {
735 UnpackedKind::Lifetime(lt) => p!(print(lt)),
736 UnpackedKind::Type(ty) => p!(print(ty)),
737 UnpackedKind::Const(ct) => p!(print(ct)),
741 match self.unpack() {
742 UnpackedKind::Lifetime(lt) => p!(print(lt)),
743 UnpackedKind::Type(ty) => p!(print(ty)),
744 UnpackedKind::Const(ct) => p!(print(ct)),