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::{self, ParamConst, Ty, TypeFoldable};
5 use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print, Printer};
6 use crate::mir::interpret::ConstValue;
8 use std::fmt::{self, Write as _};
12 use rustc_target::spec::abi::Abi;
13 use syntax::ast::CRATE_NODE_ID;
14 use syntax::symbol::{Symbol, InternedString};
17 macro_rules! gen_display_debug_body {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
21 $with(&cx.tcx.lift(self).expect("could not lift for printing"), cx)?;
27 macro_rules! gen_display_debug {
28 ( ($($x:tt)+) $target:ty, display yes ) => {
29 impl<$($x)+> fmt::Display for $target {
30 gen_display_debug_body! { Print::print_display }
33 ( () $target:ty, display yes ) => {
34 impl fmt::Display for $target {
35 gen_display_debug_body! { Print::print_display }
38 ( ($($x:tt)+) $target:ty, debug yes ) => {
39 impl<$($x)+> fmt::Debug for $target {
40 gen_display_debug_body! { Print::print_debug }
43 ( () $target:ty, debug yes ) => {
44 impl fmt::Debug for $target {
45 gen_display_debug_body! { Print::print_debug }
48 ( $generic:tt $target:ty, $t:ident no ) => {};
50 macro_rules! gen_print_impl {
51 ( ($($x:tt)+) $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
52 impl<$($x)+, P: PrettyPrinter> Print<'tcx, P> for $target {
54 type Error = fmt::Error;
55 fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
59 define_scoped_cx!($cx);
61 if $cx.config.is_debug $dbg
68 ( () $target:ty, ($self:ident, $cx:ident) $disp:block $dbg:block ) => {
69 impl<P: PrettyPrinter> Print<'tcx, P> for $target {
71 type Error = fmt::Error;
72 fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
76 define_scoped_cx!($cx);
78 if $cx.config.is_debug $dbg
85 ( $generic:tt $target:ty,
86 $vars:tt $gendisp:ident $disp:block $gendbg:ident $dbg:block ) => {
87 gen_print_impl! { $generic $target, $vars $disp $dbg }
88 gen_display_debug! { $generic $target, display $gendisp }
89 gen_display_debug! { $generic $target, debug $gendbg }
92 macro_rules! define_print {
93 ( $generic:tt $target:ty,
94 $vars:tt { display $disp:block debug $dbg:block } ) => {
95 gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
97 ( $generic:tt $target:ty,
98 $vars:tt { debug $dbg:block display $disp:block } ) => {
99 gen_print_impl! { $generic $target, $vars yes $disp yes $dbg }
101 ( $generic:tt $target:ty,
102 $vars:tt { debug $dbg:block } ) => {
103 gen_print_impl! { $generic $target, $vars no {
104 bug!(concat!("display not implemented for ", stringify!($target)));
107 ( $generic:tt $target:ty,
108 ($self:ident, $cx:ident) { display $disp:block } ) => {
109 gen_print_impl! { $generic $target, ($self, $cx) yes $disp no {
110 write!($cx.printer, "{:?}", $self)?
114 macro_rules! define_print_multi {
115 ( [ $($generic:tt $target:ty),* ] $vars:tt $def:tt ) => {
116 $(define_print! { $generic $target, $vars $def })*
121 scoped_cx!() = scoped_cx!().nest($closure)?
124 macro_rules! print_inner {
125 (write ($($data:expr),+)) => {
126 write!(scoped_cx!().printer, $($data),+)?
128 ($kind:ident ($data:expr)) => {
129 nest!(|cx| $data.$kind(cx))
133 ($($kind:ident $data:tt),+) => {
135 $(print_inner!($kind $data));+
139 macro_rules! define_scoped_cx {
141 #[allow(unused_macros)]
142 macro_rules! scoped_cx {
148 impl<P: PrettyPrinter> PrintCx<'a, 'gcx, 'tcx, P> {
154 ) -> Result<P, fmt::Error> {
155 define_scoped_cx!(self);
158 let mut inputs = inputs.iter();
159 if let Some(&ty) = inputs.next() {
160 p!(print_display(ty));
162 p!(write(", "), print_display(ty));
169 if !output.is_unit() {
170 p!(write(" -> "), print_display(output));
176 fn in_binder<T>(mut self, value: &ty::Binder<T>) -> Result<P, fmt::Error>
177 where T: Print<'tcx, P, Output = P, Error = fmt::Error> + TypeFoldable<'tcx>
179 fn name_by_region_index(index: usize) -> InternedString {
181 0 => Symbol::intern("'r"),
182 1 => Symbol::intern("'s"),
183 i => Symbol::intern(&format!("'t{}", i-2)),
187 // Replace any anonymous late-bound regions with named
188 // variants, using gensym'd identifiers, so that we can
189 // clearly differentiate between named and unnamed regions in
190 // the output. We'll probably want to tweak this over time to
191 // decide just how much information to give.
192 if self.config.binder_depth == 0 {
193 self.prepare_late_bound_region_info(value);
196 let mut empty = true;
197 let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
198 write!(cx.printer, "{}", if empty {
206 // NOTE(eddyb) this must be below `start_or_continue`'s definition
207 // as that also has a `define_scoped_cx` and that kind of shadowing
208 // is disallowed (name resolution thinks `scoped_cx!` is ambiguous).
209 define_scoped_cx!(self);
211 let old_region_index = self.config.region_index;
212 let mut region_index = old_region_index;
213 let new_value = self.tcx.replace_late_bound_regions(value, |br| {
214 let _ = start_or_continue(&mut self, "for<", ", ");
216 ty::BrNamed(_, name) => {
217 let _ = write!(self.printer, "{}", name);
224 let name = name_by_region_index(region_index);
226 if !self.is_name_used(&name) {
230 let _ = write!(self.printer, "{}", name);
231 ty::BrNamed(self.tcx.hir().local_def_id(CRATE_NODE_ID), name)
234 self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
236 start_or_continue(&mut self, "", "> ")?;
238 // Push current state to gcx, and restore after writing new_value.
239 self.config.binder_depth += 1;
240 self.config.region_index = region_index;
241 let result = new_value.print_display(PrintCx {
243 printer: self.printer,
246 self.config.region_index = old_region_index;
247 self.config.binder_depth -= 1;
251 fn is_name_used(&self, name: &InternedString) -> bool {
252 match self.config.used_region_names {
253 Some(ref names) => names.contains(name),
259 pub fn parameterized<F: fmt::Write>(
262 substs: SubstsRef<'_>,
265 PrintCx::with_tls_tcx(FmtPrinter::new(f, ns), |cx| {
266 let substs = cx.tcx.lift(&substs).expect("could not lift for printing");
267 cx.print_def_path(did, Some(substs), iter::empty())?;
273 ('tcx) &'tcx ty::List<ty::ExistentialPredicate<'tcx>>, (self, cx) {
275 // Generate the main trait ref, including associated types.
276 let mut first = true;
278 if let Some(principal) = self.principal() {
279 let mut resugared_principal = false;
281 // Special-case `Fn(...) -> ...` and resugar it.
282 let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id);
283 if !cx.config.is_verbose && fn_trait_kind.is_some() {
284 if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
285 let mut projections = self.projection_bounds();
286 if let (Some(proj), None) = (projections.next(), projections.next()) {
287 nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty()));
288 nest!(|cx| cx.fn_sig(args, false, proj.ty));
289 resugared_principal = true;
294 if !resugared_principal {
295 // Use a type that can't appear in defaults of type parameters.
296 let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
297 let principal = principal.with_self_ty(cx.tcx, dummy_self);
298 nest!(|cx| cx.print_def_path(
300 Some(principal.substs),
301 self.projection_bounds(),
308 // FIXME(eddyb) avoid printing twice (needed to ensure
309 // that the auto traits are sorted *and* printed via cx).
310 let mut auto_traits: Vec<_> = self.auto_traits().map(|did| {
311 (cx.tcx.def_path_str(did), did)
314 // The auto traits come ordered by `DefPathHash`. While
315 // `DefPathHash` is *stable* in the sense that it depends on
316 // neither the host nor the phase of the moon, it depends
317 // "pseudorandomly" on the compiler version and the target.
319 // To avoid that causing instabilities in compiletest
320 // output, sort the auto-traits alphabetically.
323 for (_, def_id) in auto_traits {
329 nest!(|cx| cx.print_def_path(def_id, None, iter::empty()));
335 impl fmt::Debug for ty::GenericParamDef {
336 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
337 let type_name = match self.kind {
338 ty::GenericParamDefKind::Lifetime => "Lifetime",
339 ty::GenericParamDefKind::Type { .. } => "Type",
340 ty::GenericParamDefKind::Const => "Const",
342 write!(f, "{}({}, {:?}, {})",
350 impl fmt::Debug for ty::TraitDef {
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
353 cx.print_def_path(self.def_id, None, iter::empty())?;
359 impl fmt::Debug for ty::AdtDef {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::TypeNS), |cx| {
362 cx.print_def_path(self.did, None, iter::empty())?;
368 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
369 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370 write!(f, "ClosureUpvar({:?},{:?})",
376 impl fmt::Debug for ty::UpvarId {
377 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378 PrintCx::with_tls_tcx(FmtPrinter::new(f, Namespace::ValueNS), |mut cx| {
379 define_scoped_cx!(cx);
380 p!(write("UpvarId({:?};`{}`;{:?})",
381 self.var_path.hir_id,
382 cx.tcx.hir().name_by_hir_id(self.var_path.hir_id),
383 self.closure_expr_id));
389 impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> {
390 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391 write!(f, "UpvarBorrow({:?}, {:?})",
392 self.kind, self.region)
397 ('tcx) &'tcx ty::List<Ty<'tcx>>, (self, cx) {
400 let mut tys = self.iter();
401 if let Some(&ty) = tys.next() {
404 p!(write(", "), print(ty));
413 ('tcx) ty::TypeAndMut<'tcx>, (self, cx) {
416 write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
423 ('tcx) ty::ExistentialTraitRef<'tcx>, (self, cx) {
425 let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
427 let trait_ref = *ty::Binder::bind(*self)
428 .with_self_ty(cx.tcx, dummy_self)
430 p!(print_display(trait_ref))
433 p!(print_display(self))
439 ('tcx) ty::adjustment::Adjustment<'tcx>, (self, cx) {
441 p!(write("{:?} -> ", self.kind), print(self.target))
446 impl fmt::Debug for ty::BoundRegion {
447 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
449 ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
450 ty::BrFresh(n) => write!(f, "BrFresh({:?})", n),
451 ty::BrNamed(did, name) => {
452 write!(f, "BrNamed({:?}:{:?}, {})",
453 did.krate, did.index, name)
455 ty::BrEnv => write!(f, "BrEnv"),
461 () ty::RegionKind, (self, cx) {
463 return cx.print_region(self);
467 ty::ReEarlyBound(ref data) => {
468 p!(write("ReEarlyBound({}, {})",
473 ty::ReClosureBound(ref vid) => {
474 p!(write("ReClosureBound({:?})", vid))
477 ty::ReLateBound(binder_id, ref bound_region) => {
478 p!(write("ReLateBound({:?}, {:?})", binder_id, bound_region))
481 ty::ReFree(ref fr) => p!(print_debug(fr)),
484 p!(write("ReScope({:?})", id))
487 ty::ReStatic => p!(write("ReStatic")),
489 ty::ReVar(ref vid) => {
490 p!(write("{:?}", vid));
493 ty::RePlaceholder(placeholder) => {
494 p!(write("RePlaceholder({:?})", placeholder))
497 ty::ReEmpty => p!(write("ReEmpty")),
499 ty::ReErased => p!(write("ReErased"))
506 () ty::FreeRegion, (self, cx) {
508 p!(write("ReFree({:?}, {:?})", self.scope, self.bound_region))
514 () ty::Variance, (self, cx) {
516 cx.printer.write_str(match *self {
517 ty::Covariant => "+",
518 ty::Contravariant => "-",
519 ty::Invariant => "o",
520 ty::Bivariant => "*",
527 ('tcx) ty::FnSig<'tcx>, (self, cx) {
529 if self.unsafety == hir::Unsafety::Unsafe {
530 p!(write("unsafe "));
533 if self.abi != Abi::Rust {
534 p!(write("extern {} ", self.abi));
538 nest!(|cx| cx.fn_sig(self.inputs(), self.c_variadic, self.output()));
541 p!(write("({:?}; c_variadic: {})->{:?}",
542 self.inputs(), self.c_variadic, self.output()))
547 impl fmt::Debug for ty::TyVid {
548 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
549 write!(f, "_#{}t", self.index)
553 impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> {
554 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
555 write!(f, "_#{}f", self.index)
559 impl fmt::Debug for ty::IntVid {
560 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
561 write!(f, "_#{}i", self.index)
565 impl fmt::Debug for ty::FloatVid {
566 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
567 write!(f, "_#{}f", self.index)
571 impl fmt::Debug for ty::RegionVid {
572 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
573 write!(f, "'_#{}r", self.index())
578 () ty::InferTy, (self, cx) {
580 if cx.config.is_verbose {
581 return self.print_debug(cx);
584 ty::TyVar(_) => p!(write("_")),
585 ty::IntVar(_) => p!(write("{}", "{integer}")),
586 ty::FloatVar(_) => p!(write("{}", "{float}")),
587 ty::FreshTy(v) => p!(write("FreshTy({})", v)),
588 ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
589 ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
594 ty::TyVar(ref v) => p!(write("{:?}", v)),
595 ty::IntVar(ref v) => p!(write("{:?}", v)),
596 ty::FloatVar(ref v) => p!(write("{:?}", v)),
597 ty::FreshTy(v) => p!(write("FreshTy({:?})", v)),
598 ty::FreshIntTy(v) => p!(write("FreshIntTy({:?})", v)),
599 ty::FreshFloatTy(v) => p!(write("FreshFloatTy({:?})", v))
605 impl fmt::Debug for ty::IntVarValue {
606 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
608 ty::IntType(ref v) => v.fmt(f),
609 ty::UintType(ref v) => v.fmt(f),
614 impl fmt::Debug for ty::FloatVarValue {
615 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
620 // The generic impl doesn't work yet because projections are not
621 // normalized under HRTB.
622 /*impl<T> fmt::Display for ty::Binder<T>
623 where T: fmt::Display + for<'a> ty::Lift<'a>,
624 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
626 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
627 PrintCx::with_tls_tcx(|cx| cx.in_binder(cx.tcx.lift(self)
628 .expect("could not lift for printing")))
632 define_print_multi! {
634 ('tcx) ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
635 ('tcx) ty::Binder<ty::TraitRef<'tcx>>,
636 ('tcx) ty::Binder<ty::FnSig<'tcx>>,
637 ('tcx) ty::Binder<ty::TraitPredicate<'tcx>>,
638 ('tcx) ty::Binder<ty::SubtypePredicate<'tcx>>,
639 ('tcx) ty::Binder<ty::ProjectionPredicate<'tcx>>,
640 ('tcx) ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
641 ('tcx) ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>
645 nest!(|cx| cx.in_binder(self))
651 ('tcx) ty::TraitRef<'tcx>, (self, cx) {
653 nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty()));
656 nest!(|cx| cx.path_qualified(self.self_ty(), Some(*self)));
661 // FIXME(eddyb) move this to `ty::print`.
662 impl<'gcx, 'tcx, P: PrettyPrinter> PrintCx<'_, 'gcx, 'tcx, P> {
663 pub fn pretty_print_type(
666 ) -> Result<P::Type, P::Error> {
667 define_scoped_cx!(self);
670 ty::Bool => p!(write("bool")),
671 ty::Char => p!(write("char")),
672 ty::Int(t) => p!(write("{}", t.ty_to_string())),
673 ty::Uint(t) => p!(write("{}", t.ty_to_string())),
674 ty::Float(t) => p!(write("{}", t.ty_to_string())),
675 ty::RawPtr(ref tm) => {
676 p!(write("*{} ", match tm.mutbl {
677 hir::MutMutable => "mut",
678 hir::MutImmutable => "const",
682 ty::Ref(r, ty, mutbl) => {
684 if self.print_region_outputs_anything(r) {
685 p!(print_display(r), write(" "));
687 p!(print(ty::TypeAndMut { ty, mutbl }))
689 ty::Never => p!(write("!")),
690 ty::Tuple(ref tys) => {
692 let mut tys = tys.iter();
693 if let Some(&ty) = tys.next() {
694 p!(print(ty), write(","));
695 if let Some(&ty) = tys.next() {
696 p!(write(" "), print(ty));
698 p!(write(", "), print(ty));
704 ty::FnDef(def_id, substs) => {
705 let sig = self.tcx.fn_sig(def_id).subst(self.tcx, substs);
706 p!(print(sig), write(" {{"));
707 nest!(|cx| cx.print_value_path(def_id, Some(substs)));
710 ty::FnPtr(ref bare_fn) => {
713 ty::Infer(infer_ty) => p!(write("{}", infer_ty)),
714 ty::Error => p!(write("[type error]")),
715 ty::Param(ref param_ty) => p!(write("{}", param_ty)),
716 ty::Bound(debruijn, bound_ty) => {
717 match bound_ty.kind {
718 ty::BoundTyKind::Anon => {
719 if debruijn == ty::INNERMOST {
720 p!(write("^{}", bound_ty.var.index()))
722 p!(write("^{}_{}", debruijn.index(), bound_ty.var.index()))
726 ty::BoundTyKind::Param(p) => p!(write("{}", p)),
729 ty::Adt(def, substs) => {
730 nest!(|cx| cx.print_def_path(def.did, Some(substs), iter::empty()));
732 ty::Dynamic(data, r) => {
733 let print_r = self.print_region_outputs_anything(r);
737 p!(write("dyn "), print(data));
739 p!(write(" + "), print_display(r), write(")"));
742 ty::Foreign(def_id) => {
743 nest!(|cx| cx.print_def_path(def_id, None, iter::empty()));
745 ty::Projection(ref data) => p!(print(data)),
746 ty::UnnormalizedProjection(ref data) => {
747 p!(write("Unnormalized("), print(data), write(")"))
749 ty::Placeholder(placeholder) => {
750 p!(write("Placeholder({:?})", placeholder))
752 ty::Opaque(def_id, substs) => {
753 if self.config.is_verbose {
754 p!(write("Opaque({:?}, {:?})", def_id, substs));
755 return Ok(self.printer);
758 let def_key = self.tcx.def_key(def_id);
759 if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
760 p!(write("{}", name));
761 let mut substs = substs.iter();
762 // FIXME(eddyb) print this with `print_def_path`.
763 if let Some(first) = substs.next() {
765 p!(print_display(first));
766 for subst in substs {
767 p!(write(", "), print_display(subst));
771 return Ok(self.printer);
773 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
774 // by looking up the projections associated with the def_id.
775 let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
777 let mut first = true;
778 let mut is_sized = false;
780 for predicate in bounds.predicates {
781 if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
782 // Don't print +Sized, but rather +?Sized if absent.
783 if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
789 write("{}", if first { " " } else { "+" }),
795 p!(write("{}?Sized", if first { " " } else { "+" }));
800 ty::Str => p!(write("str")),
801 ty::Generator(did, substs, movability) => {
802 let upvar_tys = substs.upvar_tys(did, self.tcx);
803 let witness = substs.witness(did, self.tcx);
804 if movability == hir::GeneratorMovability::Movable {
805 p!(write("[generator"));
807 p!(write("[static generator"));
810 // FIXME(eddyb) should use `def_span`.
811 if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) {
812 p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id)));
814 for (freevar, upvar_ty) in self.tcx.freevars(did)
816 .map_or(&[][..], |fv| &fv[..])
823 self.tcx.hir().name(freevar.var_id())),
828 // cross-crate closure types should only be
829 // visible in codegen bug reports, I imagine.
830 p!(write("@{:?}", did));
832 for (index, upvar_ty) in upvar_tys.enumerate() {
834 write("{}{}:", sep, index),
840 p!(write(" "), print(witness), write("]"))
842 ty::GeneratorWitness(types) => {
843 nest!(|cx| cx.in_binder(&types))
845 ty::Closure(did, substs) => {
846 let upvar_tys = substs.upvar_tys(did, self.tcx);
847 p!(write("[closure"));
849 // FIXME(eddyb) should use `def_span`.
850 if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) {
851 if self.tcx.sess.opts.debugging_opts.span_free_formats {
852 p!(write("@{:?}", hir_id));
854 p!(write("@{:?}", self.tcx.hir().span_by_hir_id(hir_id)));
857 for (freevar, upvar_ty) in self.tcx.freevars(did)
859 .map_or(&[][..], |fv| &fv[..])
866 self.tcx.hir().name(freevar.var_id())),
871 // cross-crate closure types should only be
872 // visible in codegen bug reports, I imagine.
873 p!(write("@{:?}", did));
875 for (index, upvar_ty) in upvar_tys.enumerate() {
877 write("{}{}:", sep, index),
883 if self.config.is_verbose {
885 " closure_kind_ty={:?} closure_sig_ty={:?}",
886 substs.closure_kind_ty(did, self.tcx),
887 substs.closure_sig_ty(did, self.tcx)
893 ty::Array(ty, sz) => {
894 p!(write("["), print(ty), write("; "));
896 ty::LazyConst::Unevaluated(_def_id, _substs) => {
899 ty::LazyConst::Evaluated(c) => {
901 ConstValue::Infer(..) => p!(write("_")),
902 ConstValue::Param(ParamConst { name, .. }) =>
903 p!(write("{}", name)),
904 _ => p!(write("{}", c.unwrap_usize(self.tcx))),
911 p!(write("["), print(ty), write("]"))
920 ('tcx) Ty<'tcx>, (self, cx) {
922 return cx.print_type(self);
925 p!(print_display(self))
931 ('tcx) ConstValue<'tcx>, (self, cx) {
934 ConstValue::Infer(..) => p!(write("_")),
935 ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
936 _ => p!(write("{:?}", self)),
943 ('tcx) ty::Const<'tcx>, (self, cx) {
945 p!(write("{} : {}", self.val, self.ty))
951 ('tcx) ty::LazyConst<'tcx>, (self, cx) {
954 // FIXME(const_generics) this should print at least the type.
955 ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
956 ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
963 () ty::ParamTy, (self, cx) {
965 p!(write("{}", self.name))
968 p!(write("{}/#{}", self.name, self.idx))
974 () ty::ParamConst, (self, cx) {
976 p!(write("{}", self.name))
979 p!(write("{}/#{}", self.name, self.index))
984 // Similar problem to `Binder<T>`, can't define a generic impl.
985 define_print_multi! {
987 ('tcx) ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
988 ('tcx) ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
992 p!(print(self.0), write(" : "), print(self.1))
998 ('tcx) ty::SubtypePredicate<'tcx>, (self, cx) {
1000 p!(print(self.a), write(" <: "), print(self.b))
1006 ('tcx) ty::TraitPredicate<'tcx>, (self, cx) {
1008 p!(write("TraitPredicate({:?})",
1012 p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
1018 ('tcx) ty::ProjectionPredicate<'tcx>, (self, cx) {
1021 write("ProjectionPredicate("),
1022 print(self.projection_ty),
1028 p!(print(self.projection_ty), write(" == "), print(self.ty))
1034 ('tcx) ty::ProjectionTy<'tcx>, (self, cx) {
1036 nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty()));
1042 () ty::ClosureKind, (self, cx) {
1045 ty::ClosureKind::Fn => p!(write("Fn")),
1046 ty::ClosureKind::FnMut => p!(write("FnMut")),
1047 ty::ClosureKind::FnOnce => p!(write("FnOnce")),
1054 ('tcx) ty::Predicate<'tcx>, (self, cx) {
1057 ty::Predicate::Trait(ref data) => p!(print(data)),
1058 ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
1059 ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
1060 ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
1061 ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
1062 ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
1063 ty::Predicate::ObjectSafe(trait_def_id) => {
1064 p!(write("the trait `"));
1065 nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty()));
1066 p!(write("` is object-safe"))
1068 ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
1069 p!(write("the closure `"));
1070 nest!(|cx| cx.print_value_path(closure_def_id, None));
1071 p!(write("` implements the trait `{}`", kind))
1073 ty::Predicate::ConstEvaluatable(def_id, substs) => {
1074 p!(write("the constant `"));
1075 nest!(|cx| cx.print_value_path(def_id, Some(substs)));
1076 p!(write("` can be evaluated"))
1082 ty::Predicate::Trait(ref a) => p!(print(a)),
1083 ty::Predicate::Subtype(ref pair) => p!(print(pair)),
1084 ty::Predicate::RegionOutlives(ref pair) => p!(print(pair)),
1085 ty::Predicate::TypeOutlives(ref pair) => p!(print(pair)),
1086 ty::Predicate::Projection(ref pair) => p!(print(pair)),
1087 ty::Predicate::WellFormed(ty) => p!(print(ty)),
1088 ty::Predicate::ObjectSafe(trait_def_id) => {
1089 p!(write("ObjectSafe({:?})", trait_def_id))
1091 ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
1092 p!(write("ClosureKind({:?}, {:?}, {:?})",
1093 closure_def_id, closure_substs, kind))
1095 ty::Predicate::ConstEvaluatable(def_id, substs) => {
1096 p!(write("ConstEvaluatable({:?}, {:?})", def_id, substs))
1104 ('tcx) Kind<'tcx>, (self, cx) {
1106 match self.unpack() {
1107 UnpackedKind::Lifetime(lt) => p!(print(lt)),
1108 UnpackedKind::Type(ty) => p!(print(ty)),
1109 UnpackedKind::Const(ct) => p!(print(ct)),
1113 match self.unpack() {
1114 UnpackedKind::Lifetime(lt) => p!(print(lt)),
1115 UnpackedKind::Type(ty) => p!(print(ty)),
1116 UnpackedKind::Const(ct) => p!(print(ct)),