]> git.lizzy.rs Git - rust.git/blob - src/librustc/util/ppaux.rs
Remove unused imports
[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
12 use middle::def_id::DefId;
13 use middle::subst::{self, Subst};
14 use middle::ty::{BrAnon, BrEnv, BrFresh, BrNamed};
15 use middle::ty::{TyBool, TyChar, TyStruct, TyEnum};
16 use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn};
17 use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple};
18 use middle::ty::TyClosure;
19 use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
20 use middle::ty::{self, Ty, HasTypeFlags};
21 use middle::ty::fold::TypeFoldable;
22
23 use std::fmt;
24 use syntax::{abi};
25 use syntax::parse::token;
26 use syntax::ast::CRATE_NODE_ID;
27 use rustc_front::hir;
28
29 pub fn verbose() -> bool {
30     ty::tls::with(|tcx| tcx.sess.verbose())
31 }
32
33 fn fn_sig(f: &mut fmt::Formatter,
34           inputs: &[Ty],
35           variadic: bool,
36           output: ty::FnOutput)
37           -> fmt::Result {
38     try!(write!(f, "("));
39     let mut inputs = inputs.iter();
40     if let Some(&ty) = inputs.next() {
41         try!(write!(f, "{}", ty));
42         for &ty in inputs {
43             try!(write!(f, ", {}", ty));
44         }
45         if variadic {
46             try!(write!(f, ", ..."));
47         }
48     }
49     try!(write!(f, ")"));
50
51     match output {
52         ty::FnConverging(ty) => {
53             if !ty.is_nil() {
54                 try!(write!(f, " -> {}", ty));
55             }
56             Ok(())
57         }
58         ty::FnDiverging => {
59             write!(f, " -> !")
60         }
61     }
62 }
63
64 fn parameterized<GG>(f: &mut fmt::Formatter,
65                      substs: &subst::Substs,
66                      did: DefId,
67                      projections: &[ty::ProjectionPredicate],
68                      get_generics: GG)
69                      -> fmt::Result
70     where GG: for<'tcx> FnOnce(&ty::ctxt<'tcx>) -> ty::Generics<'tcx>
71 {
72     let (fn_trait_kind, verbose) = try!(ty::tls::with(|tcx| {
73         try!(write!(f, "{}", tcx.item_path_str(did)));
74         Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose()))
75     }));
76
77     let mut empty = true;
78     let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
79         if empty {
80             empty = false;
81             write!(f, "{}", start)
82         } else {
83             write!(f, "{}", cont)
84         }
85     };
86
87     if verbose {
88         match substs.regions {
89             subst::ErasedRegions => {
90                 try!(start_or_continue(f, "<", ", "));
91                 try!(write!(f, ".."));
92             }
93             subst::NonerasedRegions(ref regions) => {
94                 for region in regions {
95                     try!(start_or_continue(f, "<", ", "));
96                     try!(write!(f, "{:?}", region));
97                 }
98             }
99         }
100         for &ty in &substs.types {
101             try!(start_or_continue(f, "<", ", "));
102             try!(write!(f, "{}", ty));
103         }
104         for projection in projections {
105             try!(start_or_continue(f, "<", ", "));
106             try!(write!(f, "{}={}",
107                         projection.projection_ty.item_name,
108                         projection.ty));
109         }
110         return start_or_continue(f, "", ">");
111     }
112
113     if fn_trait_kind.is_some() && projections.len() == 1 {
114         let projection_ty = projections[0].ty;
115         if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
116             return fn_sig(f, args, false, ty::FnConverging(projection_ty));
117         }
118     }
119
120     match substs.regions {
121         subst::ErasedRegions => { }
122         subst::NonerasedRegions(ref regions) => {
123             for &r in regions {
124                 try!(start_or_continue(f, "<", ", "));
125                 let s = r.to_string();
126                 if s.is_empty() {
127                     // This happens when the value of the region
128                     // parameter is not easily serialized. This may be
129                     // because the user omitted it in the first place,
130                     // or because it refers to some block in the code,
131                     // etc. I'm not sure how best to serialize this.
132                     try!(write!(f, "'_"));
133                 } else {
134                     try!(write!(f, "{}", s));
135                 }
136             }
137         }
138     }
139
140     // It is important to execute this conditionally, only if -Z
141     // verbose is false. Otherwise, debug logs can sometimes cause
142     // ICEs trying to fetch the generics early in the pipeline. This
143     // is kind of a hacky workaround in that -Z verbose is required to
144     // avoid those ICEs.
145     let tps = substs.types.get_slice(subst::TypeSpace);
146     let num_defaults = ty::tls::with(|tcx| {
147         let generics = get_generics(tcx);
148
149         let has_self = substs.self_ty().is_some();
150         let ty_params = generics.types.get_slice(subst::TypeSpace);
151         if ty_params.last().map_or(false, |def| def.default.is_some()) {
152             let substs = tcx.lift(&substs);
153             ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
154                 match def.default {
155                     Some(default) => {
156                         if !has_self && default.has_self_ty() {
157                             // In an object type, there is no `Self`, and
158                             // thus if the default value references Self,
159                             // the user will be required to give an
160                             // explicit value. We can't even do the
161                             // substitution below to check without causing
162                             // an ICE. (#18956).
163                             false
164                         } else {
165                             let default = tcx.lift(&default);
166                             substs.and_then(|substs| default.subst(tcx, substs)) == Some(actual)
167                         }
168                     }
169                     None => false
170                 }
171             }).count()
172         } else {
173             0
174         }
175     });
176
177     for &ty in &tps[..tps.len() - num_defaults] {
178         try!(start_or_continue(f, "<", ", "));
179         try!(write!(f, "{}", ty));
180     }
181
182     for projection in projections {
183         try!(start_or_continue(f, "<", ", "));
184         try!(write!(f, "{}={}",
185                     projection.projection_ty.item_name,
186                     projection.ty));
187     }
188
189     start_or_continue(f, "", ">")
190 }
191
192 fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
193                          tcx: &ty::ctxt<'tcx>,
194                          original: &ty::Binder<T>,
195                          lifted: Option<ty::Binder<U>>) -> fmt::Result
196     where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
197 {
198     // Replace any anonymous late-bound regions with named
199     // variants, using gensym'd identifiers, so that we can
200     // clearly differentiate between named and unnamed regions in
201     // the output. We'll probably want to tweak this over time to
202     // decide just how much information to give.
203     let value = if let Some(v) = lifted {
204         v
205     } else {
206         return write!(f, "{}", original.0);
207     };
208
209     let mut empty = true;
210     let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
211         if empty {
212             empty = false;
213             write!(f, "{}", start)
214         } else {
215             write!(f, "{}", cont)
216         }
217     };
218
219     let new_value = tcx.replace_late_bound_regions(&value, |br| {
220         let _ = start_or_continue(f, "for<", ", ");
221         ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
222             ty::BrNamed(_, name) => {
223                 let _ = write!(f, "{}", name);
224                 br
225             }
226             ty::BrAnon(_) |
227             ty::BrFresh(_) |
228             ty::BrEnv => {
229                 let name = token::intern("'r");
230                 let _ = write!(f, "{}", name);
231                 ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID), name)
232             }
233         })
234     }).0;
235
236     try!(start_or_continue(f, "", "> "));
237     write!(f, "{}", new_value)
238 }
239
240 /// This curious type is here to help pretty-print trait objects. In
241 /// a trait object, the projections are stored separately from the
242 /// main trait bound, but in fact we want to package them together
243 /// when printing out; they also have separate binders, but we want
244 /// them to share a binder when we print them out. (And the binder
245 /// pretty-printing logic is kind of clever and we don't want to
246 /// reproduce it.) So we just repackage up the structure somewhat.
247 ///
248 /// Right now there is only one trait in an object that can have
249 /// projection bounds, so we just stuff them altogether. But in
250 /// reality we should eventually sort things out better.
251 #[derive(Clone, Debug)]
252 struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
253
254 impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
255     fn fold_with<F:ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F)
256                                               -> TraitAndProjections<'tcx> {
257         TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder))
258     }
259 }
260
261 impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
262     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
263         let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
264         parameterized(f, trait_ref.substs,
265                       trait_ref.def_id,
266                       projection_bounds,
267                       |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
268     }
269 }
270
271 impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
272     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
273         let bounds = &self.bounds;
274
275         // Generate the main trait ref, including associated types.
276         try!(ty::tls::with(|tcx| {
277             let principal = tcx.lift(&self.principal.0)
278                                .expect("could not lift TraitRef for printing");
279             let projections = tcx.lift(&bounds.projection_bounds[..])
280                                  .expect("could not lift projections for printing");
281             let projections = projections.into_iter().map(|p| p.0).collect();
282
283             let tap = ty::Binder(TraitAndProjections(principal, projections));
284             in_binder(f, tcx, &ty::Binder(""), Some(tap))
285         }));
286
287         // Builtin bounds.
288         for bound in &bounds.builtin_bounds {
289             try!(write!(f, " + {:?}", bound));
290         }
291
292         // FIXME: It'd be nice to compute from context when this bound
293         // is implied, but that's non-trivial -- we'd perhaps have to
294         // use thread-local data of some kind? There are also
295         // advantages to just showing the region, since it makes
296         // people aware that it's there.
297         let bound = bounds.region_bound.to_string();
298         if !bound.is_empty() {
299             try!(write!(f, " + {}", bound));
300         }
301
302         Ok(())
303     }
304 }
305
306 impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
307     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
308         write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
309                self.name,
310                self.def_id,
311                self.space, self.index)
312     }
313 }
314
315 impl fmt::Debug for ty::RegionParameterDef {
316     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317         write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
318                self.name,
319                self.def_id,
320                self.space, self.index,
321                self.bounds)
322     }
323 }
324
325 impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
326     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
327         write!(f, "{}", *self)
328     }
329 }
330
331 impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
332     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
333         write!(f, "{}{}",
334                if self.mutbl == hir::MutMutable { "mut " } else { "" },
335                self.ty)
336     }
337 }
338
339 impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
340     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341         write!(f, "Substs[types={:?}, regions={:?}]",
342                self.types, self.regions)
343     }
344 }
345
346 impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
347     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
348         write!(f, "ItemSubsts({:?})", self.substs)
349     }
350 }
351
352 impl fmt::Debug for subst::RegionSubsts {
353     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
354         match *self {
355             subst::ErasedRegions => write!(f, "erased"),
356             subst::NonerasedRegions(ref regions) => write!(f, "{:?}", regions)
357         }
358     }
359 }
360
361 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
362     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
363         // when printing out the debug representation, we don't need
364         // to enumerate the `for<...>` etc because the debruijn index
365         // tells you everything you need to know.
366         match self.substs.self_ty() {
367             None => write!(f, "{}", *self),
368             Some(self_ty) => write!(f, "<{:?} as {}>", self_ty, *self)
369         }
370     }
371 }
372
373 impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
374     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
375         write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
376                self.generics, self.trait_ref)
377     }
378 }
379
380 impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
381     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
382         ty::tls::with(|tcx| {
383             write!(f, "{}", tcx.item_path_str(self.did))
384         })
385     }
386 }
387
388 impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
389     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
390         match *self {
391             ty::adjustment::AdjustReifyFnPointer => {
392                 write!(f, "AdjustReifyFnPointer")
393             }
394             ty::adjustment::AdjustUnsafeFnPointer => {
395                 write!(f, "AdjustUnsafeFnPointer")
396             }
397             ty::adjustment::AdjustDerefRef(ref data) => {
398                 write!(f, "{:?}", data)
399             }
400         }
401     }
402 }
403
404 impl<'tcx> fmt::Debug for ty::adjustment::AutoDerefRef<'tcx> {
405     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406         write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
407                self.autoderefs, self.unsize, self.autoref)
408     }
409 }
410
411 impl<'tcx> fmt::Debug for ty::TraitTy<'tcx> {
412     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
413         write!(f, "TraitTy({:?},{:?})",
414                self.principal,
415                self.bounds)
416     }
417 }
418
419 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
420     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
421         match *self {
422             ty::Predicate::Trait(ref a) => write!(f, "{:?}", a),
423             ty::Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
424             ty::Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
425             ty::Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
426             ty::Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
427             ty::Predicate::WellFormed(ty) => write!(f, "WF({:?})", ty),
428             ty::Predicate::ObjectSafe(trait_def_id) => {
429                 write!(f, "ObjectSafe({:?})", trait_def_id)
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({:?}, {:?})", did, name)
455             }
456             BrEnv => "BrEnv".fmt(f),
457         }
458     }
459 }
460
461 impl fmt::Debug for ty::Region {
462     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
463         match *self {
464             ty::ReEarlyBound(ref data) => {
465                 write!(f, "ReEarlyBound({:?}, {:?}, {}, {})",
466                        data.def_id,
467                        data.space,
468                        data.index,
469                        data.name)
470             }
471
472             ty::ReLateBound(binder_id, ref bound_region) => {
473                 write!(f, "ReLateBound({:?}, {:?})",
474                        binder_id,
475                        bound_region)
476             }
477
478             ty::ReFree(ref fr) => write!(f, "{:?}", fr),
479
480             ty::ReScope(id) => {
481                 write!(f, "ReScope({:?})", id)
482             }
483
484             ty::ReStatic => write!(f, "ReStatic"),
485
486             ty::ReVar(ref vid) => {
487                 write!(f, "{:?}", vid)
488             }
489
490             ty::ReSkolemized(id, ref bound_region) => {
491                 write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
492             }
493
494             ty::ReEmpty => write!(f, "ReEmpty")
495         }
496     }
497 }
498
499 impl<'tcx> fmt::Debug for ty::ClosureTy<'tcx> {
500     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
501         write!(f, "ClosureTy({},{:?},{})",
502                self.unsafety,
503                self.sig,
504                self.abi)
505     }
506 }
507
508 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
509     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
510         write!(f, "ClosureUpvar({:?},{:?})",
511                self.def,
512                self.ty)
513     }
514 }
515
516 impl<'a, 'tcx> fmt::Debug for ty::ParameterEnvironment<'a, 'tcx> {
517     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
518         write!(f, "ParameterEnvironment(\
519             free_substs={:?}, \
520             implicit_region_bound={:?}, \
521             caller_bounds={:?})",
522             self.free_substs,
523             self.implicit_region_bound,
524             self.caller_bounds)
525     }
526 }
527
528 impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault {
529     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
530         match *self {
531             ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
532             ty::ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
533             ty::ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
534         }
535     }
536 }
537
538 impl fmt::Display for ty::Region {
539     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
540         if verbose() {
541             return write!(f, "{:?}", *self);
542         }
543
544         // These printouts are concise.  They do not contain all the information
545         // the user might want to diagnose an error, but there is basically no way
546         // to fit that into a short string.  Hence the recommendation to use
547         // `explain_region()` or `note_and_explain_region()`.
548         match *self {
549             ty::ReEarlyBound(ref data) => {
550                 write!(f, "{}", data.name)
551             }
552             ty::ReLateBound(_, br) |
553             ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
554             ty::ReSkolemized(_, br) => {
555                 write!(f, "{}", br)
556             }
557             ty::ReScope(_) |
558             ty::ReVar(_) => Ok(()),
559             ty::ReStatic => write!(f, "'static"),
560             ty::ReEmpty => write!(f, "'<empty>"),
561         }
562     }
563 }
564
565 impl fmt::Debug for ty::FreeRegion {
566     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
567         write!(f, "ReFree({:?}, {:?})",
568                self.scope, self.bound_region)
569     }
570 }
571
572 impl fmt::Debug for ty::Variance {
573     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
574         f.write_str(match *self {
575             ty::Covariant => "+",
576             ty::Contravariant => "-",
577             ty::Invariant => "o",
578             ty::Bivariant => "*",
579         })
580     }
581 }
582
583 impl fmt::Debug for ty::ItemVariances {
584     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
585         write!(f, "ItemVariances(types={:?}, regions={:?})",
586                self.types, self.regions)
587     }
588 }
589
590 impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
591     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
592         write!(f, "GenericPredicates({:?})", self.predicates)
593     }
594 }
595
596 impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
597     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
598         write!(f, "InstantiatedPredicates({:?})",
599                self.predicates)
600     }
601 }
602
603 impl<'tcx> fmt::Debug for ty::ImplOrTraitItem<'tcx> {
604     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605         try!(write!(f, "ImplOrTraitItem("));
606         try!(match *self {
607             ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
608             ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
609             ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
610         });
611         write!(f, ")")
612     }
613 }
614
615 impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
616     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
617         try!(write!(f, "fn"));
618         fn_sig(f, &self.inputs, self.variadic, self.output)
619     }
620 }
621
622 impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
623     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
624         let mut empty = true;
625         let mut maybe_continue = |f: &mut fmt::Formatter| {
626             if empty {
627                 empty = false;
628                 Ok(())
629             } else {
630                 write!(f, " + ")
631             }
632         };
633
634         let region_str = format!("{:?}", self.region_bound);
635         if !region_str.is_empty() {
636             try!(maybe_continue(f));
637             try!(write!(f, "{}", region_str));
638         }
639
640         for bound in &self.builtin_bounds {
641             try!(maybe_continue(f));
642             try!(write!(f, "{:?}", bound));
643         }
644
645         for projection_bound in &self.projection_bounds {
646             try!(maybe_continue(f));
647             try!(write!(f, "{:?}", projection_bound));
648         }
649
650         Ok(())
651     }
652 }
653
654 impl fmt::Display for ty::BuiltinBounds {
655     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
656         let mut bounds = self.iter();
657         if let Some(bound) = bounds.next() {
658             try!(write!(f, "{:?}", bound));
659             for bound in bounds {
660                 try!(write!(f, " + {:?}", bound));
661             }
662         }
663         Ok(())
664     }
665 }
666
667 impl fmt::Debug for ty::TyVid {
668     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
669         write!(f, "_#{}t", self.index)
670     }
671 }
672
673 impl fmt::Debug for ty::IntVid {
674     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
675         write!(f, "_#{}i", self.index)
676     }
677 }
678
679 impl fmt::Debug for ty::FloatVid {
680     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
681         write!(f, "_#{}f", self.index)
682     }
683 }
684
685 impl fmt::Debug for ty::RegionVid {
686     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
687         write!(f, "'_#{}r", self.index)
688     }
689 }
690
691 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
692     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
693         write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
694     }
695 }
696
697 impl fmt::Debug for ty::InferTy {
698     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
699         match *self {
700             ty::TyVar(ref v) => v.fmt(f),
701             ty::IntVar(ref v) => v.fmt(f),
702             ty::FloatVar(ref v) => v.fmt(f),
703             ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
704             ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
705             ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
706         }
707     }
708 }
709
710 impl fmt::Debug for ty::IntVarValue {
711     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
712         match *self {
713             ty::IntType(ref v) => v.fmt(f),
714             ty::UintType(ref v) => v.fmt(f),
715         }
716     }
717 }
718
719 // The generic impl doesn't work yet because projections are not
720 // normalized under HRTB.
721 /*impl<T> fmt::Display for ty::Binder<T>
722     where T: fmt::Display + for<'a> ty::Lift<'a>,
723           for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
724 {
725     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
726         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
727     }
728 }*/
729
730 impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
731     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
732         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
733     }
734 }
735
736 impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
737     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
738         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
739     }
740 }
741
742 impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
743     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
744         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
745     }
746 }
747
748 impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
749     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
750         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
751     }
752 }
753
754 impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
755     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
756         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
757     }
758 }
759
760 impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
761     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
762         ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
763     }
764 }
765
766 impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
767     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
768         parameterized(f, self.substs, self.def_id, &[],
769                       |tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
770     }
771 }
772
773 impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
774     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
775         match *self {
776             TyBool => write!(f, "bool"),
777             TyChar => write!(f, "char"),
778             TyInt(t) => write!(f, "{}", t.ty_to_string()),
779             TyUint(t) => write!(f, "{}", t.ty_to_string()),
780             TyFloat(t) => write!(f, "{}", t.ty_to_string()),
781             TyBox(typ) => write!(f, "Box<{}>",  typ),
782             TyRawPtr(ref tm) => {
783                 write!(f, "*{} {}", match tm.mutbl {
784                     hir::MutMutable => "mut",
785                     hir::MutImmutable => "const",
786                 },  tm.ty)
787             }
788             TyRef(r, ref tm) => {
789                 try!(write!(f, "&"));
790                 let s = r.to_string();
791                 try!(write!(f, "{}", s));
792                 if !s.is_empty() {
793                     try!(write!(f, " "));
794                 }
795                 write!(f, "{}", tm)
796             }
797             TyTuple(ref tys) => {
798                 try!(write!(f, "("));
799                 let mut tys = tys.iter();
800                 if let Some(&ty) = tys.next() {
801                     try!(write!(f, "{},", ty));
802                     if let Some(&ty) = tys.next() {
803                         try!(write!(f, " {}", ty));
804                         for &ty in tys {
805                             try!(write!(f, ", {}", ty));
806                         }
807                     }
808                 }
809                 write!(f, ")")
810             }
811             TyBareFn(opt_def_id, ref bare_fn) => {
812                 if bare_fn.unsafety == hir::Unsafety::Unsafe {
813                     try!(write!(f, "unsafe "));
814                 }
815
816                 if bare_fn.abi != abi::Rust {
817                     try!(write!(f, "extern {} ", bare_fn.abi));
818                 }
819
820                 try!(write!(f, "{}", bare_fn.sig.0));
821
822                 if let Some(def_id) = opt_def_id {
823                     try!(write!(f, " {{{}}}", ty::tls::with(|tcx| {
824                         tcx.item_path_str(def_id)
825                     })));
826                 }
827                 Ok(())
828             }
829             TyInfer(infer_ty) => write!(f, "{}", infer_ty),
830             TyError => write!(f, "[type error]"),
831             TyParam(ref param_ty) => write!(f, "{}", param_ty),
832             TyEnum(def, substs) | TyStruct(def, substs) => {
833                 ty::tls::with(|tcx| {
834                     if def.did.is_local() &&
835                           !tcx.tcache.borrow().contains_key(&def.did) {
836                         write!(f, "{}<..>", tcx.item_path_str(def.did))
837                     } else {
838                         parameterized(f, substs, def.did, &[],
839                                       |tcx| tcx.lookup_item_type(def.did).generics)
840                     }
841                 })
842             }
843             TyTrait(ref data) => write!(f, "{}", data),
844             ty::TyProjection(ref data) => write!(f, "{}", data),
845             TyStr => write!(f, "str"),
846             TyClosure(did, ref substs) => ty::tls::with(|tcx| {
847                 try!(write!(f, "[closure"));
848
849                 if let Some(node_id) = tcx.map.as_local_node_id(did) {
850                     try!(write!(f, "@{:?}", tcx.map.span(node_id)));
851                     let mut sep = " ";
852                     try!(tcx.with_freevars(node_id, |freevars| {
853                         for (freevar, upvar_ty) in freevars.iter().zip(&substs.upvar_tys) {
854                             let node_id = freevar.def.var_id();
855                             try!(write!(f,
856                                         "{}{}:{}",
857                                         sep,
858                                         tcx.local_var_name_str(node_id),
859                                         upvar_ty));
860                             sep = ", ";
861                         }
862                         Ok(())
863                     }))
864                 } else {
865                     // cross-crate closure types should only be
866                     // visible in trans bug reports, I imagine.
867                     try!(write!(f, "@{:?}", did));
868                     let mut sep = " ";
869                     for (index, upvar_ty) in substs.upvar_tys.iter().enumerate() {
870                         try!(write!(f, "{}{}:{}", sep, index, upvar_ty));
871                         sep = ", ";
872                     }
873                 }
874
875                 write!(f, "]")
876             }),
877             TyArray(ty, sz) => write!(f, "[{}; {}]",  ty, sz),
878             TySlice(ty) => write!(f, "[{}]",  ty)
879         }
880     }
881 }
882
883 impl<'tcx> fmt::Display for ty::TyS<'tcx> {
884     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
885         write!(f, "{}", self.sty)
886     }
887 }
888
889 impl fmt::Debug for ty::UpvarId {
890     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
891         write!(f, "UpvarId({};`{}`;{})",
892                self.var_id,
893                ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
894                self.closure_expr_id)
895     }
896 }
897
898 impl fmt::Debug for ty::UpvarBorrow {
899     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
900         write!(f, "UpvarBorrow({:?}, {:?})",
901                self.kind, self.region)
902     }
903 }
904
905 impl fmt::Display for ty::InferTy {
906     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
907         let print_var_ids = verbose();
908         match *self {
909             ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
910             ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
911             ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
912             ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => write!(f, "_"),
913             ty::FreshTy(v) => write!(f, "FreshTy({})", v),
914             ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
915             ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
916         }
917     }
918 }
919
920 impl fmt::Display for ty::ExplicitSelfCategory {
921     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
922         f.write_str(match *self {
923             ty::StaticExplicitSelfCategory => "static",
924             ty::ByValueExplicitSelfCategory => "self",
925             ty::ByReferenceExplicitSelfCategory(_, hir::MutMutable) => {
926                 "&mut self"
927             }
928             ty::ByReferenceExplicitSelfCategory(_, hir::MutImmutable) => "&self",
929             ty::ByBoxExplicitSelfCategory => "Box<self>",
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.space, 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::Debug for ty::TraitPredicate<'tcx> {
961     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
962         write!(f, "TraitPredicate({:?})",
963                self.trait_ref)
964     }
965 }
966
967 impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
968     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
969         write!(f, "{} : {}",
970                self.trait_ref.self_ty(),
971                self.trait_ref)
972     }
973 }
974
975 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
976     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
977         write!(f, "ProjectionPredicate({:?}, {:?})",
978                self.projection_ty,
979                self.ty)
980     }
981 }
982
983 impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
984     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
985         write!(f, "{} == {}",
986                self.projection_ty,
987                self.ty)
988     }
989 }
990
991 impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
992     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
993         write!(f, "{:?}::{}",
994                self.trait_ref,
995                self.item_name)
996     }
997 }
998
999 impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
1000     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1001         match *self {
1002             ty::Predicate::Trait(ref data) => write!(f, "{}", data),
1003             ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
1004             ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
1005             ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
1006             ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
1007             ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty),
1008             ty::Predicate::ObjectSafe(trait_def_id) =>
1009                 ty::tls::with(|tcx| {
1010                     write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))
1011                 }),
1012         }
1013     }
1014 }