1 use crate::hir::def::Namespace;
2 use crate::hir::def_id::DefId;
3 use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind};
4 use crate::ty::{Bool, Char, Adt};
5 use crate::ty::{Error, Str, Array, Slice, Float, FnDef, FnPtr};
6 use crate::ty::{Param, Bound, RawPtr, Ref, Never, Tuple};
7 use crate::ty::{Closure, Generator, GeneratorWitness, Foreign, Projection, Opaque};
8 use crate::ty::{Placeholder, UnnormalizedProjection, Dynamic, Int, Uint, Infer};
9 use crate::ty::{self, ParamConst, Ty, TypeFoldable};
10 use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer};
11 use crate::mir::interpret::ConstValue;
13 use std::fmt::{self, Write as _};
17 use rustc_target::spec::abi::Abi;
18 use syntax::ast::CRATE_NODE_ID;
19 use syntax::symbol::{Symbol, InternedString};
22 macro_rules! gen_display_debug_body {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
26 $with(&cx.tcx.lift(self).expect("could not lift for printing"), cx)?;
32 macro_rules! gen_display_debug {
33 ( ($($x:tt)+) $target:ty, display yes ) => {
34 impl<$($x)+> fmt::Display for $target {
35 gen_display_debug_body! { Print::print_display }
38 ( () $target:ty, display yes ) => {
39 impl fmt::Display for $target {
40 gen_display_debug_body! { Print::print_display }
43 ( ($($x:tt)+) $target:ty, debug yes ) => {
44 impl<$($x)+> fmt::Debug for $target {
45 gen_display_debug_body! { Print::print_debug }
48 ( () $target:ty, debug yes ) => {
49 impl fmt::Debug for $target {
50 gen_display_debug_body! { Print::print_debug }
53 ( $generic:tt $target:ty, $t:ident no ) => {};
55 macro_rules! gen_print_impl {
56 ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
57 impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target {
59 type Error = fmt::Error;
60 fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
64 define_scoped_cx!($cx);
66 if $cx.config.is_debug $dbg
73 ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
74 impl<P: PrettyPrinter> Print<'tcx, P> for $target {
76 type Error = fmt::Error;
77 fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
81 define_scoped_cx!($cx);
83 if $cx.config.is_debug $dbg
90 ( $generic:tt $target:ty,
91 $vars:tt $gendisp:ident $disp:block $gendbg:ident $dbg:block ) => {
92 gen_print_impl! { $generic $target, $vars $disp $dbg }
93 gen_display_debug! { $generic $target, display $gendisp }
94 gen_display_debug! { $generic $target, debug $gendbg }
97 macro_rules! define_print {
98 ( $generic:tt $target:ty,
99 $vars:tt { display $disp:block debug $dbg:block } ) => {
100 gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
102 ( $generic:tt $target:ty,
103 $vars:tt { debug $dbg:block display $disp:block } ) => {
104 gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
106 ( $generic:tt $target:ty,
107 $vars:tt { debug $dbg:block } ) => {
108 gen_print_impl! { $generic $target, $vars no {
109 bug!(concat!("display not implemented for ", stringify!($target)));
112 ( $generic:tt $target:ty,
113 ($self:ident, $cx:ident) { display $disp:block } ) => {
114 gen_print_impl! { $generic $target, ($self, $cx) yes $disp no {
115 write!($cx.printer, "{:?}", $self)?
119 macro_rules! define_print_multi {
120 ( [ $($generic:tt $target:ty),* ] $vars:tt $def:tt ) => {
121 $(define_print! { $generic $target, $vars $def })*
126 scoped_cx!() = scoped_cx!().nest($closure)?
129 macro_rules! print_inner {
130 (write ($($data:expr),+)) => {
131 write!(scoped_cx!().printer, $($data),+)?
133 ($kind:ident ($data:expr)) => {
134 nest!(|cx| $data.$kind(cx))
138 ($($kind:ident $data:tt),+) => {
140 $(print_inner!($kind $data));+
144 macro_rules! define_scoped_cx {
146 #[allow(unused_macros)]
147 macro_rules! scoped_cx {
153 impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
159 ) -> Result<P, fmt::Error> {
160 define_scoped_cx!(self);
163 let mut inputs = inputs.iter();
164 if let Some(&ty) = inputs.next() {
165 p!(print_display(ty));
167 p!(write(", "), print_display(ty));
174 if !output.is_unit() {
175 p!(write(" -> "), print_display(output));
181 fn in_binder<T>(mut self, value: &ty::Binder<T>) -> Result<P, fmt::Error>
182 where T: Print<'tcx, P, Output = P, Error = fmt::Error> + TypeFoldable<'tcx>
184 fn name_by_region_index(index: usize) -> InternedString {
186 0 => Symbol::intern("'r"),
187 1 => Symbol::intern("'s"),
188 i => Symbol::intern(&format!("'t{}", i-2)),
192 // Replace any anonymous late-bound regions with named
193 // variants, using gensym'd identifiers, so that we can
194 // clearly differentiate between named and unnamed regions in
195 // the output. We'll probably want to tweak this over time to
196 // decide just how much information to give.
197 if self.config.binder_depth == 0 {
198 self.prepare_late_bound_region_info(value);
201 let mut empty = true;
202 let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
203 write!(cx.printer, "{}", if empty {
211 // NOTE(eddyb) this must be below `start_or_continue`'s definition
212 // as that also has a `define_scoped_cx` and that kind of shadowing
213 // is disallowed (name resolution thinks `scoped_cx!` is ambiguous).
214 define_scoped_cx!(self);
216 let old_region_index = self.config.region_index;
217 let mut region_index = old_region_index;
218 let new_value = self.tcx.replace_late_bound_regions(value, |br| {
219 let _ = start_or_continue(&mut self, "for<", ", ");
221 ty::BrNamed(_, name) => {
222 let _ = write!(self.printer, "{}", name);
229 let name = name_by_region_index(region_index);
231 if !self.is_name_used(&name) {
235 let _ = write!(self.printer, "{}", name);
236 ty::BrNamed(self.tcx.hir().local_def_id(CRATE_NODE_ID), name)
239 self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
241 start_or_continue(&mut self, "", "> ")?;
243 // Push current state to gcx, and restore after writing new_value.
244 self.config.binder_depth += 1;
245 self.config.region_index = region_index;
246 let result = new_value.print_display(PrintCx {
248 printer: self.printer,
251 self.config.region_index = old_region_index;
252 self.config.binder_depth -= 1;
256 fn is_name_used(&self, name: &InternedString) -> bool {
257 match self.config.used_region_names {
258 Some(ref names) => names.contains(name),
264 pub fn parameterized<F: fmt::Write>(
267 substs: SubstsRef<'_>,
270 PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
271 let substs = cx.tcx.lift(&substs).expect("could not lift for printing");
272 cx.print_def_path(did, Some(substs), ns, iter::empty())?;
278 ('tcx) &'tcx ty::List<ty::ExistentialPredicate<'tcx>>, (self, cx) {
280 // Generate the main trait ref, including associated types.
281 let mut first = true;
283 if let Some(principal) = self.principal() {
284 let mut resugared_principal = false;
286 // Special-case `Fn(...) -> ...` and resugar it.
287 let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id);
288 if !cx.config.is_verbose && fn_trait_kind.is_some() {
289 if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
290 let mut projections = self.projection_bounds();
291 if let (Some(proj), None) = (projections.next(), projections.next()) {
292 nest!(|cx| cx.print_def_path(
298 nest!(|cx| cx.fn_sig(args, false, proj.ty));
299 resugared_principal = true;
304 if !resugared_principal {
305 // Use a type that can't appear in defaults of type parameters.
306 let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
307 let principal = principal.with_self_ty(cx.tcx, dummy_self);
308 nest!(|cx| cx.print_def_path(
310 Some(principal.substs),
312 self.projection_bounds(),
319 // FIXME(eddyb) avoid printing twice (needed to ensure
320 // that the auto traits are sorted *and* printed via cx).
321 let mut auto_traits: Vec<_> = self.auto_traits().map(|did| {
322 (cx.tcx.def_path_str(did), did)
325 // The auto traits come ordered by `DefPathHash`. While
326 // `DefPathHash` is *stable* in the sense that it depends on
327 // neither the host nor the phase of the moon, it depends
328 // "pseudorandomly" on the compiler version and the target.
330 // To avoid that causing instabilities in compiletest
331 // output, sort the auto-traits alphabetically.
334 for (_, def_id) in auto_traits {
340 nest!(|cx| cx.print_def_path(
351 impl fmt::Debug for ty::GenericParamDef {
352 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353 let type_name = match self.kind {
354 ty::GenericParamDefKind::Lifetime => "Lifetime",
355 ty::GenericParamDefKind::Type { .. } => "Type",
356 ty::GenericParamDefKind::Const => "Const",
358 write!(f, "{}({}, {:?}, {})",
366 impl fmt::Debug for ty::TraitDef {
367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
368 PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
380 impl fmt::Debug for ty::AdtDef {
381 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382 PrintCx::with_tls_tcx(FmtPrinter::new(f), |cx| {
394 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
395 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
396 write!(f, "ClosureUpvar({:?},{:?})",
402 impl fmt::Debug for ty::UpvarId {
403 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
404 PrintCx::with_tls_tcx(FmtPrinter::new(f), |mut cx| {
405 define_scoped_cx!(cx);
406 p!(write("UpvarId({:?};`{}`;{:?})",
407 self.var_path.hir_id,
408 cx.tcx.hir().name_by_hir_id(self.var_path.hir_id),
409 self.closure_expr_id));
415 impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> {
416 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
417 write!(f, "UpvarBorrow({:?}, {:?})",
418 self.kind, self.region)
423 ('tcx) &'tcx ty::List<Ty<'tcx>>, (self, cx) {
426 let mut tys = self.iter();
427 if let Some(&ty) = tys.next() {
430 p!(write(", "), print(ty));
439 ('tcx) ty::TypeAndMut<'tcx>, (self, cx) {
442 write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
449 ('tcx) ty::ExistentialTraitRef<'tcx>, (self, cx) {
451 let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
453 let trait_ref = *ty::Binder::bind(*self)
454 .with_self_ty(cx.tcx, dummy_self)
456 p!(print_display(trait_ref))
459 p!(print_display(self))
465 ('tcx) ty::adjustment::Adjustment<'tcx>, (self, cx) {
467 p!(write("{:?} -> ", self.kind), print(self.target))
472 impl fmt::Debug for ty::BoundRegion {
473 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
475 ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
476 ty::BrFresh(n) => write!(f, "BrFresh({:?})", n),
477 ty::BrNamed(did, name) => {
478 write!(f, "BrNamed({:?}:{:?}, {})",
479 did.krate, did.index, name)
481 ty::BrEnv => write!(f, "BrEnv"),
487 () ty::RegionKind, (self, cx) {
489 return cx.print_region(self);
493 ty::ReEarlyBound(ref data) => {
494 p!(write("ReEarlyBound({}, {})",
499 ty::ReClosureBound(ref vid) => {
500 p!(write("ReClosureBound({:?})", vid))
503 ty::ReLateBound(binder_id, ref bound_region) => {
504 p!(write("ReLateBound({:?}, {:?})", binder_id, bound_region))
507 ty::ReFree(ref fr) => p!(print_debug(fr)),
510 p!(write("ReScope({:?})", id))
513 ty::ReStatic => p!(write("ReStatic")),
515 ty::ReVar(ref vid) => {
516 p!(write("{:?}", vid));
519 ty::RePlaceholder(placeholder) => {
520 p!(write("RePlaceholder({:?})", placeholder))
523 ty::ReEmpty => p!(write("ReEmpty")),
525 ty::ReErased => p!(write("ReErased"))
532 () ty::FreeRegion, (self, cx) {
534 p!(write("ReFree({:?}, {:?})", self.scope, self.bound_region))
540 () ty::Variance, (self, cx) {
542 cx.printer.write_str(match *self {
543 ty::Covariant => "+",
544 ty::Contravariant => "-",
545 ty::Invariant => "o",
546 ty::Bivariant => "*",
553 ('tcx) ty::FnSig<'tcx>, (self, cx) {
555 if self.unsafety == hir::Unsafety::Unsafe {
556 p!(write("unsafe "));
559 if self.abi != Abi::Rust {
560 p!(write("extern {} ", self.abi));
564 nest!(|cx| cx.fn_sig(self.inputs(), self.c_variadic, self.output()));
567 p!(write("({:?}; c_variadic: {})->{:?}",
568 self.inputs(), self.c_variadic, self.output()))
573 impl fmt::Debug for ty::TyVid {
574 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
575 write!(f, "_#{}t", self.index)
579 impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
580 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
581 write!(f, "_#{}f", self.index)
585 impl fmt::Debug for ty::IntVid {
586 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587 write!(f, "_#{}i", self.index)
591 impl fmt::Debug for ty::FloatVid {
592 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
593 write!(f, "_#{}f", self.index)
597 impl fmt::Debug for ty::RegionVid {
598 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
599 write!(f, "'_#{}r", self.index())
604 () ty::InferTy, (self, cx) {
606 if cx.config.is_verbose {
607 return self.print_debug(cx);
610 ty::TyVar(_) => p!(write("_")),
611 ty::IntVar(_) => p!(write("{}", "{integer}")),
612 ty::FloatVar(_) => p!(write("{}", "{float}")),
613 ty::FreshTy(v) => p!(write("FreshTy({})", v)),
614 ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
615 ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
620 ty::TyVar(ref v) => p!(write("{:?}", v)),
621 ty::IntVar(ref v) => p!(write("{:?}", v)),
622 ty::FloatVar(ref v) => p!(write("{:?}", v)),
623 ty::FreshTy(v) => p!(write("FreshTy({:?})", v)),
624 ty::FreshIntTy(v) => p!(write("FreshIntTy({:?})", v)),
625 ty::FreshFloatTy(v) => p!(write("FreshFloatTy({:?})", v))
631 impl fmt::Debug for ty::IntVarValue {
632 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
634 ty::IntType(ref v) => v.fmt(f),
635 ty::UintType(ref v) => v.fmt(f),
640 impl fmt::Debug for ty::FloatVarValue {
641 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
646 // The generic impl doesn't work yet because projections are not
647 // normalized under HRTB.
648 /*impl<T> fmt::Display for ty::Binder<T>
649 where T: fmt::Display + for<'a> ty::Lift<'a>,
650 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
652 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653 PrintCx::with_tls_tcx(|cx| cx.in_binder(cx.tcx.lift(self)
654 .expect("could not lift for printing")))
658 define_print_multi! {
660 ('tcx) ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
661 ('tcx) ty::Binder<ty::TraitRef<'tcx>>,
662 ('tcx) ty::Binder<ty::FnSig<'tcx>>,
663 ('tcx) ty::Binder<ty::TraitPredicate<'tcx>>,
664 ('tcx) ty::Binder<ty::SubtypePredicate<'tcx>>,
665 ('tcx) ty::Binder<ty::ProjectionPredicate<'tcx>>,
666 ('tcx) ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
667 ('tcx) ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>
671 nest!(|cx| cx.in_binder(self))
677 ('tcx) ty::TraitRef<'tcx>, (self, cx) {
679 nest!(|cx| cx.print_def_path(
687 nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self), Namespace::TypeNS));
693 ('tcx) ty::Ty<'tcx>, (self, cx) {
696 Bool => p!(write("bool")),
697 Char => p!(write("char")),
698 Int(t) => p!(write("{}", t.ty_to_string())),
699 Uint(t) => p!(write("{}", t.ty_to_string())),
700 Float(t) => p!(write("{}", t.ty_to_string())),
702 p!(write("*{} ", match tm.mutbl {
703 hir::MutMutable => "mut",
704 hir::MutImmutable => "const",
708 Ref(r, ty, mutbl) => {
710 if cx.print_region_outputs_anything(r) {
711 p!(print_display(r), write(" "));
713 p!(print(ty::TypeAndMut { ty, mutbl }))
715 Never => p!(write("!")),
718 let mut tys = tys.iter();
719 if let Some(&ty) = tys.next() {
720 p!(print(ty), write(","));
721 if let Some(&ty) = tys.next() {
722 p!(write(" "), print(ty));
724 p!(write(", "), print(ty));
730 FnDef(def_id, substs) => {
731 let sig = cx.tcx.fn_sig(def_id).subst(cx.tcx, substs);
732 p!(print(sig), write(" {{"));
733 nest!(|cx| cx.print_def_path(
741 FnPtr(ref bare_fn) => {
744 Infer(infer_ty) => p!(write("{}", infer_ty)),
745 Error => p!(write("[type error]")),
746 Param(ref param_ty) => p!(write("{}", param_ty)),
747 Bound(debruijn, bound_ty) => {
748 match bound_ty.kind {
749 ty::BoundTyKind::Anon => {
750 if debruijn == ty::INNERMOST {
751 p!(write("^{}", bound_ty.var.index()))
753 p!(write("^{}_{}", debruijn.index(), bound_ty.var.index()))
757 ty::BoundTyKind::Param(p) => p!(write("{}", p)),
760 Adt(def, substs) => {
761 nest!(|cx| cx.print_def_path(
768 Dynamic(data, r) => {
769 let print_r = cx.print_region_outputs_anything(r);
773 p!(write("dyn "), print(data));
775 p!(write(" + "), print_display(r), write(")"));
779 nest!(|cx| cx.print_def_path(
786 Projection(ref data) => p!(print(data)),
787 UnnormalizedProjection(ref data) => {
788 p!(write("Unnormalized("), print(data), write(")"))
790 Placeholder(placeholder) => {
791 p!(write("Placeholder({:?})", placeholder))
793 Opaque(def_id, substs) => {
794 if cx.config.is_verbose {
795 p!(write("Opaque({:?}, {:?})", def_id, substs));
796 return Ok(cx.printer);
799 let def_key = cx.tcx.def_key(def_id);
800 if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
801 p!(write("{}", name));
802 let mut substs = substs.iter();
803 // FIXME(eddyb) print this with `print_def_path`.
804 if let Some(first) = substs.next() {
806 p!(print_display(first));
807 for subst in substs {
808 p!(write(", "), print_display(subst));
812 return Ok(cx.printer);
814 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
815 // by looking up the projections associated with the def_id.
816 let bounds = cx.tcx.predicates_of(def_id).instantiate(cx.tcx, substs);
818 let mut first = true;
819 let mut is_sized = false;
821 for predicate in bounds.predicates {
822 if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
823 // Don't print +Sized, but rather +?Sized if absent.
824 if Some(trait_ref.def_id()) == cx.tcx.lang_items().sized_trait() {
830 write("{}", if first { " " } else { "+" }),
836 p!(write("{}?Sized", if first { " " } else { "+" }));
841 Str => p!(write("str")),
842 Generator(did, substs, movability) => {
843 let upvar_tys = substs.upvar_tys(did, cx.tcx);
844 let witness = substs.witness(did, cx.tcx);
845 if movability == hir::GeneratorMovability::Movable {
846 p!(write("[generator"));
848 p!(write("[static generator"));
851 // FIXME(eddyb) should use `def_span`.
852 if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) {
853 p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)));
855 for (freevar, upvar_ty) in cx.tcx.freevars(did)
857 .map_or(&[][..], |fv| &fv[..])
864 cx.tcx.hir().name(freevar.var_id())),
869 // cross-crate closure types should only be
870 // visible in codegen bug reports, I imagine.
871 p!(write("@{:?}", did));
873 for (index, upvar_ty) in upvar_tys.enumerate() {
875 write("{}{}:", sep, index),
881 p!(write(" "), print(witness), write("]"))
883 GeneratorWitness(types) => {
884 nest!(|cx| cx.in_binder(&types))
886 Closure(did, substs) => {
887 let upvar_tys = substs.upvar_tys(did, cx.tcx);
888 p!(write("[closure"));
890 // FIXME(eddyb) should use `def_span`.
891 if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) {
892 if cx.tcx.sess.opts.debugging_opts.span_free_formats {
893 p!(write("@{:?}", hir_id));
895 p!(write("@{:?}", cx.tcx.hir().span_by_hir_id(hir_id)));
898 for (freevar, upvar_ty) in cx.tcx.freevars(did)
900 .map_or(&[][..], |fv| &fv[..])
907 cx.tcx.hir().name(freevar.var_id())),
912 // cross-crate closure types should only be
913 // visible in codegen bug reports, I imagine.
914 p!(write("@{:?}", did));
916 for (index, upvar_ty) in upvar_tys.enumerate() {
918 write("{}{}:", sep, index),
924 if cx.config.is_verbose {
926 " closure_kind_ty={:?} closure_sig_ty={:?}",
927 substs.closure_kind_ty(did, cx.tcx),
928 substs.closure_sig_ty(did, cx.tcx)
935 p!(write("["), print(ty), write("; "));
937 ty::LazyConst::Unevaluated(_def_id, _substs) => {
940 ty::LazyConst::Evaluated(c) => {
942 ConstValue::Infer(..) => p!(write("_")),
943 ConstValue::Param(ParamConst { name, .. }) =>
944 p!(write("{}", name)),
945 _ => p!(write("{}", c.unwrap_usize(cx.tcx))),
952 p!(write("["), print(ty), write("]"))
957 p!(print_display(self))
963 ('tcx) ConstValue<'tcx>, (self, cx) {
966 ConstValue::Infer(..) => p!(write("_")),
967 ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
968 _ => p!(write("{:?}", self)),
975 ('tcx) ty::Const<'tcx>, (self, cx) {
977 p!(write("{} : {}", self.val, self.ty))
983 ('tcx) ty::LazyConst<'tcx>, (self, cx) {
986 // FIXME(const_generics) this should print at least the type.
987 ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
988 ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
995 () ty::ParamTy, (self, cx) {
997 p!(write("{}", self.name))
1000 p!(write("{}/#{}", self.name, self.idx))
1006 () ty::ParamConst, (self, cx) {
1008 p!(write("{}", self.name))
1011 p!(write("{}/#{}", self.name, self.index))
1016 // Similar problem to `Binder<T>`, can't define a generic impl.
1017 define_print_multi! {
1019 ('tcx) ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
1020 ('tcx) ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
1024 p!(print(self.0), write(" : "), print(self.1))
1030 ('tcx) ty::SubtypePredicate<'tcx>, (self, cx) {
1032 p!(print(self.a), write(" <: "), print(self.b))
1038 ('tcx) ty::TraitPredicate<'tcx>, (self, cx) {
1040 p!(write("TraitPredicate({:?})",
1044 p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
1050 ('tcx) ty::ProjectionPredicate<'tcx>, (self, cx) {
1053 write("ProjectionPredicate("),
1054 print(self.projection_ty),
1060 p!(print(self.projection_ty), write(" == "), print(self.ty))
1066 ('tcx) ty::ProjectionTy<'tcx>, (self, cx) {
1068 nest!(|cx| cx.print_def_path(
1079 () ty::ClosureKind, (self, cx) {
1082 ty::ClosureKind::Fn => p!(write("Fn")),
1083 ty::ClosureKind::FnMut => p!(write("FnMut")),
1084 ty::ClosureKind::FnOnce => p!(write("FnOnce")),
1091 ('tcx) ty::Predicate<'tcx>, (self, cx) {
1094 ty::Predicate::Trait(ref data) => p!(print(data)),
1095 ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
1096 ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
1097 ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
1098 ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
1099 ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
1100 ty::Predicate::ObjectSafe(trait_def_id) => {
1101 p!(write("the trait `"));
1102 nest!(|cx| cx.print_def_path(
1108 p!(write("` is object-safe"))
1110 ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
1111 p!(write("the closure `"));
1112 nest!(|cx| cx.print_def_path(
1118 p!(write("` implements the trait `{}`", kind))
1120 ty::Predicate::ConstEvaluatable(def_id, substs) => {
1121 p!(write("the constant `"));
1122 nest!(|cx| cx.print_def_path(
1128 p!(write("` can be evaluated"))
1134 ty::Predicate::Trait(ref a) => p!(print(a)),
1135 ty::Predicate::Subtype(ref pair) => p!(print(pair)),
1136 ty::Predicate::RegionOutlives(ref pair) => p!(print(pair)),
1137 ty::Predicate::TypeOutlives(ref pair) => p!(print(pair)),
1138 ty::Predicate::Projection(ref pair) => p!(print(pair)),
1139 ty::Predicate::WellFormed(ty) => p!(print(ty)),
1140 ty::Predicate::ObjectSafe(trait_def_id) => {
1141 p!(write("ObjectSafe({:?})", trait_def_id))
1143 ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
1144 p!(write("ClosureKind({:?}, {:?}, {:?})",
1145 closure_def_id, closure_substs, kind))
1147 ty::Predicate::ConstEvaluatable(def_id, substs) => {
1148 p!(write("ConstEvaluatable({:?}, {:?})", def_id, substs))
1156 ('tcx) Kind<'tcx>, (self, cx) {
1158 match self.unpack() {
1159 UnpackedKind::Lifetime(lt) => p!(print(lt)),
1160 UnpackedKind::Type(ty) => p!(print(ty)),
1161 UnpackedKind::Const(ct) => p!(print(ct)),
1165 match self.unpack() {
1166 UnpackedKind::Lifetime(lt) => p!(print(lt)),
1167 UnpackedKind::Type(ty) => p!(print(ty)),
1168 UnpackedKind::Const(ct) => p!(print(ct)),