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