]> git.lizzy.rs Git - rust.git/blob - src/librustc/util/ppaux.rs
Use NodeId/HirId instead of DefId for local variables.
[rust.git] / src / librustc / util / ppaux.rs
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.
4 //
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.
10
11 use hir::def_id::DefId;
12 use hir::map::definitions::DefPathData;
13 use middle::region::{self, BlockRemainder};
14 use ty::subst::{self, Subst};
15 use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
16 use ty::{TyBool, TyChar, TyAdt};
17 use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
18 use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
19 use ty::{TyClosure, TyGenerator, TyProjection, TyAnon};
20 use ty::{TyDynamic, TyInt, TyUint, TyInfer};
21 use ty::{self, Ty, TyCtxt, TypeFoldable};
22
23 use std::cell::Cell;
24 use std::fmt;
25 use std::usize;
26
27 use syntax::abi::Abi;
28 use syntax::ast::CRATE_NODE_ID;
29 use syntax::symbol::Symbol;
30 use hir;
31
32 pub fn verbose() -> bool {
33     ty::tls::with(|tcx| tcx.sess.verbose())
34 }
35
36 pub fn identify_regions() -> bool {
37     ty::tls::with(|tcx| tcx.sess.opts.debugging_opts.identify_regions)
38 }
39
40 fn fn_sig(f: &mut fmt::Formatter,
41           inputs: &[Ty],
42           variadic: bool,
43           output: Ty)
44           -> fmt::Result {
45     write!(f, "(")?;
46     let mut inputs = inputs.iter();
47     if let Some(&ty) = inputs.next() {
48         write!(f, "{}", ty)?;
49         for &ty in inputs {
50             write!(f, ", {}", ty)?;
51         }
52         if variadic {
53             write!(f, ", ...")?;
54         }
55     }
56     write!(f, ")")?;
57     if !output.is_nil() {
58         write!(f, " -> {}", output)?;
59     }
60
61     Ok(())
62 }
63
64 pub fn parameterized(f: &mut fmt::Formatter,
65                      substs: &subst::Substs,
66                      mut did: DefId,
67                      projections: &[ty::ProjectionPredicate])
68                      -> fmt::Result {
69     let key = ty::tls::with(|tcx| tcx.def_key(did));
70     let mut item_name = if let Some(name) = key.disambiguated_data.data.get_opt_name() {
71         Some(name)
72     } else {
73         did.index = key.parent.unwrap_or_else(
74             || bug!("finding type for {:?}, encountered def-id {:?} with no parent",
75                     did, did));
76         parameterized(f, substs, did, projections)?;
77         return write!(f, "::{}", key.disambiguated_data.data.as_interned_str());
78     };
79
80     let mut verbose = false;
81     let mut num_supplied_defaults = 0;
82     let mut has_self = false;
83     let mut num_regions = 0;
84     let mut num_types = 0;
85     let mut is_value_path = false;
86     let fn_trait_kind = ty::tls::with(|tcx| {
87         // Unfortunately, some kinds of items (e.g., closures) don't have
88         // generics. So walk back up the find the closest parent that DOES
89         // have them.
90         let mut item_def_id = did;
91         loop {
92             let key = tcx.def_key(item_def_id);
93             match key.disambiguated_data.data {
94                 DefPathData::TypeNs(_) => {
95                     break;
96                 }
97                 DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => {
98                     is_value_path = true;
99                     break;
100                 }
101                 _ => {
102                     // if we're making a symbol for something, there ought
103                     // to be a value or type-def or something in there
104                     // *somewhere*
105                     item_def_id.index = key.parent.unwrap_or_else(|| {
106                         bug!("finding type for {:?}, encountered def-id {:?} with no \
107                              parent", did, item_def_id);
108                     });
109                 }
110             }
111         }
112         let mut generics = tcx.generics_of(item_def_id);
113         let mut path_def_id = did;
114         verbose = tcx.sess.verbose();
115         has_self = generics.has_self;
116
117         let mut child_types = 0;
118         if let Some(def_id) = generics.parent {
119             // Methods.
120             assert!(is_value_path);
121             child_types = generics.types.len();
122             generics = tcx.generics_of(def_id);
123             num_regions = generics.regions.len();
124             num_types = generics.types.len();
125
126             if has_self {
127                 write!(f, "<{} as ", substs.type_at(0))?;
128             }
129
130             path_def_id = def_id;
131         } else {
132             item_name = None;
133
134             if is_value_path {
135                 // Functions.
136                 assert_eq!(has_self, false);
137             } else {
138                 // Types and traits.
139                 num_regions = generics.regions.len();
140                 num_types = generics.types.len();
141             }
142         }
143
144         if !verbose {
145             if generics.types.last().map_or(false, |def| def.has_default) {
146                 if let Some(substs) = tcx.lift(&substs) {
147                     let tps = substs.types().rev().skip(child_types);
148                     for (def, actual) in generics.types.iter().rev().zip(tps) {
149                         if !def.has_default {
150                             break;
151                         }
152                         if tcx.type_of(def.def_id).subst(tcx, substs) != actual {
153                             break;
154                         }
155                         num_supplied_defaults += 1;
156                     }
157                 }
158             }
159         }
160
161         write!(f, "{}", tcx.item_path_str(path_def_id))?;
162         Ok(tcx.lang_items().fn_trait_kind(path_def_id))
163     })?;
164
165     if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
166         let projection_ty = projections[0].ty;
167         if let TyTuple(ref args, _) = substs.type_at(1).sty {
168             return fn_sig(f, args, false, projection_ty);
169         }
170     }
171
172     let empty = Cell::new(true);
173     let start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
174         if empty.get() {
175             empty.set(false);
176             write!(f, "{}", start)
177         } else {
178             write!(f, "{}", cont)
179         }
180     };
181
182     let print_regions = |f: &mut fmt::Formatter, start: &str, skip, count| {
183         // Don't print any regions if they're all erased.
184         let regions = || substs.regions().skip(skip).take(count);
185         if regions().all(|r: ty::Region| *r == ty::ReErased) {
186             return Ok(());
187         }
188
189         for region in regions() {
190             let region: ty::Region = region;
191             start_or_continue(f, start, ", ")?;
192             if verbose {
193                 write!(f, "{:?}", region)?;
194             } else {
195                 let s = region.to_string();
196                 if s.is_empty() {
197                     // This happens when the value of the region
198                     // parameter is not easily serialized. This may be
199                     // because the user omitted it in the first place,
200                     // or because it refers to some block in the code,
201                     // etc. I'm not sure how best to serialize this.
202                     write!(f, "'_")?;
203                 } else {
204                     write!(f, "{}", s)?;
205                 }
206             }
207         }
208
209         Ok(())
210     };
211
212     print_regions(f, "<", 0, num_regions)?;
213
214     let tps = substs.types().take(num_types - num_supplied_defaults)
215                             .skip(has_self as usize);
216
217     for ty in tps {
218         start_or_continue(f, "<", ", ")?;
219         write!(f, "{}", ty)?;
220     }
221
222     for projection in projections {
223         start_or_continue(f, "<", ", ")?;
224         ty::tls::with(|tcx|
225             write!(f, "{}={}",
226             tcx.associated_item(projection.projection_ty.item_def_id).name,
227             projection.ty)
228         )?;
229     }
230
231     start_or_continue(f, "", ">")?;
232
233     // For values, also print their name and type parameters.
234     if is_value_path {
235         empty.set(true);
236
237         if has_self {
238             write!(f, ">")?;
239         }
240
241         if let Some(item_name) = item_name {
242             write!(f, "::{}", item_name)?;
243         }
244
245         print_regions(f, "::<", num_regions, usize::MAX)?;
246
247         // FIXME: consider being smart with defaults here too
248         for ty in substs.types().skip(num_types) {
249             start_or_continue(f, "::<", ", ")?;
250             write!(f, "{}", ty)?;
251         }
252
253         start_or_continue(f, "", ">")?;
254     }
255
256     Ok(())
257 }
258
259 fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter,
260                                    tcx: TyCtxt<'a, 'gcx, 'tcx>,
261                                    original: &ty::Binder<T>,
262                                    lifted: Option<ty::Binder<U>>) -> fmt::Result
263     where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
264 {
265     // Replace any anonymous late-bound regions with named
266     // variants, using gensym'd identifiers, so that we can
267     // clearly differentiate between named and unnamed regions in
268     // the output. We'll probably want to tweak this over time to
269     // decide just how much information to give.
270     let value = if let Some(v) = lifted {
271         v
272     } else {
273         return write!(f, "{}", original.0);
274     };
275
276     let mut empty = true;
277     let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
278         if empty {
279             empty = false;
280             write!(f, "{}", start)
281         } else {
282             write!(f, "{}", cont)
283         }
284     };
285
286     let new_value = tcx.replace_late_bound_regions(&value, |br| {
287         let _ = start_or_continue(f, "for<", ", ");
288         let br = match br {
289             ty::BrNamed(_, name) => {
290                 let _ = write!(f, "{}", name);
291                 br
292             }
293             ty::BrAnon(_) |
294             ty::BrFresh(_) |
295             ty::BrEnv => {
296                 let name = Symbol::intern("'r");
297                 let _ = write!(f, "{}", name);
298                 ty::BrNamed(tcx.hir.local_def_id(CRATE_NODE_ID),
299                             name)
300             }
301         };
302         tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::new(1), br))
303     }).0;
304
305     start_or_continue(f, "", "> ")?;
306     write!(f, "{}", new_value)
307 }
308
309 impl<'tcx> fmt::Display for &'tcx ty::Slice<ty::ExistentialPredicate<'tcx>> {
310     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
311         // Generate the main trait ref, including associated types.
312         ty::tls::with(|tcx| {
313             // Use a type that can't appear in defaults of type parameters.
314             let dummy_self = tcx.mk_infer(ty::FreshTy(0));
315
316             if let Some(p) = self.principal() {
317                 let principal = tcx.lift(&p).expect("could not lift TraitRef for printing")
318                     .with_self_ty(tcx, dummy_self);
319                 let projections = self.projection_bounds().map(|p| {
320                     tcx.lift(&p)
321                         .expect("could not lift projection for printing")
322                         .with_self_ty(tcx, dummy_self)
323                 }).collect::<Vec<_>>();
324                 parameterized(f, principal.substs, principal.def_id, &projections)?;
325             }
326
327             // Builtin bounds.
328             for did in self.auto_traits() {
329                 write!(f, " + {}", tcx.item_path_str(did))?;
330             }
331
332             Ok(())
333         })?;
334
335         Ok(())
336     }
337 }
338
339 impl fmt::Debug for ty::TypeParameterDef {
340     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341         write!(f, "TypeParameterDef({}, {:?}, {})",
342                self.name,
343                self.def_id,
344                self.index)
345     }
346 }
347
348 impl fmt::Debug for ty::RegionParameterDef {
349     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350         write!(f, "RegionParameterDef({}, {:?}, {})",
351                self.name,
352                self.def_id,
353                self.index)
354     }
355 }
356
357 impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
358     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
359         write!(f, "{}", *self)
360     }
361 }
362
363 impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
364     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
365         write!(f, "{}{}",
366                if self.mutbl == hir::MutMutable { "mut " } else { "" },
367                self.ty)
368     }
369 }
370
371 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
372     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
373         // when printing out the debug representation, we don't need
374         // to enumerate the `for<...>` etc because the debruijn index
375         // tells you everything you need to know.
376         write!(f, "<{:?} as {}>", self.self_ty(), *self)
377     }
378 }
379
380 impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
381     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
382         ty::tls::with(|tcx| {
383             let dummy_self = tcx.mk_infer(ty::FreshTy(0));
384
385             let trait_ref = tcx.lift(&ty::Binder(*self))
386                                .expect("could not lift TraitRef for printing")
387                                .with_self_ty(tcx, dummy_self).0;
388             parameterized(f, trait_ref.substs, trait_ref.def_id, &[])
389         })
390     }
391 }
392
393 impl fmt::Debug for ty::TraitDef {
394     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395         ty::tls::with(|tcx| {
396             write!(f, "{}", tcx.item_path_str(self.def_id))
397         })
398     }
399 }
400
401 impl fmt::Debug for ty::AdtDef {
402     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
403         ty::tls::with(|tcx| {
404             write!(f, "{}", tcx.item_path_str(self.did))
405         })
406     }
407 }
408
409 impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
410     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
411         write!(f, "{:?} -> {}", self.kind, self.target)
412     }
413 }
414
415 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
416     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
417         match *self {
418             ty::Predicate::Trait(ref a) => write!(f, "{:?}", a),
419             ty::Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
420             ty::Predicate::Subtype(ref pair) => write!(f, "{:?}", pair),
421             ty::Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
422             ty::Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
423             ty::Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
424             ty::Predicate::WellFormed(ty) => write!(f, "WF({:?})", ty),
425             ty::Predicate::ObjectSafe(trait_def_id) => {
426                 write!(f, "ObjectSafe({:?})", trait_def_id)
427             }
428             ty::Predicate::ClosureKind(closure_def_id, kind) => {
429                 write!(f, "ClosureKind({:?}, {:?})", closure_def_id, kind)
430             }
431         }
432     }
433 }
434
435 impl fmt::Display for ty::BoundRegion {
436     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
437         if verbose() {
438             return write!(f, "{:?}", *self);
439         }
440
441         match *self {
442             BrNamed(_, name) => write!(f, "{}", name),
443             BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
444         }
445     }
446 }
447
448 impl fmt::Debug for ty::BoundRegion {
449     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
450         match *self {
451             BrAnon(n) => write!(f, "BrAnon({:?})", n),
452             BrFresh(n) => write!(f, "BrFresh({:?})", n),
453             BrNamed(did, name) => {
454                 write!(f, "BrNamed({:?}:{:?}, {:?})",
455                        did.krate, did.index, name)
456             }
457             BrEnv => "BrEnv".fmt(f),
458         }
459     }
460 }
461
462 impl fmt::Debug for ty::RegionKind {
463     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
464         match *self {
465             ty::ReEarlyBound(ref data) => {
466                 write!(f, "ReEarlyBound({}, {})",
467                        data.index,
468                        data.name)
469             }
470
471             ty::ReLateBound(binder_id, ref bound_region) => {
472                 write!(f, "ReLateBound({:?}, {:?})",
473                        binder_id,
474                        bound_region)
475             }
476
477             ty::ReFree(ref fr) => write!(f, "{:?}", fr),
478
479             ty::ReScope(id) => {
480                 write!(f, "ReScope({:?})", id)
481             }
482
483             ty::ReStatic => write!(f, "ReStatic"),
484
485             ty::ReVar(ref vid) => {
486                 write!(f, "{:?}", vid)
487             }
488
489             ty::ReSkolemized(id, ref bound_region) => {
490                 write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
491             }
492
493             ty::ReEmpty => write!(f, "ReEmpty"),
494
495             ty::ReErased => write!(f, "ReErased")
496         }
497     }
498 }
499
500 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
501     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
502         write!(f, "ClosureUpvar({:?},{:?})",
503                self.def,
504                self.ty)
505     }
506 }
507
508 impl fmt::Display for ty::RegionKind {
509     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
510         if verbose() {
511             return write!(f, "{:?}", *self);
512         }
513
514         // These printouts are concise.  They do not contain all the information
515         // the user might want to diagnose an error, but there is basically no way
516         // to fit that into a short string.  Hence the recommendation to use
517         // `explain_region()` or `note_and_explain_region()`.
518         match *self {
519             ty::ReEarlyBound(ref data) => {
520                 write!(f, "{}", data.name)
521             }
522             ty::ReLateBound(_, br) |
523             ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
524             ty::ReSkolemized(_, br) => {
525                 write!(f, "{}", br)
526             }
527             ty::ReScope(scope) if identify_regions() => {
528                 match scope {
529                     region::Scope::Node(id) =>
530                         write!(f, "'{}s", id.as_usize()),
531                     region::Scope::CallSite(id) =>
532                         write!(f, "'{}cs", id.as_usize()),
533                     region::Scope::Arguments(id) =>
534                         write!(f, "'{}as", id.as_usize()),
535                     region::Scope::Destruction(id) =>
536                         write!(f, "'{}ds", id.as_usize()),
537                     region::Scope::Remainder(BlockRemainder { block, first_statement_index }) =>
538                         write!(f, "'{}_{}rs", block.as_usize(), first_statement_index),
539                 }
540             }
541             ty::ReVar(region_vid) if identify_regions() => {
542                 write!(f, "'{}rv", region_vid.index)
543             }
544             ty::ReScope(_) |
545             ty::ReVar(_) |
546             ty::ReErased => Ok(()),
547             ty::ReStatic => write!(f, "'static"),
548             ty::ReEmpty => write!(f, "'<empty>"),
549         }
550     }
551 }
552
553 impl fmt::Debug for ty::FreeRegion {
554     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
555         write!(f, "ReFree({:?}, {:?})",
556                self.scope, self.bound_region)
557     }
558 }
559
560 impl fmt::Debug for ty::Variance {
561     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
562         f.write_str(match *self {
563             ty::Covariant => "+",
564             ty::Contravariant => "-",
565             ty::Invariant => "o",
566             ty::Bivariant => "*",
567         })
568     }
569 }
570
571 impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
572     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
573         write!(f, "GenericPredicates({:?})", self.predicates)
574     }
575 }
576
577 impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
578     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
579         write!(f, "InstantiatedPredicates({:?})",
580                self.predicates)
581     }
582 }
583
584 impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
585     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
586         if self.unsafety == hir::Unsafety::Unsafe {
587             write!(f, "unsafe ")?;
588         }
589
590         if self.abi != Abi::Rust {
591             write!(f, "extern {} ", self.abi)?;
592         }
593
594         write!(f, "fn")?;
595         fn_sig(f, self.inputs(), self.variadic, self.output())
596     }
597 }
598
599 impl fmt::Debug for ty::TyVid {
600     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
601         write!(f, "_#{}t", self.index)
602     }
603 }
604
605 impl fmt::Debug for ty::IntVid {
606     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
607         write!(f, "_#{}i", self.index)
608     }
609 }
610
611 impl fmt::Debug for ty::FloatVid {
612     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
613         write!(f, "_#{}f", self.index)
614     }
615 }
616
617 impl fmt::Debug for ty::RegionVid {
618     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
619         write!(f, "'_#{}r", self.index)
620     }
621 }
622
623 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
624     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
625         write!(f, "({:?}; variadic: {})->{:?}", self.inputs(), self.variadic, self.output())
626     }
627 }
628
629 impl fmt::Debug for ty::InferTy {
630     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
631         match *self {
632             ty::TyVar(ref v) => v.fmt(f),
633             ty::IntVar(ref v) => v.fmt(f),
634             ty::FloatVar(ref v) => v.fmt(f),
635             ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
636             ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
637             ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
638         }
639     }
640 }
641
642 impl fmt::Debug for ty::IntVarValue {
643     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
644         match *self {
645             ty::IntType(ref v) => v.fmt(f),
646             ty::UintType(ref v) => v.fmt(f),
647         }
648     }
649 }
650
651 // The generic impl doesn't work yet because projections are not
652 // normalized under HRTB.
653 /*impl<T> fmt::Display for ty::Binder<T>
654     where T: fmt::Display + for<'a> ty::Lift<'a>,
655           for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
656 {
657     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
658         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
659     }
660 }*/
661
662 impl<'tcx> fmt::Display for ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>> {
663     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
664         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
665     }
666 }
667
668 impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
669     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
670         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
671     }
672 }
673
674 impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
675     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
676         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
677     }
678 }
679
680 impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
681     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
682         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
683     }
684 }
685
686 impl<'tcx> fmt::Display for ty::Binder<ty::SubtypePredicate<'tcx>> {
687     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
688         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
689     }
690 }
691
692 impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
693     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
694         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
695     }
696 }
697
698 impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
699     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
700         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
701     }
702 }
703
704 impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>,
705                                                              ty::Region<'tcx>>> {
706     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
707         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
708     }
709 }
710
711 impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
712     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
713         parameterized(f, self.substs, self.def_id, &[])
714     }
715 }
716
717 impl<'tcx> fmt::Display for ty::GeneratorInterior<'tcx> {
718     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
719         self.witness.fmt(f)
720     }
721 }
722
723 impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
724     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
725         match *self {
726             TyBool => write!(f, "bool"),
727             TyChar => write!(f, "char"),
728             TyInt(t) => write!(f, "{}", t.ty_to_string()),
729             TyUint(t) => write!(f, "{}", t.ty_to_string()),
730             TyFloat(t) => write!(f, "{}", t.ty_to_string()),
731             TyRawPtr(ref tm) => {
732                 write!(f, "*{} {}", match tm.mutbl {
733                     hir::MutMutable => "mut",
734                     hir::MutImmutable => "const",
735                 },  tm.ty)
736             }
737             TyRef(r, ref tm) => {
738                 write!(f, "&")?;
739                 let s = r.to_string();
740                 write!(f, "{}", s)?;
741                 if !s.is_empty() {
742                     write!(f, " ")?;
743                 }
744                 write!(f, "{}", tm)
745             }
746             TyNever => write!(f, "!"),
747             TyTuple(ref tys, _) => {
748                 write!(f, "(")?;
749                 let mut tys = tys.iter();
750                 if let Some(&ty) = tys.next() {
751                     write!(f, "{},", ty)?;
752                     if let Some(&ty) = tys.next() {
753                         write!(f, " {}", ty)?;
754                         for &ty in tys {
755                             write!(f, ", {}", ty)?;
756                         }
757                     }
758                 }
759                 write!(f, ")")
760             }
761             TyFnDef(def_id, substs) => {
762                 ty::tls::with(|tcx| {
763                     let mut sig = tcx.fn_sig(def_id);
764                     if let Some(substs) = tcx.lift(&substs) {
765                         sig = sig.subst(tcx, substs);
766                     }
767                     write!(f, "{} {{", sig.0)
768                 })?;
769                 parameterized(f, substs, def_id, &[])?;
770                 write!(f, "}}")
771             }
772             TyFnPtr(ref bare_fn) => {
773                 write!(f, "{}", bare_fn.0)
774             }
775             TyInfer(infer_ty) => write!(f, "{}", infer_ty),
776             TyError => write!(f, "[type error]"),
777             TyParam(ref param_ty) => write!(f, "{}", param_ty),
778             TyAdt(def, substs) => parameterized(f, substs, def.did, &[]),
779             TyDynamic(data, r) => {
780                 write!(f, "{}", data)?;
781                 let r = r.to_string();
782                 if !r.is_empty() {
783                     write!(f, " + {}", r)
784                 } else {
785                     Ok(())
786                 }
787             }
788             TyProjection(ref data) => write!(f, "{}", data),
789             TyAnon(def_id, substs) => {
790                 ty::tls::with(|tcx| {
791                     // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
792                     // by looking up the projections associated with the def_id.
793                     let predicates_of = tcx.predicates_of(def_id);
794                     let substs = tcx.lift(&substs).unwrap_or_else(|| {
795                         tcx.intern_substs(&[])
796                     });
797                     let bounds = predicates_of.instantiate(tcx, substs);
798
799                     let mut first = true;
800                     let mut is_sized = false;
801                     write!(f, "impl")?;
802                     for predicate in bounds.predicates {
803                         if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
804                             // Don't print +Sized, but rather +?Sized if absent.
805                             if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
806                                 is_sized = true;
807                                 continue;
808                             }
809
810                             write!(f, "{}{}", if first { " " } else { "+" }, trait_ref)?;
811                             first = false;
812                         }
813                     }
814                     if !is_sized {
815                         write!(f, "{}?Sized", if first { " " } else { "+" })?;
816                     }
817                     Ok(())
818                 })
819             }
820             TyStr => write!(f, "str"),
821             TyGenerator(did, substs, interior) => ty::tls::with(|tcx| {
822                 let upvar_tys = substs.upvar_tys(did, tcx);
823                 write!(f, "[generator")?;
824
825                 if let Some(node_id) = tcx.hir.as_local_node_id(did) {
826                     write!(f, "@{:?}", tcx.hir.span(node_id))?;
827                     let mut sep = " ";
828                     tcx.with_freevars(node_id, |freevars| {
829                         for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
830                             write!(f,
831                                         "{}{}:{}",
832                                         sep,
833                                         tcx.hir.name(freevar.var_id()),
834                                         upvar_ty)?;
835                             sep = ", ";
836                         }
837                         Ok(())
838                     })?
839                 } else {
840                     // cross-crate closure types should only be
841                     // visible in trans bug reports, I imagine.
842                     write!(f, "@{:?}", did)?;
843                     let mut sep = " ";
844                     for (index, upvar_ty) in upvar_tys.enumerate() {
845                         write!(f, "{}{}:{}", sep, index, upvar_ty)?;
846                         sep = ", ";
847                     }
848                 }
849
850                 write!(f, " {}", interior)?;
851
852                 write!(f, "]")
853             }),
854             TyClosure(did, substs) => ty::tls::with(|tcx| {
855                 let upvar_tys = substs.upvar_tys(did, tcx);
856                 write!(f, "[closure")?;
857
858                 if let Some(node_id) = tcx.hir.as_local_node_id(did) {
859                     if tcx.sess.opts.debugging_opts.span_free_formats {
860                         write!(f, "@{:?}", node_id)?;
861                     } else {
862                         write!(f, "@{:?}", tcx.hir.span(node_id))?;
863                     }
864                     let mut sep = " ";
865                     tcx.with_freevars(node_id, |freevars| {
866                         for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) {
867                             write!(f,
868                                         "{}{}:{}",
869                                         sep,
870                                         tcx.hir.name(freevar.var_id()),
871                                         upvar_ty)?;
872                             sep = ", ";
873                         }
874                         Ok(())
875                     })?
876                 } else {
877                     // cross-crate closure types should only be
878                     // visible in trans bug reports, I imagine.
879                     write!(f, "@{:?}", did)?;
880                     let mut sep = " ";
881                     for (index, upvar_ty) in upvar_tys.enumerate() {
882                         write!(f, "{}{}:{}", sep, index, upvar_ty)?;
883                         sep = ", ";
884                     }
885                 }
886
887                 write!(f, "]")
888             }),
889             TyArray(ty, sz) => write!(f, "[{}; {}]",  ty, sz),
890             TySlice(ty) => write!(f, "[{}]",  ty)
891         }
892     }
893 }
894
895 impl<'tcx> fmt::Display for ty::TyS<'tcx> {
896     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
897         write!(f, "{}", self.sty)
898     }
899 }
900
901 impl fmt::Debug for ty::UpvarId {
902     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
903         write!(f, "UpvarId({:?};`{}`;{:?})",
904                self.var_id,
905                ty::tls::with(|tcx| tcx.hir.name(tcx.hir.hir_to_node_id(self.var_id))),
906                self.closure_expr_id)
907     }
908 }
909
910 impl<'tcx> fmt::Debug for ty::UpvarBorrow<'tcx> {
911     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
912         write!(f, "UpvarBorrow({:?}, {:?})",
913                self.kind, self.region)
914     }
915 }
916
917 impl fmt::Display for ty::InferTy {
918     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
919         let print_var_ids = verbose();
920         match *self {
921             ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
922             ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
923             ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
924             ty::TyVar(_) => write!(f, "_"),
925             ty::IntVar(_) => write!(f, "{}", "{integer}"),
926             ty::FloatVar(_) => write!(f, "{}", "{float}"),
927             ty::FreshTy(v) => write!(f, "FreshTy({})", v),
928             ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
929             ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
930         }
931     }
932 }
933
934 impl fmt::Display for ty::ParamTy {
935     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
936         write!(f, "{}", self.name)
937     }
938 }
939
940 impl fmt::Debug for ty::ParamTy {
941     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
942         write!(f, "{}/#{}", self, self.idx)
943     }
944 }
945
946 impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate<T,U>
947     where T: fmt::Display, U: fmt::Display
948 {
949     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
950         write!(f, "{} : {}", self.0, self.1)
951     }
952 }
953
954 impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> {
955     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
956         write!(f, "{} == {}", self.0, self.1)
957     }
958 }
959
960 impl<'tcx> fmt::Display for ty::SubtypePredicate<'tcx> {
961     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
962         write!(f, "{} <: {}", self.a, self.b)
963     }
964 }
965
966 impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
967     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
968         write!(f, "TraitPredicate({:?})",
969                self.trait_ref)
970     }
971 }
972
973 impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
974     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
975         write!(f, "{}: {}", self.trait_ref.self_ty(), self.trait_ref)
976     }
977 }
978
979 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
980     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
981         write!(f, "ProjectionPredicate({:?}, {:?})",
982                self.projection_ty,
983                self.ty)
984     }
985 }
986
987 impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
988     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
989         write!(f, "{} == {}",
990                self.projection_ty,
991                self.ty)
992     }
993 }
994
995 impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
996     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
997         // FIXME(tschottdorf): use something like
998         //   parameterized(f, self.substs, self.item_def_id, &[])
999         // (which currently ICEs).
1000         let (trait_ref, item_name) = ty::tls::with(|tcx|
1001             (self.trait_ref(tcx), tcx.associated_item(self.item_def_id).name)
1002         );
1003         write!(f, "{:?}::{}",
1004                trait_ref,
1005                item_name)
1006     }
1007 }
1008
1009 impl fmt::Display for ty::ClosureKind {
1010     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1011         match *self {
1012             ty::ClosureKind::Fn => write!(f, "Fn"),
1013             ty::ClosureKind::FnMut => write!(f, "FnMut"),
1014             ty::ClosureKind::FnOnce => write!(f, "FnOnce"),
1015         }
1016     }
1017 }
1018
1019 impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
1020     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1021         match *self {
1022             ty::Predicate::Trait(ref data) => write!(f, "{}", data),
1023             ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
1024             ty::Predicate::Subtype(ref predicate) => write!(f, "{}", predicate),
1025             ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
1026             ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
1027             ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
1028             ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty),
1029             ty::Predicate::ObjectSafe(trait_def_id) =>
1030                 ty::tls::with(|tcx| {
1031                     write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))
1032                 }),
1033             ty::Predicate::ClosureKind(closure_def_id, kind) =>
1034                 ty::tls::with(|tcx| {
1035                     write!(f, "the closure `{}` implements the trait `{}`",
1036                            tcx.item_path_str(closure_def_id), kind)
1037                 }),
1038         }
1039     }
1040 }