1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use hir
::def_id
::DefId
;
12 use hir
::map
::definitions
::DefPathData
;
13 use middle
::const_val
::ConstVal
;
14 use middle
::region
::{self, BlockRemainder}
;
15 use ty
::subst
::{self, Subst}
;
16 use ty
::{BrAnon, BrEnv, BrFresh, BrNamed}
;
17 use ty
::{TyBool, TyChar, TyAdt}
;
18 use ty
::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}
;
19 use ty
::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}
;
20 use ty
::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon}
;
21 use ty
::{TyDynamic, TyInt, TyUint, TyInfer}
;
22 use ty
::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind}
;
23 use util
::nodemap
::FxHashSet
;
29 use rustc_data_structures
::indexed_vec
::Idx
;
30 use rustc_target
::spec
::abi
::Abi
;
31 use syntax
::ast
::CRATE_NODE_ID
;
32 use syntax
::symbol
::{Symbol, InternedString}
;
35 macro_rules
! gen_display_debug_body
{
37 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
38 let mut cx
= PrintContext
::new();
39 $
with(self, f
, &mut cx
)
43 macro_rules
! gen_display_debug
{
44 ( ($
($x
:tt
)+) $target
:ty
, display yes
) => {
45 impl<$
($x
)+> fmt
::Display
for $target
{
46 gen_display_debug_body
! { Print::print_display }
49 ( () $target
:ty
, display yes
) => {
50 impl fmt
::Display
for $target
{
51 gen_display_debug_body
! { Print::print_display }
54 ( ($
($x
:tt
)+) $target
:ty
, debug yes
) => {
55 impl<$
($x
)+> fmt
::Debug
for $target
{
56 gen_display_debug_body
! { Print::print_debug }
59 ( () $target
:ty
, debug yes
) => {
60 impl fmt
::Debug
for $target
{
61 gen_display_debug_body
! { Print::print_debug }
64 ( $generic
:tt $target
:ty
, $t
:ident no
) => {}
;
66 macro_rules
! gen_print_impl
{
67 ( ($
($x
:tt
)+) $target
:ty
, ($
self:ident
, $f
:ident
, $cx
:ident
) $disp
:block $dbg
:block
) => {
68 impl<$
($x
)+> Print
for $target
{
69 fn print
<F
: fmt
::Write
>(&$
self, $f
: &mut F
, $cx
: &mut PrintContext
) -> fmt
::Result
{
75 ( () $target
:ty
, ($
self:ident
, $f
:ident
, $cx
:ident
) $disp
:block $dbg
:block
) => {
76 impl Print
for $target
{
77 fn print
<F
: fmt
::Write
>(&$
self, $f
: &mut F
, $cx
: &mut PrintContext
) -> fmt
::Result
{
83 ( $generic
:tt $target
:ty
,
84 $vars
:tt $gendisp
:ident $disp
:block $gendbg
:ident $dbg
:block
) => {
85 gen_print_impl
! { $generic $target, $vars $disp $dbg }
86 gen_display_debug
! { $generic $target, display $gendisp }
87 gen_display_debug
! { $generic $target, debug $gendbg }
90 macro_rules
! define_print
{
91 ( $generic
:tt $target
:ty
,
92 $vars
:tt { display $disp:block debug $dbg:block }
) => {
93 gen_print_impl
! { $generic $target, $vars yes $disp yes $dbg }
95 ( $generic
:tt $target
:ty
,
96 $vars
:tt { debug $dbg:block display $disp:block }
) => {
97 gen_print_impl
! { $generic $target, $vars yes $disp yes $dbg }
99 ( $generic
:tt $target
:ty
,
100 $vars
:tt { debug $dbg:block }
) => {
101 gen_print_impl
! { $generic $target
, $vars no
{
102 bug
!(concat
!("display not implemented for ", stringify
!($target
)));
105 ( $generic
:tt $target
:ty
,
106 ($
self:ident
, $f
:ident
, $cx
:ident
) { display $disp:block }
) => {
107 gen_print_impl
! { $generic $target
, ($
self, $f
, $cx
) yes $disp no
{
108 write
!($f
, "{:?}", $
self)
112 macro_rules
! define_print_multi
{
113 ( [ $
($generic
:tt $target
:ty
),* ] $vars
:tt $def
:tt
) => {
114 $
(define_print
! { $generic $target, $vars $def }
)*
117 macro_rules
! print_inner
{
118 ( $f
:expr
, $cx
:expr
, write ($
($data
:expr
),+) ) => {
119 write
!($f
, $
($data
),+)
121 ( $f
:expr
, $cx
:expr
, $kind
:ident ($data
:expr
) ) => {
126 ( $f
:expr
, $cx
:expr $
(, $kind
:ident $data
:tt
)+ ) => {
127 Ok(())$
(.and_then(|_
| print_inner
!($f
, $cx
, $kind $data
)))+
132 struct LateBoundRegionNameCollector(FxHashSet
<InternedString
>);
133 impl<'tcx
> ty
::fold
::TypeVisitor
<'tcx
> for LateBoundRegionNameCollector
{
134 fn visit_region(&mut self, r
: ty
::Region
<'tcx
>) -> bool
{
136 ty
::ReLateBound(_
, ty
::BrNamed(_
, name
)) => {
141 r
.super_visit_with(self)
146 pub struct PrintContext
{
149 identify_regions
: bool
,
150 used_region_names
: Option
<FxHashSet
<InternedString
>>,
156 ty
::tls
::with_opt(|tcx
| {
157 let (is_verbose
, identify_regions
) = tcx
.map(
158 |tcx
| (tcx
.sess
.verbose(), tcx
.sess
.opts
.debugging_opts
.identify_regions
)
159 ).unwrap_or((false, false));
162 is_verbose
: is_verbose
,
163 identify_regions
: identify_regions
,
164 used_region_names
: None
,
170 fn prepare_late_bound_region_info
<'tcx
, T
>(&mut self, value
: &ty
::Binder
<T
>)
171 where T
: TypeFoldable
<'tcx
>
173 let mut collector
= LateBoundRegionNameCollector(FxHashSet());
174 value
.visit_with(&mut collector
);
175 self.used_region_names
= Some(collector
.0);
176 self.region_index
= 0;
181 fn print
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
;
182 fn print_to_string(&self, cx
: &mut PrintContext
) -> String
{
183 let mut result
= String
::new();
184 let _
= self.print(&mut result
, cx
);
187 fn print_display
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
{
188 let old_debug
= cx
.is_debug
;
190 let result
= self.print(f
, cx
);
191 cx
.is_debug
= old_debug
;
194 fn print_display_to_string(&self, cx
: &mut PrintContext
) -> String
{
195 let mut result
= String
::new();
196 let _
= self.print_display(&mut result
, cx
);
199 fn print_debug
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
{
200 let old_debug
= cx
.is_debug
;
202 let result
= self.print(f
, cx
);
203 cx
.is_debug
= old_debug
;
206 fn print_debug_to_string(&self, cx
: &mut PrintContext
) -> String
{
207 let mut result
= String
::new();
208 let _
= self.print_debug(&mut result
, cx
);
214 fn fn_sig
<F
: fmt
::Write
>(&mut self,
221 let mut inputs
= inputs
.iter();
222 if let Some(&ty
) = inputs
.next() {
223 print
!(f
, self, print_display(ty
))?
;
225 print
!(f
, self, write(", "), print_display(ty
))?
;
232 if !output
.is_nil() {
233 print
!(f
, self, write(" -> "), print_display(output
))?
;
239 fn parameterized
<F
: fmt
::Write
>(&mut self,
241 substs
: &subst
::Substs
,
243 projections
: &[ty
::ProjectionPredicate
])
245 let key
= ty
::tls
::with(|tcx
| tcx
.def_key(did
));
246 let mut item_name
= if let Some(name
) = key
.disambiguated_data
.data
.get_opt_name() {
249 did
.index
= key
.parent
.unwrap_or_else(
250 || bug
!("finding type for {:?}, encountered def-id {:?} with no parent",
252 self.parameterized(f
, substs
, did
, projections
)?
;
253 return write
!(f
, "::{}", key
.disambiguated_data
.data
.as_interned_str());
256 let verbose
= self.is_verbose
;
257 let mut num_supplied_defaults
= 0;
258 let mut has_self
= false;
259 let mut own_counts
= GenericParamCount
{
263 let mut is_value_path
= false;
264 let fn_trait_kind
= ty
::tls
::with(|tcx
| {
265 // Unfortunately, some kinds of items (e.g., closures) don't have
266 // generics. So walk back up the find the closest parent that DOES
268 let mut item_def_id
= did
;
270 let key
= tcx
.def_key(item_def_id
);
271 match key
.disambiguated_data
.data
{
272 DefPathData
::AssocTypeInTrait(_
) |
273 DefPathData
::AssocTypeInImpl(_
) |
274 DefPathData
::Trait(_
) |
275 DefPathData
::TypeNs(_
) => {
278 DefPathData
::ValueNs(_
) |
279 DefPathData
::EnumVariant(_
) => {
280 is_value_path
= true;
283 DefPathData
::CrateRoot
|
286 DefPathData
::Module(_
) |
287 DefPathData
::MacroDef(_
) |
288 DefPathData
::ClosureExpr
|
289 DefPathData
::TypeParam(_
) |
290 DefPathData
::LifetimeDef(_
) |
291 DefPathData
::Field(_
) |
292 DefPathData
::StructCtor
|
293 DefPathData
::AnonConst
|
294 DefPathData
::ExistentialImplTrait
|
295 DefPathData
::UniversalImplTrait
|
296 DefPathData
::GlobalMetaData(_
) => {
297 // if we're making a symbol for something, there ought
298 // to be a value or type-def or something in there
300 item_def_id
.index
= key
.parent
.unwrap_or_else(|| {
301 bug
!("finding type for {:?}, encountered def-id {:?} with no \
302 parent", did
, item_def_id
);
307 let mut generics
= tcx
.generics_of(item_def_id
);
308 let child_own_counts
= generics
.own_counts();
309 let mut path_def_id
= did
;
310 has_self
= generics
.has_self
;
312 let mut child_types
= 0;
313 if let Some(def_id
) = generics
.parent
{
315 assert
!(is_value_path
);
316 child_types
= child_own_counts
.types
;
317 generics
= tcx
.generics_of(def_id
);
318 own_counts
= generics
.own_counts();
321 print
!(f
, self, write("<"), print_display(substs
.type_at(0)), write(" as "))?
;
324 path_def_id
= def_id
;
330 assert_eq
!(has_self
, false);
333 own_counts
= child_own_counts
;
338 let mut type_params
=
339 generics
.params
.iter().rev().filter_map(|param
| {
341 GenericParamDefKind
::Type { has_default, .. }
=> {
342 Some((param
.def_id
, has_default
))
344 GenericParamDefKind
::Lifetime
=> None
,
348 let has_default
= type_params
.peek().map(|(_
, has_default
)| has_default
);
349 *has_default
.unwrap_or(&false)
352 if let Some(substs
) = tcx
.lift(&substs
) {
353 let mut types
= substs
.types().rev().skip(child_types
);
354 for ((def_id
, has_default
), actual
) in type_params
.zip(types
) {
358 if tcx
.type_of(def_id
).subst(tcx
, substs
) != actual
{
361 num_supplied_defaults
+= 1;
367 print
!(f
, self, write("{}", tcx
.item_path_str(path_def_id
)))?
;
368 Ok(tcx
.lang_items().fn_trait_kind(path_def_id
))
371 if !verbose
&& fn_trait_kind
.is_some() && projections
.len() == 1 {
372 let projection_ty
= projections
[0].ty
;
373 if let TyTuple(ref args
) = substs
.type_at(1).sty
{
374 return self.fn_sig(f
, args
, false, projection_ty
);
378 let empty
= Cell
::new(true);
379 let start_or_continue
= |f
: &mut F
, start
: &str, cont
: &str| {
382 write
!(f
, "{}", start
)
384 write
!(f
, "{}", cont
)
388 let print_regions
= |f
: &mut F
, start
: &str, skip
, count
| {
389 // Don't print any regions if they're all erased.
390 let regions
= || substs
.regions().skip(skip
).take(count
);
391 if regions().all(|r
: ty
::Region
| *r
== ty
::ReErased
) {
395 for region
in regions() {
396 let region
: ty
::Region
= region
;
397 start_or_continue(f
, start
, ", ")?
;
399 write
!(f
, "{:?}", region
)?
;
401 let s
= region
.to_string();
403 // This happens when the value of the region
404 // parameter is not easily serialized. This may be
405 // because the user omitted it in the first place,
406 // or because it refers to some block in the code,
407 // etc. I'm not sure how best to serialize this.
418 print_regions(f
, "<", 0, own_counts
.lifetimes
)?
;
420 let tps
= substs
.types()
421 .take(own_counts
.types
- num_supplied_defaults
)
422 .skip(has_self
as usize);
425 start_or_continue(f
, "<", ", ")?
;
426 ty
.print_display(f
, self)?
;
429 for projection
in projections
{
430 start_or_continue(f
, "<", ", ")?
;
434 tcx
.associated_item(projection
.projection_ty
.item_def_id
).name
),
435 print_display(projection
.ty
))
439 start_or_continue(f
, "", ">")?
;
441 // For values, also print their name and type parameters.
449 if let Some(item_name
) = item_name
{
450 write
!(f
, "::{}", item_name
)?
;
453 print_regions(f
, "::<", own_counts
.lifetimes
, usize::MAX
)?
;
455 // FIXME: consider being smart with defaults here too
456 for ty
in substs
.types().skip(own_counts
.types
) {
457 start_or_continue(f
, "::<", ", ")?
;
458 ty
.print_display(f
, self)?
;
461 start_or_continue(f
, "", ">")?
;
467 fn in_binder
<'a
, 'gcx
, 'tcx
, T
, U
, F
>(&mut self,
469 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
470 original
: &ty
::Binder
<T
>,
471 lifted
: Option
<ty
::Binder
<U
>>) -> fmt
::Result
472 where T
: Print
, U
: Print
+ TypeFoldable
<'tcx
>, F
: fmt
::Write
474 fn name_by_region_index(index
: usize) -> InternedString
{
476 0 => Symbol
::intern("'r"),
477 1 => Symbol
::intern("'s"),
478 i
=> Symbol
::intern(&format
!("'t{}", i
-2)),
482 // Replace any anonymous late-bound regions with named
483 // variants, using gensym'd identifiers, so that we can
484 // clearly differentiate between named and unnamed regions in
485 // the output. We'll probably want to tweak this over time to
486 // decide just how much information to give.
487 let value
= if let Some(v
) = lifted
{
490 return original
.skip_binder().print_display(f
, self);
493 if self.binder_depth
== 0 {
494 self.prepare_late_bound_region_info(&value
);
497 let mut empty
= true;
498 let mut start_or_continue
= |f
: &mut F
, start
: &str, cont
: &str| {
501 write
!(f
, "{}", start
)
503 write
!(f
, "{}", cont
)
507 let old_region_index
= self.region_index
;
508 let mut region_index
= old_region_index
;
509 let new_value
= tcx
.replace_late_bound_regions(&value
, |br
| {
510 let _
= start_or_continue(f
, "for<", ", ");
512 ty
::BrNamed(_
, name
) => {
513 let _
= write
!(f
, "{}", name
);
520 let name
= name_by_region_index(region_index
);
522 if !self.is_name_used(&name
) {
526 let _
= write
!(f
, "{}", name
);
527 ty
::BrNamed(tcx
.hir
.local_def_id(CRATE_NODE_ID
), name
)
530 tcx
.mk_region(ty
::ReLateBound(ty
::INNERMOST
, br
))
532 start_or_continue(f
, "", "> ")?
;
534 // Push current state to gcx, and restore after writing new_value.
535 self.binder_depth
+= 1;
536 self.region_index
= region_index
;
537 let result
= new_value
.print_display(f
, self);
538 self.region_index
= old_region_index
;
539 self.binder_depth
-= 1;
543 fn is_name_used(&self, name
: &InternedString
) -> bool
{
544 match self.used_region_names
{
545 Some(ref names
) => names
.contains(name
),
551 pub fn verbose() -> bool
{
552 ty
::tls
::with(|tcx
| tcx
.sess
.verbose())
555 pub fn identify_regions() -> bool
{
556 ty
::tls
::with(|tcx
| tcx
.sess
.opts
.debugging_opts
.identify_regions
)
559 pub fn parameterized
<F
: fmt
::Write
>(f
: &mut F
,
560 substs
: &subst
::Substs
,
562 projections
: &[ty
::ProjectionPredicate
])
564 PrintContext
::new().parameterized(f
, substs
, did
, projections
)
568 impl<'a
, T
: Print
> Print
for &'a T
{
569 fn print
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
{
575 ('tcx
) &'tcx ty
::Slice
<ty
::ExistentialPredicate
<'tcx
>>, (self, f
, cx
) {
577 // Generate the main trait ref, including associated types.
578 ty
::tls
::with(|tcx
| {
579 // Use a type that can't appear in defaults of type parameters.
580 let dummy_self
= tcx
.mk_infer(ty
::FreshTy(0));
582 if let Some(p
) = self.principal() {
583 let principal
= tcx
.lift(&p
).expect("could not lift TraitRef for printing")
584 .with_self_ty(tcx
, dummy_self
);
585 let projections
= self.projection_bounds().map(|p
| {
587 .expect("could not lift projection for printing")
588 .with_self_ty(tcx
, dummy_self
)
589 }).collect
::<Vec
<_
>>();
590 cx
.parameterized(f
, principal
.substs
, principal
.def_id
, &projections
)?
;
594 for did
in self.auto_traits() {
595 write
!(f
, " + {}", tcx
.item_path_str(did
))?
;
606 impl fmt
::Debug
for ty
::GenericParamDef
{
607 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
608 let type_name
= match self.kind
{
609 ty
::GenericParamDefKind
::Lifetime
=> "Lifetime",
610 ty
::GenericParamDefKind
::Type {..}
=> "Type",
612 write
!(f
, "{}({}, {:?}, {})",
620 impl fmt
::Debug
for ty
::TraitDef
{
621 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
622 ty
::tls
::with(|tcx
| {
623 write
!(f
, "{}", tcx
.item_path_str(self.def_id
))
628 impl fmt
::Debug
for ty
::AdtDef
{
629 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
630 ty
::tls
::with(|tcx
| {
631 write
!(f
, "{}", tcx
.item_path_str(self.did
))
636 impl<'tcx
> fmt
::Debug
for ty
::ClosureUpvar
<'tcx
> {
637 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
638 write
!(f
, "ClosureUpvar({:?},{:?})",
644 impl fmt
::Debug
for ty
::UpvarId
{
645 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
646 write
!(f
, "UpvarId({:?};`{}`;{:?})",
648 ty
::tls
::with(|tcx
| tcx
.hir
.name(tcx
.hir
.hir_to_node_id(self.var_id
))),
649 self.closure_expr_id
)
653 impl<'tcx
> fmt
::Debug
for ty
::UpvarBorrow
<'tcx
> {
654 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
655 write
!(f
, "UpvarBorrow({:?}, {:?})",
656 self.kind
, self.region
)
661 ('tcx
) &'tcx ty
::Slice
<Ty
<'tcx
>>, (self, f
, cx
) {
664 let mut tys
= self.iter();
665 if let Some(&ty
) = tys
.next() {
666 print
!(f
, cx
, print(ty
))?
;
668 print
!(f
, cx
, write(", "), print(ty
))?
;
677 ('tcx
) ty
::TypeAndMut
<'tcx
>, (self, f
, cx
) {
680 write("{}", if self.mutbl
== hir
::MutMutable { "mut " }
else { "" }
),
687 ('tcx
) ty
::ExistentialTraitRef
<'tcx
>, (self, f
, cx
) {
689 ty
::tls
::with(|tcx
| {
690 let dummy_self
= tcx
.mk_infer(ty
::FreshTy(0));
692 let trait_ref
= *tcx
.lift(&ty
::Binder
::bind(*self))
693 .expect("could not lift TraitRef for printing")
694 .with_self_ty(tcx
, dummy_self
).skip_binder();
695 cx
.parameterized(f
, trait_ref
.substs
, trait_ref
.def_id
, &[])
702 ('tcx
) ty
::adjustment
::Adjustment
<'tcx
>, (self, f
, cx
) {
704 print
!(f
, cx
, write("{:?} -> ", self.kind
), print(self.target
))
710 () ty
::BoundRegion
, (self, f
, cx
) {
713 return self.print_debug(f
, cx
);
717 BrNamed(_
, name
) => write
!(f
, "{}", name
),
718 BrAnon(_
) | BrFresh(_
) | BrEnv
=> Ok(())
723 BrAnon(n
) => write
!(f
, "BrAnon({:?})", n
),
724 BrFresh(n
) => write
!(f
, "BrFresh({:?})", n
),
725 BrNamed(did
, name
) => {
726 write
!(f
, "BrNamed({:?}:{:?}, {})",
727 did
.krate
, did
.index
, name
)
729 BrEnv
=> write
!(f
, "BrEnv"),
736 () ty
::RegionKind
, (self, f
, cx
) {
739 return self.print_debug(f
, cx
);
742 // These printouts are concise. They do not contain all the information
743 // the user might want to diagnose an error, but there is basically no way
744 // to fit that into a short string. Hence the recommendation to use
745 // `explain_region()` or `note_and_explain_region()`.
747 ty
::ReEarlyBound(ref data
) => {
748 write
!(f
, "{}", data
.name
)
750 ty
::ReCanonical(_
) => {
753 ty
::ReLateBound(_
, br
) |
754 ty
::ReFree(ty
::FreeRegion { bound_region: br, .. }
) |
755 ty
::ReSkolemized(_
, br
) => {
758 ty
::ReScope(scope
) if cx
.identify_regions
=> {
760 region
::ScopeData
::Node(id
) =>
761 write
!(f
, "'{}s", id
.as_usize()),
762 region
::ScopeData
::CallSite(id
) =>
763 write
!(f
, "'{}cs", id
.as_usize()),
764 region
::ScopeData
::Arguments(id
) =>
765 write
!(f
, "'{}as", id
.as_usize()),
766 region
::ScopeData
::Destruction(id
) =>
767 write
!(f
, "'{}ds", id
.as_usize()),
768 region
::ScopeData
::Remainder(BlockRemainder
769 { block, first_statement_index }
) =>
770 write
!(f
, "'{}_{}rs", block
.as_usize(), first_statement_index
.index()),
773 ty
::ReVar(region_vid
) if cx
.identify_regions
=> {
774 write
!(f
, "'{}rv", region_vid
.index())
778 ty
::ReErased
=> Ok(()),
779 ty
::ReStatic
=> write
!(f
, "'static"),
780 ty
::ReEmpty
=> write
!(f
, "'<empty>"),
782 // The user should never encounter these in unsubstituted form.
783 ty
::ReClosureBound(vid
) => write
!(f
, "{:?}", vid
),
788 ty
::ReEarlyBound(ref data
) => {
789 write
!(f
, "ReEarlyBound({}, {})",
794 ty
::ReClosureBound(ref vid
) => {
795 write
!(f
, "ReClosureBound({:?})",
799 ty
::ReLateBound(binder_id
, ref bound_region
) => {
800 write
!(f
, "ReLateBound({:?}, {:?})",
805 ty
::ReFree(ref fr
) => write
!(f
, "{:?}", fr
),
808 write
!(f
, "ReScope({:?})", id
)
811 ty
::ReStatic
=> write
!(f
, "ReStatic"),
813 ty
::ReVar(ref vid
) => {
814 write
!(f
, "{:?}", vid
)
817 ty
::ReCanonical(c
) => {
818 write
!(f
, "'?{}", c
.index())
821 ty
::ReSkolemized(universe
, ref bound_region
) => {
822 write
!(f
, "ReSkolemized({:?}, {:?})", universe
, bound_region
)
825 ty
::ReEmpty
=> write
!(f
, "ReEmpty"),
827 ty
::ReErased
=> write
!(f
, "ReErased")
834 () ty
::FreeRegion
, (self, f
, cx
) {
836 write
!(f
, "ReFree({:?}, {:?})", self.scope
, self.bound_region
)
842 () ty
::Variance
, (self, f
, cx
) {
844 f
.write_str(match *self {
845 ty
::Covariant
=> "+",
846 ty
::Contravariant
=> "-",
847 ty
::Invariant
=> "o",
848 ty
::Bivariant
=> "*",
855 ('tcx
) ty
::GenericPredicates
<'tcx
>, (self, f
, cx
) {
857 write
!(f
, "GenericPredicates({:?})", self.predicates
)
863 ('tcx
) ty
::InstantiatedPredicates
<'tcx
>, (self, f
, cx
) {
865 write
!(f
, "InstantiatedPredicates({:?})", self.predicates
)
871 ('tcx
) ty
::FnSig
<'tcx
>, (self, f
, cx
) {
873 if self.unsafety
== hir
::Unsafety
::Unsafe
{
874 write
!(f
, "unsafe ")?
;
877 if self.abi
!= Abi
::Rust
{
878 write
!(f
, "extern {} ", self.abi
)?
;
882 cx
.fn_sig(f
, self.inputs(), self.variadic
, self.output())
885 write
!(f
, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic
, self.output())
890 impl fmt
::Debug
for ty
::TyVid
{
891 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
892 write
!(f
, "_#{}t", self.index
)
896 impl fmt
::Debug
for ty
::IntVid
{
897 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
898 write
!(f
, "_#{}i", self.index
)
902 impl fmt
::Debug
for ty
::FloatVid
{
903 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
904 write
!(f
, "_#{}f", self.index
)
908 impl fmt
::Debug
for ty
::RegionVid
{
909 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
910 write
!(f
, "'_#{}r", self.index())
915 () ty
::InferTy
, (self, f
, cx
) {
918 print
!(f
, cx
, print_debug(self))
921 ty
::TyVar(_
) => write
!(f
, "_"),
922 ty
::IntVar(_
) => write
!(f
, "{}", "{integer}"),
923 ty
::FloatVar(_
) => write
!(f
, "{}", "{float}"),
924 ty
::CanonicalTy(_
) => write
!(f
, "_"),
925 ty
::FreshTy(v
) => write
!(f
, "FreshTy({})", v
),
926 ty
::FreshIntTy(v
) => write
!(f
, "FreshIntTy({})", v
),
927 ty
::FreshFloatTy(v
) => write
!(f
, "FreshFloatTy({})", v
)
933 ty
::TyVar(ref v
) => write
!(f
, "{:?}", v
),
934 ty
::IntVar(ref v
) => write
!(f
, "{:?}", v
),
935 ty
::FloatVar(ref v
) => write
!(f
, "{:?}", v
),
936 ty
::CanonicalTy(v
) => write
!(f
, "?{:?}", v
.index()),
937 ty
::FreshTy(v
) => write
!(f
, "FreshTy({:?})", v
),
938 ty
::FreshIntTy(v
) => write
!(f
, "FreshIntTy({:?})", v
),
939 ty
::FreshFloatTy(v
) => write
!(f
, "FreshFloatTy({:?})", v
)
945 impl fmt
::Debug
for ty
::IntVarValue
{
946 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
948 ty
::IntType(ref v
) => v
.fmt(f
),
949 ty
::UintType(ref v
) => v
.fmt(f
),
954 impl fmt
::Debug
for ty
::FloatVarValue
{
955 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
960 // The generic impl doesn't work yet because projections are not
961 // normalized under HRTB.
962 /*impl<T> fmt::Display for ty::Binder<T>
963 where T: fmt::Display + for<'a> ty::Lift<'a>,
964 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
966 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
967 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
971 define_print_multi
! {
973 ('tcx
) ty
::Binder
<&'tcx ty
::Slice
<ty
::ExistentialPredicate
<'tcx
>>>,
974 ('tcx
) ty
::Binder
<ty
::TraitRef
<'tcx
>>,
975 ('tcx
) ty
::Binder
<ty
::FnSig
<'tcx
>>,
976 ('tcx
) ty
::Binder
<ty
::TraitPredicate
<'tcx
>>,
977 ('tcx
) ty
::Binder
<ty
::SubtypePredicate
<'tcx
>>,
978 ('tcx
) ty
::Binder
<ty
::ProjectionPredicate
<'tcx
>>,
979 ('tcx
) ty
::Binder
<ty
::OutlivesPredicate
<Ty
<'tcx
>, ty
::Region
<'tcx
>>>,
980 ('tcx
) ty
::Binder
<ty
::OutlivesPredicate
<ty
::Region
<'tcx
>, ty
::Region
<'tcx
>>>
984 ty
::tls
::with(|tcx
| cx
.in_binder(f
, tcx
, self, tcx
.lift(self)))
990 ('tcx
) ty
::TraitRef
<'tcx
>, (self, f
, cx
) {
992 cx
.parameterized(f
, self.substs
, self.def_id
, &[])
995 // when printing out the debug representation, we don't need
996 // to enumerate the `for<...>` etc because the debruijn index
997 // tells you everything you need to know.
1000 print(self.self_ty()),
1002 cx
.parameterized(f
, self.substs
, self.def_id
, &[])?
;
1009 ('tcx
) ty
::TypeVariants
<'tcx
>, (self, f
, cx
) {
1012 TyBool
=> write
!(f
, "bool"),
1013 TyChar
=> write
!(f
, "char"),
1014 TyInt(t
) => write
!(f
, "{}", t
.ty_to_string()),
1015 TyUint(t
) => write
!(f
, "{}", t
.ty_to_string()),
1016 TyFloat(t
) => write
!(f
, "{}", t
.ty_to_string()),
1017 TyRawPtr(ref tm
) => {
1018 write
!(f
, "*{} ", match tm
.mutbl
{
1019 hir
::MutMutable
=> "mut",
1020 hir
::MutImmutable
=> "const",
1024 TyRef(r
, ty
, mutbl
) => {
1026 let s
= r
.print_to_string(cx
);
1027 write
!(f
, "{}", s
)?
;
1031 ty
::TypeAndMut { ty, mutbl }
.print(f
, cx
)
1033 TyNever
=> write
!(f
, "!"),
1034 TyTuple(ref tys
) => {
1036 let mut tys
= tys
.iter();
1037 if let Some(&ty
) = tys
.next() {
1038 print
!(f
, cx
, print(ty
), write(","))?
;
1039 if let Some(&ty
) = tys
.next() {
1040 print
!(f
, cx
, write(" "), print(ty
))?
;
1042 print
!(f
, cx
, write(", "), print(ty
))?
;
1048 TyFnDef(def_id
, substs
) => {
1049 ty
::tls
::with(|tcx
| {
1050 let mut sig
= tcx
.fn_sig(def_id
);
1051 if let Some(substs
) = tcx
.lift(&substs
) {
1052 sig
= sig
.subst(tcx
, substs
);
1054 print
!(f
, cx
, print(sig
), write(" {{"))
1056 cx
.parameterized(f
, substs
, def_id
, &[])?
;
1059 TyFnPtr(ref bare_fn
) => {
1060 bare_fn
.print(f
, cx
)
1062 TyInfer(infer_ty
) => write
!(f
, "{}", infer_ty
),
1063 TyError
=> write
!(f
, "[type error]"),
1064 TyParam(ref param_ty
) => write
!(f
, "{}", param_ty
),
1065 TyAdt(def
, substs
) => cx
.parameterized(f
, substs
, def
.did
, &[]),
1066 TyDynamic(data
, r
) => {
1068 let r
= r
.print_to_string(cx
);
1070 write
!(f
, " + {}", r
)
1075 TyForeign(def_id
) => parameterized(f
, subst
::Substs
::empty(), def_id
, &[]),
1076 TyProjection(ref data
) => data
.print(f
, cx
),
1077 TyAnon(def_id
, substs
) => {
1079 return write
!(f
, "TyAnon({:?}, {:?})", def_id
, substs
);
1082 ty
::tls
::with(|tcx
| {
1083 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
1084 // by looking up the projections associated with the def_id.
1085 let predicates_of
= tcx
.predicates_of(def_id
);
1086 let substs
= tcx
.lift(&substs
).unwrap_or_else(|| {
1087 tcx
.intern_substs(&[])
1089 let bounds
= predicates_of
.instantiate(tcx
, substs
);
1091 let mut first
= true;
1092 let mut is_sized
= false;
1094 for predicate
in bounds
.predicates
{
1095 if let Some(trait_ref
) = predicate
.to_opt_poly_trait_ref() {
1096 // Don't print +Sized, but rather +?Sized if absent.
1097 if Some(trait_ref
.def_id()) == tcx
.lang_items().sized_trait() {
1103 write("{}", if first { " " }
else { "+" }
),
1109 write
!(f
, "{}?Sized", if first { " " }
else { "+" }
)?
;
1114 TyStr
=> write
!(f
, "str"),
1115 TyGenerator(did
, substs
, movability
) => ty
::tls
::with(|tcx
| {
1116 let upvar_tys
= substs
.upvar_tys(did
, tcx
);
1117 let witness
= substs
.witness(did
, tcx
);
1118 if movability
== hir
::GeneratorMovability
::Movable
{
1119 write
!(f
, "[generator")?
;
1121 write
!(f
, "[static generator")?
;
1124 if let Some(node_id
) = tcx
.hir
.as_local_node_id(did
) {
1125 write
!(f
, "@{:?}", tcx
.hir
.span(node_id
))?
;
1127 tcx
.with_freevars(node_id
, |freevars
| {
1128 for (freevar
, upvar_ty
) in freevars
.iter().zip(upvar_tys
) {
1132 tcx
.hir
.name(freevar
.var_id())),
1139 // cross-crate closure types should only be
1140 // visible in codegen bug reports, I imagine.
1141 write
!(f
, "@{:?}", did
)?
;
1143 for (index
, upvar_ty
) in upvar_tys
.enumerate() {
1145 write("{}{}:", sep
, index
),
1151 print
!(f
, cx
, write(" "), print(witness
), write("]"))
1153 TyGeneratorWitness(types
) => {
1154 ty
::tls
::with(|tcx
| cx
.in_binder(f
, tcx
, &types
, tcx
.lift(&types
)))
1156 TyClosure(did
, substs
) => ty
::tls
::with(|tcx
| {
1157 let upvar_tys
= substs
.upvar_tys(did
, tcx
);
1158 write
!(f
, "[closure")?
;
1160 if let Some(node_id
) = tcx
.hir
.as_local_node_id(did
) {
1161 if tcx
.sess
.opts
.debugging_opts
.span_free_formats
{
1162 write
!(f
, "@{:?}", node_id
)?
;
1164 write
!(f
, "@{:?}", tcx
.hir
.span(node_id
))?
;
1167 tcx
.with_freevars(node_id
, |freevars
| {
1168 for (freevar
, upvar_ty
) in freevars
.iter().zip(upvar_tys
) {
1172 tcx
.hir
.name(freevar
.var_id())),
1179 // cross-crate closure types should only be
1180 // visible in codegen bug reports, I imagine.
1181 write
!(f
, "@{:?}", did
)?
;
1183 for (index
, upvar_ty
) in upvar_tys
.enumerate() {
1185 write("{}{}:", sep
, index
),
1193 TyArray(ty
, sz
) => {
1194 print
!(f
, cx
, write("["), print(ty
), write("; "))?
;
1196 ConstVal
::Value(..) => ty
::tls
::with(|tcx
| {
1197 write
!(f
, "{}", sz
.unwrap_usize(tcx
))
1199 ConstVal
::Unevaluated(_def_id
, _substs
) => {
1206 print
!(f
, cx
, write("["), print(ty
), write("]"))
1214 ('tcx
) ty
::TyS
<'tcx
>, (self, f
, cx
) {
1216 self.sty
.print(f
, cx
)
1219 self.sty
.print_display(f
, cx
)
1225 () ty
::ParamTy
, (self, f
, cx
) {
1227 write
!(f
, "{}", self.name
)
1230 write
!(f
, "{}/#{}", self.name
, self.idx
)
1236 ('tcx
, T
: Print
+ fmt
::Debug
, U
: Print
+ fmt
::Debug
) ty
::OutlivesPredicate
<T
, U
>,
1239 print
!(f
, cx
, print(self.0), write(" : "), print(self.1))
1245 ('tcx
) ty
::SubtypePredicate
<'tcx
>, (self, f
, cx
) {
1247 print
!(f
, cx
, print(self.a
), write(" <: "), print(self.b
))
1253 ('tcx
) ty
::TraitPredicate
<'tcx
>, (self, f
, cx
) {
1255 write
!(f
, "TraitPredicate({:?})",
1259 print
!(f
, cx
, print(self.trait_ref
.self_ty()), write(": "), print(self.trait_ref
))
1265 ('tcx
) ty
::ProjectionPredicate
<'tcx
>, (self, f
, cx
) {
1268 write("ProjectionPredicate("),
1269 print(self.projection_ty
),
1275 print
!(f
, cx
, print(self.projection_ty
), write(" == "), print(self.ty
))
1281 ('tcx
) ty
::ProjectionTy
<'tcx
>, (self, f
, cx
) {
1283 // FIXME(tschottdorf): use something like
1284 // parameterized(f, self.substs, self.item_def_id, &[])
1285 // (which currently ICEs).
1286 let (trait_ref
, item_name
) = ty
::tls
::with(|tcx
|
1287 (self.trait_ref(tcx
), tcx
.associated_item(self.item_def_id
).name
)
1289 print
!(f
, cx
, print_debug(trait_ref
), write("::{}", item_name
))
1295 () ty
::ClosureKind
, (self, f
, cx
) {
1298 ty
::ClosureKind
::Fn
=> write
!(f
, "Fn"),
1299 ty
::ClosureKind
::FnMut
=> write
!(f
, "FnMut"),
1300 ty
::ClosureKind
::FnOnce
=> write
!(f
, "FnOnce"),
1307 ('tcx
) ty
::Predicate
<'tcx
>, (self, f
, cx
) {
1310 ty
::Predicate
::Trait(ref data
) => data
.print(f
, cx
),
1311 ty
::Predicate
::Subtype(ref predicate
) => predicate
.print(f
, cx
),
1312 ty
::Predicate
::RegionOutlives(ref predicate
) => predicate
.print(f
, cx
),
1313 ty
::Predicate
::TypeOutlives(ref predicate
) => predicate
.print(f
, cx
),
1314 ty
::Predicate
::Projection(ref predicate
) => predicate
.print(f
, cx
),
1315 ty
::Predicate
::WellFormed(ty
) => print
!(f
, cx
, print(ty
), write(" well-formed")),
1316 ty
::Predicate
::ObjectSafe(trait_def_id
) =>
1317 ty
::tls
::with(|tcx
| {
1318 write
!(f
, "the trait `{}` is object-safe", tcx
.item_path_str(trait_def_id
))
1320 ty
::Predicate
::ClosureKind(closure_def_id
, _closure_substs
, kind
) =>
1321 ty
::tls
::with(|tcx
| {
1322 write
!(f
, "the closure `{}` implements the trait `{}`",
1323 tcx
.item_path_str(closure_def_id
), kind
)
1325 ty
::Predicate
::ConstEvaluatable(def_id
, substs
) => {
1326 write
!(f
, "the constant `")?
;
1327 cx
.parameterized(f
, substs
, def_id
, &[])?
;
1328 write
!(f
, "` can be evaluated")
1334 ty
::Predicate
::Trait(ref a
) => a
.print(f
, cx
),
1335 ty
::Predicate
::Subtype(ref pair
) => pair
.print(f
, cx
),
1336 ty
::Predicate
::RegionOutlives(ref pair
) => pair
.print(f
, cx
),
1337 ty
::Predicate
::TypeOutlives(ref pair
) => pair
.print(f
, cx
),
1338 ty
::Predicate
::Projection(ref pair
) => pair
.print(f
, cx
),
1339 ty
::Predicate
::WellFormed(ty
) => ty
.print(f
, cx
),
1340 ty
::Predicate
::ObjectSafe(trait_def_id
) => {
1341 write
!(f
, "ObjectSafe({:?})", trait_def_id
)
1343 ty
::Predicate
::ClosureKind(closure_def_id
, closure_substs
, kind
) => {
1344 write
!(f
, "ClosureKind({:?}, {:?}, {:?})", closure_def_id
, closure_substs
, kind
)
1346 ty
::Predicate
::ConstEvaluatable(def_id
, substs
) => {
1347 write
!(f
, "ConstEvaluatable({:?}, {:?})", def_id
, substs
)