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