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, TyForeign, TyProjection, TyAnon}
;
21 use ty
::{TyDynamic, TyInt, TyUint, TyInfer}
;
22 use ty
::{self, Ty, TyCtxt, TypeFoldable}
;
23 use util
::nodemap
::FxHashSet
;
29 use rustc_const_math
::ConstInt
;
30 use rustc_data_structures
::indexed_vec
::Idx
;
32 use syntax
::ast
::CRATE_NODE_ID
;
33 use syntax
::symbol
::Symbol
;
36 macro_rules
! gen_display_debug_body
{
38 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
39 let mut cx
= PrintContext
::new();
40 $
with(self, f
, &mut cx
)
44 macro_rules
! gen_display_debug
{
45 ( ($
($x
:tt
)+) $target
:ty
, display yes
) => {
46 impl<$
($x
)+> fmt
::Display
for $target
{
47 gen_display_debug_body
! { Print::print_display }
50 ( () $target
:ty
, display yes
) => {
51 impl fmt
::Display
for $target
{
52 gen_display_debug_body
! { Print::print_display }
55 ( ($
($x
:tt
)+) $target
:ty
, debug yes
) => {
56 impl<$
($x
)+> fmt
::Debug
for $target
{
57 gen_display_debug_body
! { Print::print_debug }
60 ( () $target
:ty
, debug yes
) => {
61 impl fmt
::Debug
for $target
{
62 gen_display_debug_body
! { Print::print_debug }
65 ( $generic
:tt $target
:ty
, $t
:ident no
) => {}
;
67 macro_rules
! gen_print_impl
{
68 ( ($
($x
:tt
)+) $target
:ty
, ($
self:ident
, $f
:ident
, $cx
:ident
) $disp
:block $dbg
:block
) => {
69 impl<$
($x
)+> Print
for $target
{
70 fn print
<F
: fmt
::Write
>(&$
self, $f
: &mut F
, $cx
: &mut PrintContext
) -> fmt
::Result
{
76 ( () $target
:ty
, ($
self:ident
, $f
:ident
, $cx
:ident
) $disp
:block $dbg
:block
) => {
77 impl Print
for $target
{
78 fn print
<F
: fmt
::Write
>(&$
self, $f
: &mut F
, $cx
: &mut PrintContext
) -> fmt
::Result
{
84 ( $generic
:tt $target
:ty
,
85 $vars
:tt $gendisp
:ident $disp
:block $gendbg
:ident $dbg
:block
) => {
86 gen_print_impl
! { $generic $target, $vars $disp $dbg }
87 gen_display_debug
! { $generic $target, display $gendisp }
88 gen_display_debug
! { $generic $target, debug $gendbg }
91 macro_rules
! define_print
{
92 ( $generic
:tt $target
:ty
,
93 $vars
:tt { display $disp:block debug $dbg:block }
) => {
94 gen_print_impl
! { $generic $target, $vars yes $disp yes $dbg }
96 ( $generic
:tt $target
:ty
,
97 $vars
:tt { debug $dbg:block display $disp:block }
) => {
98 gen_print_impl
! { $generic $target, $vars yes $disp yes $dbg }
100 ( $generic
:tt $target
:ty
,
101 $vars
:tt { debug $dbg:block }
) => {
102 gen_print_impl
! { $generic $target
, $vars no
{
103 bug
!(concat
!("display not implemented for ", stringify
!($target
)));
106 ( $generic
:tt $target
:ty
,
107 ($
self:ident
, $f
:ident
, $cx
:ident
) { display $disp:block }
) => {
108 gen_print_impl
! { $generic $target
, ($
self, $f
, $cx
) yes $disp no
{
109 write
!($f
, "{:?}", $
self)
113 macro_rules
! define_print_multi
{
114 ( [ $
($generic
:tt $target
:ty
),* ] $vars
:tt $def
:tt
) => {
115 $
(define_print
! { $generic $target, $vars $def }
)*
118 macro_rules
! print_inner
{
119 ( $f
:expr
, $cx
:expr
, write ($
($data
:expr
),+) ) => {
120 write
!($f
, $
($data
),+)
122 ( $f
:expr
, $cx
:expr
, $kind
:ident ($data
:expr
) ) => {
127 ( $f
:expr
, $cx
:expr $
(, $kind
:ident $data
:tt
)+ ) => {
128 Ok(())$
(.and_then(|_
| print_inner
!($f
, $cx
, $kind $data
)))+
133 struct LateBoundRegionNameCollector(FxHashSet
<Symbol
>);
134 impl<'tcx
> ty
::fold
::TypeVisitor
<'tcx
> for LateBoundRegionNameCollector
{
135 fn visit_region(&mut self, r
: ty
::Region
<'tcx
>) -> bool
{
137 ty
::ReLateBound(_
, ty
::BrNamed(_
, name
)) => {
142 r
.super_visit_with(self)
147 pub struct PrintContext
{
150 identify_regions
: bool
,
151 used_region_names
: Option
<FxHashSet
<Symbol
>>,
157 ty
::tls
::with_opt(|tcx
| {
158 let (is_verbose
, identify_regions
) = tcx
.map(
159 |tcx
| (tcx
.sess
.verbose(), tcx
.sess
.opts
.debugging_opts
.identify_regions
)
160 ).unwrap_or((false, false));
163 is_verbose
: is_verbose
,
164 identify_regions
: identify_regions
,
165 used_region_names
: None
,
171 fn prepare_late_bound_region_info
<'tcx
, T
>(&mut self, value
: &ty
::Binder
<T
>)
172 where T
: TypeFoldable
<'tcx
>
174 let mut collector
= LateBoundRegionNameCollector(FxHashSet());
175 value
.visit_with(&mut collector
);
176 self.used_region_names
= Some(collector
.0);
177 self.region_index
= 0;
182 fn print
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
;
183 fn print_to_string(&self, cx
: &mut PrintContext
) -> String
{
184 let mut result
= String
::new();
185 let _
= self.print(&mut result
, cx
);
188 fn print_display
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
{
189 let old_debug
= cx
.is_debug
;
191 let result
= self.print(f
, cx
);
192 cx
.is_debug
= old_debug
;
195 fn print_display_to_string(&self, cx
: &mut PrintContext
) -> String
{
196 let mut result
= String
::new();
197 let _
= self.print_display(&mut result
, cx
);
200 fn print_debug
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
{
201 let old_debug
= cx
.is_debug
;
203 let result
= self.print(f
, cx
);
204 cx
.is_debug
= old_debug
;
207 fn print_debug_to_string(&self, cx
: &mut PrintContext
) -> String
{
208 let mut result
= String
::new();
209 let _
= self.print_debug(&mut result
, cx
);
215 fn fn_sig
<F
: fmt
::Write
>(&mut self,
222 let mut inputs
= inputs
.iter();
223 if let Some(&ty
) = inputs
.next() {
224 print
!(f
, self, print_display(ty
))?
;
226 print
!(f
, self, write(", "), print_display(ty
))?
;
233 if !output
.is_nil() {
234 print
!(f
, self, write(" -> "), print_display(output
))?
;
240 fn parameterized
<F
: fmt
::Write
>(&mut self,
242 substs
: &subst
::Substs
,
244 projections
: &[ty
::ProjectionPredicate
])
246 let key
= ty
::tls
::with(|tcx
| tcx
.def_key(did
));
247 let mut item_name
= if let Some(name
) = key
.disambiguated_data
.data
.get_opt_name() {
250 did
.index
= key
.parent
.unwrap_or_else(
251 || bug
!("finding type for {:?}, encountered def-id {:?} with no parent",
253 self.parameterized(f
, substs
, did
, projections
)?
;
254 return write
!(f
, "::{}", key
.disambiguated_data
.data
.as_interned_str());
257 let verbose
= self.is_verbose
;
258 let mut num_supplied_defaults
= 0;
259 let mut has_self
= false;
260 let mut num_regions
= 0;
261 let mut num_types
= 0;
262 let mut is_value_path
= false;
263 let fn_trait_kind
= ty
::tls
::with(|tcx
| {
264 // Unfortunately, some kinds of items (e.g., closures) don't have
265 // generics. So walk back up the find the closest parent that DOES
267 let mut item_def_id
= did
;
269 let key
= tcx
.def_key(item_def_id
);
270 match key
.disambiguated_data
.data
{
271 DefPathData
::TypeNs(_
) => {
274 DefPathData
::ValueNs(_
) | DefPathData
::EnumVariant(_
) => {
275 is_value_path
= true;
279 // if we're making a symbol for something, there ought
280 // to be a value or type-def or something in there
282 item_def_id
.index
= key
.parent
.unwrap_or_else(|| {
283 bug
!("finding type for {:?}, encountered def-id {:?} with no \
284 parent", did
, item_def_id
);
289 let mut generics
= tcx
.generics_of(item_def_id
);
290 let mut path_def_id
= did
;
291 has_self
= generics
.has_self
;
293 let mut child_types
= 0;
294 if let Some(def_id
) = generics
.parent
{
296 assert
!(is_value_path
);
297 child_types
= generics
.types
.len();
298 generics
= tcx
.generics_of(def_id
);
299 num_regions
= generics
.regions
.len();
300 num_types
= generics
.types
.len();
303 print
!(f
, self, write("<"), print_display(substs
.type_at(0)), write(" as "))?
;
306 path_def_id
= def_id
;
312 assert_eq
!(has_self
, false);
315 num_regions
= generics
.regions
.len();
316 num_types
= generics
.types
.len();
321 if generics
.types
.last().map_or(false, |def
| def
.has_default
) {
322 if let Some(substs
) = tcx
.lift(&substs
) {
323 let tps
= substs
.types().rev().skip(child_types
);
324 for (def
, actual
) in generics
.types
.iter().rev().zip(tps
) {
325 if !def
.has_default
{
328 if tcx
.type_of(def
.def_id
).subst(tcx
, substs
) != actual
{
331 num_supplied_defaults
+= 1;
337 print
!(f
, self, write("{}", tcx
.item_path_str(path_def_id
)))?
;
338 Ok(tcx
.lang_items().fn_trait_kind(path_def_id
))
341 if !verbose
&& fn_trait_kind
.is_some() && projections
.len() == 1 {
342 let projection_ty
= projections
[0].ty
;
343 if let TyTuple(ref args
, _
) = substs
.type_at(1).sty
{
344 return self.fn_sig(f
, args
, false, projection_ty
);
348 let empty
= Cell
::new(true);
349 let start_or_continue
= |f
: &mut F
, start
: &str, cont
: &str| {
352 write
!(f
, "{}", start
)
354 write
!(f
, "{}", cont
)
358 let print_regions
= |f
: &mut F
, start
: &str, skip
, count
| {
359 // Don't print any regions if they're all erased.
360 let regions
= || substs
.regions().skip(skip
).take(count
);
361 if regions().all(|r
: ty
::Region
| *r
== ty
::ReErased
) {
365 for region
in regions() {
366 let region
: ty
::Region
= region
;
367 start_or_continue(f
, start
, ", ")?
;
369 write
!(f
, "{:?}", region
)?
;
371 let s
= region
.to_string();
373 // This happens when the value of the region
374 // parameter is not easily serialized. This may be
375 // because the user omitted it in the first place,
376 // or because it refers to some block in the code,
377 // etc. I'm not sure how best to serialize this.
388 print_regions(f
, "<", 0, num_regions
)?
;
390 let tps
= substs
.types().take(num_types
- num_supplied_defaults
)
391 .skip(has_self
as usize);
394 start_or_continue(f
, "<", ", ")?
;
395 ty
.print_display(f
, self)?
;
398 for projection
in projections
{
399 start_or_continue(f
, "<", ", ")?
;
403 tcx
.associated_item(projection
.projection_ty
.item_def_id
).name
),
404 print_display(projection
.ty
))
408 start_or_continue(f
, "", ">")?
;
410 // For values, also print their name and type parameters.
418 if let Some(item_name
) = item_name
{
419 write
!(f
, "::{}", item_name
)?
;
422 print_regions(f
, "::<", num_regions
, usize::MAX
)?
;
424 // FIXME: consider being smart with defaults here too
425 for ty
in substs
.types().skip(num_types
) {
426 start_or_continue(f
, "::<", ", ")?
;
427 ty
.print_display(f
, self)?
;
430 start_or_continue(f
, "", ">")?
;
436 fn in_binder
<'a
, 'gcx
, 'tcx
, T
, U
, F
>(&mut self,
438 tcx
: TyCtxt
<'a
, 'gcx
, 'tcx
>,
439 original
: &ty
::Binder
<T
>,
440 lifted
: Option
<ty
::Binder
<U
>>) -> fmt
::Result
441 where T
: Print
, U
: Print
+ TypeFoldable
<'tcx
>, F
: fmt
::Write
443 fn name_by_region_index(index
: usize) -> Symbol
{
445 0 => Symbol
::intern("'r"),
446 1 => Symbol
::intern("'s"),
447 i
=> Symbol
::intern(&format
!("'t{}", i
-2)),
451 // Replace any anonymous late-bound regions with named
452 // variants, using gensym'd identifiers, so that we can
453 // clearly differentiate between named and unnamed regions in
454 // the output. We'll probably want to tweak this over time to
455 // decide just how much information to give.
456 let value
= if let Some(v
) = lifted
{
459 return original
.0.print_display(f
, self);
462 if self.binder_depth
== 0 {
463 self.prepare_late_bound_region_info(&value
);
466 let mut empty
= true;
467 let mut start_or_continue
= |f
: &mut F
, start
: &str, cont
: &str| {
470 write
!(f
, "{}", start
)
472 write
!(f
, "{}", cont
)
476 let old_region_index
= self.region_index
;
477 let mut region_index
= old_region_index
;
478 let new_value
= tcx
.replace_late_bound_regions(&value
, |br
| {
479 let _
= start_or_continue(f
, "for<", ", ");
481 ty
::BrNamed(_
, name
) => {
482 let _
= write
!(f
, "{}", name
);
489 let name
= name_by_region_index(region_index
);
491 if !self.is_name_used(&name
) {
495 let _
= write
!(f
, "{}", name
);
496 ty
::BrNamed(tcx
.hir
.local_def_id(CRATE_NODE_ID
),
500 tcx
.mk_region(ty
::ReLateBound(ty
::DebruijnIndex
::new(1), br
))
502 start_or_continue(f
, "", "> ")?
;
504 // Push current state to gcx, and restore after writing new_value.
505 self.binder_depth
+= 1;
506 self.region_index
= region_index
;
507 let result
= new_value
.print_display(f
, self);
508 self.region_index
= old_region_index
;
509 self.binder_depth
-= 1;
513 fn is_name_used(&self, name
: &Symbol
) -> bool
{
514 match self.used_region_names
{
515 Some(ref names
) => names
.contains(name
),
521 pub fn verbose() -> bool
{
522 ty
::tls
::with(|tcx
| tcx
.sess
.verbose())
525 pub fn identify_regions() -> bool
{
526 ty
::tls
::with(|tcx
| tcx
.sess
.opts
.debugging_opts
.identify_regions
)
529 pub fn parameterized
<F
: fmt
::Write
>(f
: &mut F
,
530 substs
: &subst
::Substs
,
532 projections
: &[ty
::ProjectionPredicate
])
534 PrintContext
::new().parameterized(f
, substs
, did
, projections
)
538 impl<'a
, T
: Print
> Print
for &'a T
{
539 fn print
<F
: fmt
::Write
>(&self, f
: &mut F
, cx
: &mut PrintContext
) -> fmt
::Result
{
545 ('tcx
) &'tcx ty
::Slice
<ty
::ExistentialPredicate
<'tcx
>>, (self, f
, cx
) {
547 // Generate the main trait ref, including associated types.
548 ty
::tls
::with(|tcx
| {
549 // Use a type that can't appear in defaults of type parameters.
550 let dummy_self
= tcx
.mk_infer(ty
::FreshTy(0));
552 if let Some(p
) = self.principal() {
553 let principal
= tcx
.lift(&p
).expect("could not lift TraitRef for printing")
554 .with_self_ty(tcx
, dummy_self
);
555 let projections
= self.projection_bounds().map(|p
| {
557 .expect("could not lift projection for printing")
558 .with_self_ty(tcx
, dummy_self
)
559 }).collect
::<Vec
<_
>>();
560 cx
.parameterized(f
, principal
.substs
, principal
.def_id
, &projections
)?
;
564 for did
in self.auto_traits() {
565 write
!(f
, " + {}", tcx
.item_path_str(did
))?
;
576 impl fmt
::Debug
for ty
::TypeParameterDef
{
577 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
578 write
!(f
, "TypeParameterDef({}, {:?}, {})",
585 impl fmt
::Debug
for ty
::RegionParameterDef
{
586 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
587 write
!(f
, "RegionParameterDef({}, {:?}, {})",
594 impl fmt
::Debug
for ty
::TraitDef
{
595 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
596 ty
::tls
::with(|tcx
| {
597 write
!(f
, "{}", tcx
.item_path_str(self.def_id
))
602 impl fmt
::Debug
for ty
::AdtDef
{
603 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
604 ty
::tls
::with(|tcx
| {
605 write
!(f
, "{}", tcx
.item_path_str(self.did
))
610 impl<'tcx
> fmt
::Debug
for ty
::ClosureUpvar
<'tcx
> {
611 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
612 write
!(f
, "ClosureUpvar({:?},{:?})",
618 impl fmt
::Debug
for ty
::UpvarId
{
619 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
620 write
!(f
, "UpvarId({:?};`{}`;{:?})",
622 ty
::tls
::with(|tcx
| tcx
.hir
.name(tcx
.hir
.hir_to_node_id(self.var_id
))),
623 self.closure_expr_id
)
627 impl<'tcx
> fmt
::Debug
for ty
::UpvarBorrow
<'tcx
> {
628 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
629 write
!(f
, "UpvarBorrow({:?}, {:?})",
630 self.kind
, self.region
)
635 ('tcx
) ty
::TypeAndMut
<'tcx
>, (self, f
, cx
) {
638 write("{}", if self.mutbl
== hir
::MutMutable { "mut " }
else { "" }
),
645 ('tcx
) ty
::ExistentialTraitRef
<'tcx
>, (self, f
, cx
) {
647 ty
::tls
::with(|tcx
| {
648 let dummy_self
= tcx
.mk_infer(ty
::FreshTy(0));
650 let trait_ref
= tcx
.lift(&ty
::Binder(*self))
651 .expect("could not lift TraitRef for printing")
652 .with_self_ty(tcx
, dummy_self
).0;
653 cx
.parameterized(f
, trait_ref
.substs
, trait_ref
.def_id
, &[])
660 ('tcx
) ty
::adjustment
::Adjustment
<'tcx
>, (self, f
, cx
) {
662 print
!(f
, cx
, write("{:?} -> ", self.kind
), print(self.target
))
668 () ty
::BoundRegion
, (self, f
, cx
) {
671 return self.print_debug(f
, cx
);
675 BrNamed(_
, name
) => write
!(f
, "{}", name
),
676 BrAnon(_
) | BrFresh(_
) | BrEnv
=> Ok(())
681 BrAnon(n
) => write
!(f
, "BrAnon({:?})", n
),
682 BrFresh(n
) => write
!(f
, "BrFresh({:?})", n
),
683 BrNamed(did
, name
) => {
684 write
!(f
, "BrNamed({:?}:{:?}, {:?})",
685 did
.krate
, did
.index
, name
)
687 BrEnv
=> write
!(f
, "BrEnv"),
694 () ty
::RegionKind
, (self, f
, cx
) {
697 return self.print_debug(f
, cx
);
700 // These printouts are concise. They do not contain all the information
701 // the user might want to diagnose an error, but there is basically no way
702 // to fit that into a short string. Hence the recommendation to use
703 // `explain_region()` or `note_and_explain_region()`.
705 ty
::ReEarlyBound(ref data
) => {
706 write
!(f
, "{}", data
.name
)
708 ty
::ReLateBound(_
, br
) |
709 ty
::ReFree(ty
::FreeRegion { bound_region: br, .. }
) |
710 ty
::ReSkolemized(_
, br
) => {
713 ty
::ReScope(scope
) if cx
.identify_regions
=> {
715 region
::ScopeData
::Node(id
) =>
716 write
!(f
, "'{}s", id
.as_usize()),
717 region
::ScopeData
::CallSite(id
) =>
718 write
!(f
, "'{}cs", id
.as_usize()),
719 region
::ScopeData
::Arguments(id
) =>
720 write
!(f
, "'{}as", id
.as_usize()),
721 region
::ScopeData
::Destruction(id
) =>
722 write
!(f
, "'{}ds", id
.as_usize()),
723 region
::ScopeData
::Remainder(BlockRemainder
724 { block, first_statement_index }
) =>
725 write
!(f
, "'{}_{}rs", block
.as_usize(), first_statement_index
.index()),
728 ty
::ReVar(region_vid
) if cx
.identify_regions
=> {
729 write
!(f
, "'{}rv", region_vid
.index
)
733 ty
::ReErased
=> Ok(()),
734 ty
::ReStatic
=> write
!(f
, "'static"),
735 ty
::ReEmpty
=> write
!(f
, "'<empty>"),
740 ty
::ReEarlyBound(ref data
) => {
741 write
!(f
, "ReEarlyBound({}, {})",
746 ty
::ReLateBound(binder_id
, ref bound_region
) => {
747 write
!(f
, "ReLateBound({:?}, {:?})",
752 ty
::ReFree(ref fr
) => write
!(f
, "{:?}", fr
),
755 write
!(f
, "ReScope({:?})", id
)
758 ty
::ReStatic
=> write
!(f
, "ReStatic"),
760 ty
::ReVar(ref vid
) => {
761 write
!(f
, "{:?}", vid
)
764 ty
::ReSkolemized(id
, ref bound_region
) => {
765 write
!(f
, "ReSkolemized({}, {:?})", id
.index
, bound_region
)
768 ty
::ReEmpty
=> write
!(f
, "ReEmpty"),
770 ty
::ReErased
=> write
!(f
, "ReErased")
777 () ty
::FreeRegion
, (self, f
, cx
) {
779 write
!(f
, "ReFree({:?}, {:?})", self.scope
, self.bound_region
)
785 () ty
::Variance
, (self, f
, cx
) {
787 f
.write_str(match *self {
788 ty
::Covariant
=> "+",
789 ty
::Contravariant
=> "-",
790 ty
::Invariant
=> "o",
791 ty
::Bivariant
=> "*",
798 ('tcx
) ty
::GenericPredicates
<'tcx
>, (self, f
, cx
) {
800 write
!(f
, "GenericPredicates({:?})", self.predicates
)
806 ('tcx
) ty
::InstantiatedPredicates
<'tcx
>, (self, f
, cx
) {
808 write
!(f
, "InstantiatedPredicates({:?})", self.predicates
)
814 ('tcx
) ty
::FnSig
<'tcx
>, (self, f
, cx
) {
816 if self.unsafety
== hir
::Unsafety
::Unsafe
{
817 write
!(f
, "unsafe ")?
;
820 if self.abi
!= Abi
::Rust
{
821 write
!(f
, "extern {} ", self.abi
)?
;
825 cx
.fn_sig(f
, self.inputs(), self.variadic
, self.output())
828 write
!(f
, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic
, self.output())
833 impl fmt
::Debug
for ty
::TyVid
{
834 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
835 write
!(f
, "_#{}t", self.index
)
839 impl fmt
::Debug
for ty
::IntVid
{
840 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
841 write
!(f
, "_#{}i", self.index
)
845 impl fmt
::Debug
for ty
::FloatVid
{
846 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
847 write
!(f
, "_#{}f", self.index
)
851 impl fmt
::Debug
for ty
::RegionVid
{
852 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
853 write
!(f
, "'_#{}r", self.index
)
858 () ty
::InferTy
, (self, f
, cx
) {
861 ty
::TyVar(_
) => write
!(f
, "_"),
862 ty
::IntVar(_
) => write
!(f
, "{}", "{integer}"),
863 ty
::FloatVar(_
) => write
!(f
, "{}", "{float}"),
864 ty
::FreshTy(v
) => write
!(f
, "FreshTy({})", v
),
865 ty
::FreshIntTy(v
) => write
!(f
, "FreshIntTy({})", v
),
866 ty
::FreshFloatTy(v
) => write
!(f
, "FreshFloatTy({})", v
)
871 ty
::TyVar(ref v
) => write
!(f
, "{:?}", v
),
872 ty
::IntVar(ref v
) => write
!(f
, "{:?}", v
),
873 ty
::FloatVar(ref v
) => write
!(f
, "{:?}", v
),
874 ty
::FreshTy(v
) => write
!(f
, "FreshTy({:?})", v
),
875 ty
::FreshIntTy(v
) => write
!(f
, "FreshIntTy({:?})", v
),
876 ty
::FreshFloatTy(v
) => write
!(f
, "FreshFloatTy({:?})", v
)
882 impl fmt
::Debug
for ty
::IntVarValue
{
883 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
885 ty
::IntType(ref v
) => v
.fmt(f
),
886 ty
::UintType(ref v
) => v
.fmt(f
),
891 // The generic impl doesn't work yet because projections are not
892 // normalized under HRTB.
893 /*impl<T> fmt::Display for ty::Binder<T>
894 where T: fmt::Display + for<'a> ty::Lift<'a>,
895 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
897 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
898 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
902 define_print_multi
! {
904 ('tcx
) ty
::Binder
<&'tcx ty
::Slice
<ty
::ExistentialPredicate
<'tcx
>>>,
905 ('tcx
) ty
::Binder
<ty
::TraitRef
<'tcx
>>,
906 ('tcx
) ty
::Binder
<ty
::FnSig
<'tcx
>>,
907 ('tcx
) ty
::Binder
<ty
::TraitPredicate
<'tcx
>>,
908 ('tcx
) ty
::Binder
<ty
::EquatePredicate
<'tcx
>>,
909 ('tcx
) ty
::Binder
<ty
::SubtypePredicate
<'tcx
>>,
910 ('tcx
) ty
::Binder
<ty
::ProjectionPredicate
<'tcx
>>,
911 ('tcx
) ty
::Binder
<ty
::OutlivesPredicate
<Ty
<'tcx
>, ty
::Region
<'tcx
>>>,
912 ('tcx
) ty
::Binder
<ty
::OutlivesPredicate
<ty
::Region
<'tcx
>, ty
::Region
<'tcx
>>>
916 ty
::tls
::with(|tcx
| cx
.in_binder(f
, tcx
, self, tcx
.lift(self)))
922 ('tcx
) ty
::TraitRef
<'tcx
>, (self, f
, cx
) {
924 cx
.parameterized(f
, self.substs
, self.def_id
, &[])
927 // when printing out the debug representation, we don't need
928 // to enumerate the `for<...>` etc because the debruijn index
929 // tells you everything you need to know.
932 print(self.self_ty()),
934 cx
.parameterized(f
, self.substs
, self.def_id
, &[])?
;
941 ('tcx
) ty
::GeneratorInterior
<'tcx
>, (self, f
, cx
) {
943 self.witness
.print(f
, cx
)
949 ('tcx
) ty
::TypeVariants
<'tcx
>, (self, f
, cx
) {
952 TyBool
=> write
!(f
, "bool"),
953 TyChar
=> write
!(f
, "char"),
954 TyInt(t
) => write
!(f
, "{}", t
.ty_to_string()),
955 TyUint(t
) => write
!(f
, "{}", t
.ty_to_string()),
956 TyFloat(t
) => write
!(f
, "{}", t
.ty_to_string()),
957 TyRawPtr(ref tm
) => {
958 write
!(f
, "*{} ", match tm
.mutbl
{
959 hir
::MutMutable
=> "mut",
960 hir
::MutImmutable
=> "const",
964 TyRef(r
, ref tm
) => {
966 let s
= r
.print_to_string(cx
);
973 TyNever
=> write
!(f
, "!"),
974 TyTuple(ref tys
, _
) => {
976 let mut tys
= tys
.iter();
977 if let Some(&ty
) = tys
.next() {
978 print
!(f
, cx
, print(ty
), write(","))?
;
979 if let Some(&ty
) = tys
.next() {
980 print
!(f
, cx
, write(" "), print(ty
))?
;
982 print
!(f
, cx
, write(", "), print(ty
))?
;
988 TyFnDef(def_id
, substs
) => {
989 ty
::tls
::with(|tcx
| {
990 let mut sig
= tcx
.fn_sig(def_id
);
991 if let Some(substs
) = tcx
.lift(&substs
) {
992 sig
= sig
.subst(tcx
, substs
);
994 print
!(f
, cx
, print(sig
), write(" {{"))
996 cx
.parameterized(f
, substs
, def_id
, &[])?
;
999 TyFnPtr(ref bare_fn
) => {
1000 bare_fn
.print(f
, cx
)
1002 TyInfer(infer_ty
) => write
!(f
, "{}", infer_ty
),
1003 TyError
=> write
!(f
, "[type error]"),
1004 TyParam(ref param_ty
) => write
!(f
, "{}", param_ty
),
1005 TyAdt(def
, substs
) => cx
.parameterized(f
, substs
, def
.did
, &[]),
1006 TyDynamic(data
, r
) => {
1008 let r
= r
.print_to_string(cx
);
1010 write
!(f
, " + {}", r
)
1015 TyForeign(def_id
) => parameterized(f
, subst
::Substs
::empty(), def_id
, &[]),
1016 TyProjection(ref data
) => data
.print(f
, cx
),
1017 TyAnon(def_id
, substs
) => {
1018 ty
::tls
::with(|tcx
| {
1019 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
1020 // by looking up the projections associated with the def_id.
1021 let predicates_of
= tcx
.predicates_of(def_id
);
1022 let substs
= tcx
.lift(&substs
).unwrap_or_else(|| {
1023 tcx
.intern_substs(&[])
1025 let bounds
= predicates_of
.instantiate(tcx
, substs
);
1027 let mut first
= true;
1028 let mut is_sized
= false;
1030 for predicate
in bounds
.predicates
{
1031 if let Some(trait_ref
) = predicate
.to_opt_poly_trait_ref() {
1032 // Don't print +Sized, but rather +?Sized if absent.
1033 if Some(trait_ref
.def_id()) == tcx
.lang_items().sized_trait() {
1039 write("{}", if first { " " }
else { "+" }
),
1045 write
!(f
, "{}?Sized", if first { " " }
else { "+" }
)?
;
1050 TyStr
=> write
!(f
, "str"),
1051 TyGenerator(did
, substs
, interior
) => ty
::tls
::with(|tcx
| {
1052 let upvar_tys
= substs
.upvar_tys(did
, tcx
);
1053 write
!(f
, "[generator")?
;
1055 if let Some(node_id
) = tcx
.hir
.as_local_node_id(did
) {
1056 write
!(f
, "@{:?}", tcx
.hir
.span(node_id
))?
;
1058 tcx
.with_freevars(node_id
, |freevars
| {
1059 for (freevar
, upvar_ty
) in freevars
.iter().zip(upvar_tys
) {
1063 tcx
.hir
.name(freevar
.var_id())),
1070 // cross-crate closure types should only be
1071 // visible in trans bug reports, I imagine.
1072 write
!(f
, "@{:?}", did
)?
;
1074 for (index
, upvar_ty
) in upvar_tys
.enumerate() {
1076 write("{}{}:", sep
, index
),
1082 print
!(f
, cx
, write(" "), print(interior
), write("]"))
1084 TyClosure(did
, substs
) => ty
::tls
::with(|tcx
| {
1085 let upvar_tys
= substs
.upvar_tys(did
, tcx
);
1086 write
!(f
, "[closure")?
;
1088 if let Some(node_id
) = tcx
.hir
.as_local_node_id(did
) {
1089 if tcx
.sess
.opts
.debugging_opts
.span_free_formats
{
1090 write
!(f
, "@{:?}", node_id
)?
;
1092 write
!(f
, "@{:?}", tcx
.hir
.span(node_id
))?
;
1095 tcx
.with_freevars(node_id
, |freevars
| {
1096 for (freevar
, upvar_ty
) in freevars
.iter().zip(upvar_tys
) {
1100 tcx
.hir
.name(freevar
.var_id())),
1107 // cross-crate closure types should only be
1108 // visible in trans bug reports, I imagine.
1109 write
!(f
, "@{:?}", did
)?
;
1111 for (index
, upvar_ty
) in upvar_tys
.enumerate() {
1113 write("{}{}:", sep
, index
),
1121 TyArray(ty
, sz
) => {
1122 print
!(f
, cx
, write("["), print(ty
), write("; "))?
;
1124 ConstVal
::Integral(ConstInt
::Usize(sz
)) => {
1125 write
!(f
, "{}", sz
)?
;
1127 ConstVal
::Unevaluated(_def_id
, substs
) => {
1128 write
!(f
, "<unevaluated{:?}>", &substs
[..])?
;
1131 write
!(f
, "{:?}", sz
)?
;
1137 print
!(f
, cx
, write("["), print(ty
), write("]"))
1145 ('tcx
) ty
::TyS
<'tcx
>, (self, f
, cx
) {
1147 self.sty
.print(f
, cx
)
1150 self.sty
.print_display(f
, cx
)
1156 () ty
::ParamTy
, (self, f
, cx
) {
1158 write
!(f
, "{}", self.name
)
1161 write
!(f
, "{}/#{}", self.name
, self.idx
)
1167 ('tcx
, T
: Print
+ fmt
::Debug
, U
: Print
+ fmt
::Debug
) ty
::OutlivesPredicate
<T
, U
>,
1170 print
!(f
, cx
, print(self.0), write(" : "), print(self.1))
1176 ('tcx
) ty
::EquatePredicate
<'tcx
>, (self, f
, cx
) {
1178 print
!(f
, cx
, print(self.0), write(" == "), print(self.1))
1184 ('tcx
) ty
::SubtypePredicate
<'tcx
>, (self, f
, cx
) {
1186 print
!(f
, cx
, print(self.a
), write(" <: "), print(self.b
))
1192 ('tcx
) ty
::TraitPredicate
<'tcx
>, (self, f
, cx
) {
1194 write
!(f
, "TraitPredicate({:?})",
1198 print
!(f
, cx
, print(self.trait_ref
.self_ty()), write(": "), print(self.trait_ref
))
1204 ('tcx
) ty
::ProjectionPredicate
<'tcx
>, (self, f
, cx
) {
1207 write("ProjectionPredicate("),
1208 print(self.projection_ty
),
1214 print
!(f
, cx
, print(self.projection_ty
), write(" == "), print(self.ty
))
1220 ('tcx
) ty
::ProjectionTy
<'tcx
>, (self, f
, cx
) {
1222 // FIXME(tschottdorf): use something like
1223 // parameterized(f, self.substs, self.item_def_id, &[])
1224 // (which currently ICEs).
1225 let (trait_ref
, item_name
) = ty
::tls
::with(|tcx
|
1226 (self.trait_ref(tcx
), tcx
.associated_item(self.item_def_id
).name
)
1228 print
!(f
, cx
, print_debug(trait_ref
), write("::{}", item_name
))
1234 () ty
::ClosureKind
, (self, f
, cx
) {
1237 ty
::ClosureKind
::Fn
=> write
!(f
, "Fn"),
1238 ty
::ClosureKind
::FnMut
=> write
!(f
, "FnMut"),
1239 ty
::ClosureKind
::FnOnce
=> write
!(f
, "FnOnce"),
1246 ('tcx
) ty
::Predicate
<'tcx
>, (self, f
, cx
) {
1249 ty
::Predicate
::Trait(ref data
) => data
.print(f
, cx
),
1250 ty
::Predicate
::Equate(ref predicate
) => predicate
.print(f
, cx
),
1251 ty
::Predicate
::Subtype(ref predicate
) => predicate
.print(f
, cx
),
1252 ty
::Predicate
::RegionOutlives(ref predicate
) => predicate
.print(f
, cx
),
1253 ty
::Predicate
::TypeOutlives(ref predicate
) => predicate
.print(f
, cx
),
1254 ty
::Predicate
::Projection(ref predicate
) => predicate
.print(f
, cx
),
1255 ty
::Predicate
::WellFormed(ty
) => print
!(f
, cx
, print(ty
), write(" well-formed")),
1256 ty
::Predicate
::ObjectSafe(trait_def_id
) =>
1257 ty
::tls
::with(|tcx
| {
1258 write
!(f
, "the trait `{}` is object-safe", tcx
.item_path_str(trait_def_id
))
1260 ty
::Predicate
::ClosureKind(closure_def_id
, kind
) =>
1261 ty
::tls
::with(|tcx
| {
1262 write
!(f
, "the closure `{}` implements the trait `{}`",
1263 tcx
.item_path_str(closure_def_id
), kind
)
1265 ty
::Predicate
::ConstEvaluatable(def_id
, substs
) => {
1266 write
!(f
, "the constant `")?
;
1267 cx
.parameterized(f
, substs
, def_id
, &[])?
;
1268 write
!(f
, "` can be evaluated")
1274 ty
::Predicate
::Trait(ref a
) => a
.print(f
, cx
),
1275 ty
::Predicate
::Equate(ref pair
) => pair
.print(f
, cx
),
1276 ty
::Predicate
::Subtype(ref pair
) => pair
.print(f
, cx
),
1277 ty
::Predicate
::RegionOutlives(ref pair
) => pair
.print(f
, cx
),
1278 ty
::Predicate
::TypeOutlives(ref pair
) => pair
.print(f
, cx
),
1279 ty
::Predicate
::Projection(ref pair
) => pair
.print(f
, cx
),
1280 ty
::Predicate
::WellFormed(ty
) => ty
.print(f
, cx
),
1281 ty
::Predicate
::ObjectSafe(trait_def_id
) => {
1282 write
!(f
, "ObjectSafe({:?})", trait_def_id
)
1284 ty
::Predicate
::ClosureKind(closure_def_id
, kind
) => {
1285 write
!(f
, "ClosureKind({:?}, {:?})", closure_def_id
, kind
)
1287 ty
::Predicate
::ConstEvaluatable(def_id
, substs
) => {
1288 write
!(f
, "ConstEvaluatable({:?}, {:?})", def_id
, substs
)