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