]> git.lizzy.rs Git - rust.git/blob - src/librustc/util/ppaux.rs
core: Fix size_hint for signed integer Range<T> iterators
[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;
13 use middle::region;
14 use middle::subst::{VecPerParamSpace,Subst};
15 use middle::subst;
16 use middle::ty::{BoundRegion, BrAnon, BrNamed};
17 use middle::ty::{ReEarlyBound, BrFresh, ctxt};
18 use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
19 use middle::ty::{ReSkolemized, ReVar, BrEnv};
20 use middle::ty::{mt, Ty, ParamTy};
21 use middle::ty::{ty_bool, ty_char, ty_struct, ty_enum};
22 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn};
23 use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup};
24 use middle::ty::ty_closure;
25 use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
26 use middle::ty;
27 use middle::ty_fold::TypeFoldable;
28
29 use std::collections::HashMap;
30 use std::collections::hash_state::HashState;
31 use std::hash::Hash;
32 use std::rc::Rc;
33 use syntax::abi;
34 use syntax::ast_map;
35 use syntax::codemap::{Span, Pos};
36 use syntax::parse::token;
37 use syntax::print::pprust;
38 use syntax::ptr::P;
39 use syntax::{ast, ast_util};
40 use syntax::owned_slice::OwnedSlice;
41
42 /// Produces a string suitable for debugging output.
43 pub trait Repr<'tcx> {
44     fn repr(&self, tcx: &ctxt<'tcx>) -> String;
45 }
46
47 /// Produces a string suitable for showing to the user.
48 pub trait UserString<'tcx> : Repr<'tcx> {
49     fn user_string(&self, tcx: &ctxt<'tcx>) -> String;
50 }
51
52 pub fn note_and_explain_region(cx: &ctxt,
53                                prefix: &str,
54                                region: ty::Region,
55                                suffix: &str) -> Option<Span> {
56     match explain_region_and_span(cx, region) {
57       (ref str, Some(span)) => {
58         cx.sess.span_note(
59             span,
60             &format!("{}{}{}", prefix, *str, suffix));
61         Some(span)
62       }
63       (ref str, None) => {
64         cx.sess.note(
65             &format!("{}{}{}", prefix, *str, suffix));
66         None
67       }
68     }
69 }
70
71 /// When a free region is associated with `item`, how should we describe the item in the error
72 /// message.
73 fn item_scope_tag(item: &ast::Item) -> &'static str {
74     match item.node {
75         ast::ItemImpl(..) => "impl",
76         ast::ItemStruct(..) => "struct",
77         ast::ItemEnum(..) => "enum",
78         ast::ItemTrait(..) => "trait",
79         ast::ItemFn(..) => "function body",
80         _ => "item"
81     }
82 }
83
84 pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
85                             -> (String, Option<Span>) {
86     return match region {
87       ReScope(scope) => {
88         let new_string;
89         let on_unknown_scope = || {
90           (format!("unknown scope: {:?}.  Please report a bug.", scope), None)
91         };
92         let span = match scope.span(&cx.map) {
93           Some(s) => s,
94           None => return on_unknown_scope(),
95         };
96         let tag = match cx.map.find(scope.node_id()) {
97           Some(ast_map::NodeBlock(_)) => "block",
98           Some(ast_map::NodeExpr(expr)) => match expr.node {
99               ast::ExprCall(..) => "call",
100               ast::ExprMethodCall(..) => "method call",
101               ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
102               ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) =>  "while let",
103               ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) =>  "for",
104               ast::ExprMatch(..) => "match",
105               _ => "expression",
106           },
107           Some(ast_map::NodeStmt(_)) => "statement",
108           Some(ast_map::NodeItem(it)) => item_scope_tag(&*it),
109           Some(_) | None => {
110             // this really should not happen
111             return on_unknown_scope();
112           }
113         };
114         let scope_decorated_tag = match scope {
115             region::CodeExtent::Misc(_) => tag,
116             region::CodeExtent::ParameterScope { .. } => {
117                 "scope of parameters for function"
118             }
119             region::CodeExtent::DestructionScope(_) => {
120                 new_string = format!("destruction scope surrounding {}", tag);
121                 &*new_string
122             }
123             region::CodeExtent::Remainder(r) => {
124                 new_string = format!("block suffix following statement {}",
125                                      r.first_statement_index);
126                 &*new_string
127             }
128         };
129         explain_span(cx, scope_decorated_tag, span)
130
131       }
132
133       ReFree(ref fr) => {
134         let prefix = match fr.bound_region {
135           BrAnon(idx) => {
136               format!("the anonymous lifetime #{} defined on", idx + 1)
137           }
138           BrFresh(_) => "an anonymous lifetime defined on".to_string(),
139           _ => {
140               format!("the lifetime {} as defined on",
141                       bound_region_ptr_to_string(cx, fr.bound_region))
142           }
143         };
144
145         match cx.map.find(fr.scope.node_id) {
146           Some(ast_map::NodeBlock(ref blk)) => {
147               let (msg, opt_span) = explain_span(cx, "block", blk.span);
148               (format!("{} {}", prefix, msg), opt_span)
149           }
150           Some(ast_map::NodeItem(it)) => {
151               let tag = item_scope_tag(&*it);
152               let (msg, opt_span) = explain_span(cx, tag, it.span);
153               (format!("{} {}", prefix, msg), opt_span)
154           }
155           Some(_) | None => {
156               // this really should not happen
157               (format!("{} unknown free region bounded by scope {:?}", prefix, fr.scope), None)
158           }
159         }
160       }
161
162       ReStatic => { ("the static lifetime".to_string(), None) }
163
164       ReEmpty => { ("the empty lifetime".to_string(), None) }
165
166       ReEarlyBound(ref data) => {
167         (format!("{}", token::get_name(data.name)), None)
168       }
169
170       // I believe these cases should not occur (except when debugging,
171       // perhaps)
172       ty::ReInfer(_) | ty::ReLateBound(..) => {
173         (format!("lifetime {:?}", region), None)
174       }
175     };
176
177     fn explain_span(cx: &ctxt, heading: &str, span: Span)
178                     -> (String, Option<Span>) {
179         let lo = cx.sess.codemap().lookup_char_pos_adj(span.lo);
180         (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
181          Some(span))
182     }
183 }
184
185 pub fn bound_region_ptr_to_string(cx: &ctxt, br: BoundRegion) -> String {
186     bound_region_to_string(cx, "", false, br)
187 }
188
189 pub fn bound_region_to_string(cx: &ctxt,
190                            prefix: &str, space: bool,
191                            br: BoundRegion) -> String {
192     let space_str = if space { " " } else { "" };
193
194     if cx.sess.verbose() {
195         return format!("{}{}{}", prefix, br.repr(cx), space_str)
196     }
197
198     match br {
199         BrNamed(_, name) => {
200             format!("{}{}{}", prefix, token::get_name(name), space_str)
201         }
202         BrAnon(_) | BrFresh(_) | BrEnv => prefix.to_string()
203     }
204 }
205
206 // In general, if you are giving a region error message,
207 // you should use `explain_region()` or, better yet,
208 // `note_and_explain_region()`
209 pub fn region_ptr_to_string(cx: &ctxt, region: Region) -> String {
210     region_to_string(cx, "&", true, region)
211 }
212
213 pub fn region_to_string(cx: &ctxt, prefix: &str, space: bool, region: Region) -> String {
214     let space_str = if space { " " } else { "" };
215
216     if cx.sess.verbose() {
217         return format!("{}{}{}", prefix, region.repr(cx), space_str)
218     }
219
220     // These printouts are concise.  They do not contain all the information
221     // the user might want to diagnose an error, but there is basically no way
222     // to fit that into a short string.  Hence the recommendation to use
223     // `explain_region()` or `note_and_explain_region()`.
224     match region {
225         ty::ReScope(_) => prefix.to_string(),
226         ty::ReEarlyBound(ref data) => {
227             token::get_name(data.name).to_string()
228         }
229         ty::ReLateBound(_, br) => bound_region_to_string(cx, prefix, space, br),
230         ty::ReFree(ref fr) => bound_region_to_string(cx, prefix, space, fr.bound_region),
231         ty::ReInfer(ReSkolemized(_, br)) => {
232             bound_region_to_string(cx, prefix, space, br)
233         }
234         ty::ReInfer(ReVar(_)) => prefix.to_string(),
235         ty::ReStatic => format!("{}'static{}", prefix, space_str),
236         ty::ReEmpty => format!("{}'<empty>{}", prefix, space_str),
237     }
238 }
239
240 pub fn mutability_to_string(m: ast::Mutability) -> String {
241     match m {
242         ast::MutMutable => "mut ".to_string(),
243         ast::MutImmutable => "".to_string(),
244     }
245 }
246
247 pub fn mt_to_string<'tcx>(cx: &ctxt<'tcx>, m: &mt<'tcx>) -> String {
248     format!("{}{}",
249         mutability_to_string(m.mutbl),
250         ty_to_string(cx, m.ty))
251 }
252
253 pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where
254     F: FnMut(&T) -> String,
255 {
256     let tstrs = ts.iter().map(f).collect::<Vec<String>>();
257     format!("[{}]", tstrs.connect(", "))
258 }
259
260 pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
261     fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
262                                opt_def_id: Option<ast::DefId>,
263                                unsafety: ast::Unsafety,
264                                abi: abi::Abi,
265                                ident: Option<ast::Ident>,
266                                sig: &ty::PolyFnSig<'tcx>)
267                                -> String {
268         let mut s = String::new();
269
270         match unsafety {
271             ast::Unsafety::Normal => {}
272             ast::Unsafety::Unsafe => {
273                 s.push_str(&unsafety.to_string());
274                 s.push(' ');
275             }
276         };
277
278         if abi != abi::Rust {
279             s.push_str(&format!("extern {} ", abi.to_string()));
280         };
281
282         s.push_str("fn");
283
284         match ident {
285             Some(i) => {
286                 s.push(' ');
287                 s.push_str(&token::get_ident(i));
288             }
289             _ => { }
290         }
291
292         push_sig_to_string(cx, &mut s, '(', ')', sig);
293
294         match opt_def_id {
295             Some(def_id) => {
296                 s.push_str(" {");
297                 let path_str = ty::item_path_str(cx, def_id);
298                 s.push_str(&path_str[..]);
299                 s.push_str("}");
300             }
301             None => { }
302         }
303
304         s
305     }
306
307     fn closure_to_string<'tcx>(cx: &ctxt<'tcx>, cty: &ty::ClosureTy<'tcx>) -> String {
308         let mut s = String::new();
309         s.push_str("[closure");
310         push_sig_to_string(cx, &mut s, '(', ')', &cty.sig);
311         s.push(']');
312         s
313     }
314
315     fn push_sig_to_string<'tcx>(cx: &ctxt<'tcx>,
316                                 s: &mut String,
317                                 bra: char,
318                                 ket: char,
319                                 sig: &ty::PolyFnSig<'tcx>) {
320         s.push(bra);
321         let strs = sig.0.inputs
322             .iter()
323             .map(|a| ty_to_string(cx, *a))
324             .collect::<Vec<_>>();
325         s.push_str(&strs.connect(", "));
326         if sig.0.variadic {
327             s.push_str(", ...");
328         }
329         s.push(ket);
330
331         match sig.0.output {
332             ty::FnConverging(t) => {
333                 if !ty::type_is_nil(t) {
334                    s.push_str(" -> ");
335                    s.push_str(&ty_to_string(cx, t));
336                 }
337             }
338             ty::FnDiverging => {
339                 s.push_str(" -> !");
340             }
341         }
342     }
343
344     fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
345         let print_var_ids = cx.sess.verbose();
346         match ty {
347             ty::TyVar(ref vid) if print_var_ids => vid.repr(cx),
348             ty::IntVar(ref vid) if print_var_ids => vid.repr(cx),
349             ty::FloatVar(ref vid) if print_var_ids => vid.repr(cx),
350             ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => format!("_"),
351             ty::FreshTy(v) => format!("FreshTy({})", v),
352             ty::FreshIntTy(v) => format!("FreshIntTy({})", v)
353         }
354     }
355
356     // pretty print the structural type representation:
357     match typ.sty {
358         ty_bool => "bool".to_string(),
359         ty_char => "char".to_string(),
360         ty_int(t) => ast_util::int_ty_to_string(t, None).to_string(),
361         ty_uint(t) => ast_util::uint_ty_to_string(t, None).to_string(),
362         ty_float(t) => ast_util::float_ty_to_string(t).to_string(),
363         ty_uniq(typ) => format!("Box<{}>", ty_to_string(cx, typ)),
364         ty_ptr(ref tm) => {
365             format!("*{} {}", match tm.mutbl {
366                 ast::MutMutable => "mut",
367                 ast::MutImmutable => "const",
368             }, ty_to_string(cx, tm.ty))
369         }
370         ty_rptr(r, ref tm) => {
371             let mut buf = region_ptr_to_string(cx, *r);
372             buf.push_str(&mt_to_string(cx, tm));
373             buf
374         }
375         ty_tup(ref elems) => {
376             let strs = elems
377                 .iter()
378                 .map(|elem| ty_to_string(cx, *elem))
379                 .collect::<Vec<_>>();
380             match &strs[..] {
381                 [ref string] => format!("({},)", string),
382                 strs => format!("({})", strs.connect(", "))
383             }
384         }
385         ty_bare_fn(opt_def_id, ref f) => {
386             bare_fn_to_string(cx, opt_def_id, f.unsafety, f.abi, None, &f.sig)
387         }
388         ty_infer(infer_ty) => infer_ty_to_string(cx, infer_ty),
389         ty_err => "[type error]".to_string(),
390         ty_param(ref param_ty) => param_ty.user_string(cx),
391         ty_enum(did, substs) | ty_struct(did, substs) => {
392             let base = ty::item_path_str(cx, did);
393             parameterized(cx, &base, substs, did, &[],
394                           || ty::lookup_item_type(cx, did).generics)
395         }
396         ty_trait(ref data) => {
397             data.user_string(cx)
398         }
399         ty::ty_projection(ref data) => {
400             format!("<{} as {}>::{}",
401                     data.trait_ref.self_ty().user_string(cx),
402                     data.trait_ref.user_string(cx),
403                     data.item_name.user_string(cx))
404         }
405         ty_str => "str".to_string(),
406         ty_closure(ref did, substs) => {
407             let closure_tys = cx.closure_tys.borrow();
408             closure_tys.get(did).map(|closure_type| {
409                 closure_to_string(cx, &closure_type.subst(cx, substs))
410             }).unwrap_or_else(|| {
411                 if did.krate == ast::LOCAL_CRATE {
412                     let span = cx.map.span(did.node);
413                     format!("[closure {}]", span.repr(cx))
414                 } else {
415                     format!("[closure]")
416                 }
417             })
418         }
419         ty_vec(t, sz) => {
420             let inner_str = ty_to_string(cx, t);
421             match sz {
422                 Some(n) => format!("[{}; {}]", inner_str, n),
423                 None => format!("[{}]", inner_str),
424             }
425         }
426     }
427 }
428
429 pub fn explicit_self_category_to_str(category: &ty::ExplicitSelfCategory)
430                                      -> &'static str {
431     match *category {
432         ty::StaticExplicitSelfCategory => "static",
433         ty::ByValueExplicitSelfCategory => "self",
434         ty::ByReferenceExplicitSelfCategory(_, ast::MutMutable) => {
435             "&mut self"
436         }
437         ty::ByReferenceExplicitSelfCategory(_, ast::MutImmutable) => "&self",
438         ty::ByBoxExplicitSelfCategory => "Box<self>",
439     }
440 }
441
442 pub fn parameterized<'tcx,GG>(cx: &ctxt<'tcx>,
443                               base: &str,
444                               substs: &subst::Substs<'tcx>,
445                               did: ast::DefId,
446                               projections: &[ty::ProjectionPredicate<'tcx>],
447                               get_generics: GG)
448                               -> String
449     where GG : FnOnce() -> ty::Generics<'tcx>
450 {
451     if cx.sess.verbose() {
452         let mut strings = vec![];
453         match substs.regions {
454             subst::ErasedRegions => {
455                 strings.push(format!(".."));
456             }
457             subst::NonerasedRegions(ref regions) => {
458                 for region in regions.iter() {
459                     strings.push(region.repr(cx));
460                 }
461             }
462         }
463         for ty in substs.types.iter() {
464             strings.push(ty.repr(cx));
465         }
466         for projection in projections.iter() {
467             strings.push(format!("{}={}",
468                                  projection.projection_ty.item_name.user_string(cx),
469                                  projection.ty.user_string(cx)));
470         }
471         return if strings.is_empty() {
472             format!("{}", base)
473         } else {
474             format!("{}<{}>", base, strings.connect(","))
475         };
476     }
477
478     let mut strs = Vec::new();
479
480     match substs.regions {
481         subst::ErasedRegions => { }
482         subst::NonerasedRegions(ref regions) => {
483             for &r in regions.iter() {
484                 let s = region_to_string(cx, "", false, r);
485                 if s.is_empty() {
486                     // This happens when the value of the region
487                     // parameter is not easily serialized. This may be
488                     // because the user omitted it in the first place,
489                     // or because it refers to some block in the code,
490                     // etc. I'm not sure how best to serialize this.
491                     strs.push(format!("'_"));
492                 } else {
493                     strs.push(s)
494                 }
495             }
496         }
497     }
498
499     // It is important to execute this conditionally, only if -Z
500     // verbose is false. Otherwise, debug logs can sometimes cause
501     // ICEs trying to fetch the generics early in the pipeline. This
502     // is kind of a hacky workaround in that -Z verbose is required to
503     // avoid those ICEs.
504     let generics = get_generics();
505
506     let has_self = substs.self_ty().is_some();
507     let tps = substs.types.get_slice(subst::TypeSpace);
508     let ty_params = generics.types.get_slice(subst::TypeSpace);
509     let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
510     let num_defaults = if has_defaults {
511         ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
512             match def.default {
513                 Some(default) => {
514                     if !has_self && ty::type_has_self(default) {
515                         // In an object type, there is no `Self`, and
516                         // thus if the default value references Self,
517                         // the user will be required to give an
518                         // explicit value. We can't even do the
519                         // substitution below to check without causing
520                         // an ICE. (#18956).
521                         false
522                     } else {
523                         default.subst(cx, substs) == actual
524                     }
525                 }
526                 None => false
527             }
528         }).count()
529     } else {
530         0
531     };
532
533     for t in &tps[..tps.len() - num_defaults] {
534         strs.push(ty_to_string(cx, *t))
535     }
536
537     for projection in projections {
538         strs.push(format!("{}={}",
539                           projection.projection_ty.item_name.user_string(cx),
540                           projection.ty.user_string(cx)));
541     }
542
543     if cx.lang_items.fn_trait_kind(did).is_some() && projections.len() == 1 {
544         let projection_ty = projections[0].ty;
545         let tail =
546             if ty::type_is_nil(projection_ty) {
547                 format!("")
548             } else {
549                 format!(" -> {}", projection_ty.user_string(cx))
550             };
551         format!("{}({}){}",
552                 base,
553                 if strs[0].starts_with("(") && strs[0].ends_with(",)") {
554                     &strs[0][1 .. strs[0].len() - 2] // Remove '(' and ',)'
555                 } else if strs[0].starts_with("(") && strs[0].ends_with(")") {
556                     &strs[0][1 .. strs[0].len() - 1] // Remove '(' and ')'
557                 } else {
558                     &strs[0][..]
559                 },
560                 tail)
561     } else if !strs.is_empty() {
562         format!("{}<{}>", base, strs.connect(", "))
563     } else {
564         format!("{}", base)
565     }
566 }
567
568 pub fn ty_to_short_str<'tcx>(cx: &ctxt<'tcx>, typ: Ty<'tcx>) -> String {
569     let mut s = typ.repr(cx).to_string();
570     if s.len() >= 32 {
571         s = (&s[0..32]).to_string();
572     }
573     return s;
574 }
575
576 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Option<T> {
577     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
578         match self {
579             &None => "None".to_string(),
580             &Some(ref t) => t.repr(tcx),
581         }
582     }
583 }
584
585 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for P<T> {
586     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
587         (**self).repr(tcx)
588     }
589 }
590
591 impl<'tcx,T:Repr<'tcx>,U:Repr<'tcx>> Repr<'tcx> for Result<T,U> {
592     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
593         match self {
594             &Ok(ref t) => t.repr(tcx),
595             &Err(ref u) => format!("Err({})", u.repr(tcx))
596         }
597     }
598 }
599
600 impl<'tcx> Repr<'tcx> for () {
601     fn repr(&self, _tcx: &ctxt) -> String {
602         "()".to_string()
603     }
604 }
605
606 impl<'a, 'tcx, T: ?Sized +Repr<'tcx>> Repr<'tcx> for &'a T {
607     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
608         Repr::repr(*self, tcx)
609     }
610 }
611
612 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Rc<T> {
613     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
614         (&**self).repr(tcx)
615     }
616 }
617
618 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Box<T> {
619     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
620         (&**self).repr(tcx)
621     }
622 }
623
624 fn repr_vec<'tcx, T:Repr<'tcx>>(tcx: &ctxt<'tcx>, v: &[T]) -> String {
625     vec_map_to_string(v, |t| t.repr(tcx))
626 }
627
628 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for [T] {
629     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
630         repr_vec(tcx, self)
631     }
632 }
633
634 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for OwnedSlice<T> {
635     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
636         repr_vec(tcx, &self[..])
637     }
638 }
639
640 // This is necessary to handle types like Option<~[T]>, for which
641 // autoderef cannot convert the &[T] handler
642 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Vec<T> {
643     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
644         repr_vec(tcx, &self[..])
645     }
646 }
647
648 impl<'tcx, T:UserString<'tcx>> UserString<'tcx> for Vec<T> {
649     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
650         let strs: Vec<String> =
651             self.iter().map(|t| t.user_string(tcx)).collect();
652         strs.connect(", ")
653     }
654 }
655
656 impl<'tcx> Repr<'tcx> for def::Def {
657     fn repr(&self, _tcx: &ctxt) -> String {
658         format!("{:?}", *self)
659     }
660 }
661
662 /// This curious type is here to help pretty-print trait objects. In
663 /// a trait object, the projections are stored separately from the
664 /// main trait bound, but in fact we want to package them together
665 /// when printing out; they also have separate binders, but we want
666 /// them to share a binder when we print them out. (And the binder
667 /// pretty-printing logic is kind of clever and we don't want to
668 /// reproduce it.) So we just repackage up the structure somewhat.
669 ///
670 /// Right now there is only one trait in an object that can have
671 /// projection bounds, so we just stuff them altogether. But in
672 /// reality we should eventually sort things out better.
673 type TraitAndProjections<'tcx> =
674     (Rc<ty::TraitRef<'tcx>>, Vec<ty::ProjectionPredicate<'tcx>>);
675
676 impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> {
677     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
678         let &(ref trait_ref, ref projection_bounds) = self;
679         let base = ty::item_path_str(tcx, trait_ref.def_id);
680         parameterized(tcx,
681                       &base,
682                       trait_ref.substs,
683                       trait_ref.def_id,
684                       &projection_bounds[..],
685                       || ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone())
686     }
687 }
688
689 impl<'tcx> UserString<'tcx> for ty::TyTrait<'tcx> {
690     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
691         let &ty::TyTrait { ref principal, ref bounds } = self;
692
693         let mut components = vec![];
694
695         let tap: ty::Binder<TraitAndProjections<'tcx>> =
696             ty::Binder((principal.0.clone(),
697                         bounds.projection_bounds.iter().map(|x| x.0.clone()).collect()));
698
699         // Generate the main trait ref, including associated types.
700         components.push(tap.user_string(tcx));
701
702         // Builtin bounds.
703         for bound in &bounds.builtin_bounds {
704             components.push(bound.user_string(tcx));
705         }
706
707         // Region, if not obviously implied by builtin bounds.
708         if bounds.region_bound != ty::ReStatic {
709             // Region bound is implied by builtin bounds:
710             components.push(bounds.region_bound.user_string(tcx));
711         }
712
713         components.retain(|s| !s.is_empty());
714
715         components.connect(" + ")
716     }
717 }
718
719 impl<'tcx> Repr<'tcx> for ty::TypeParameterDef<'tcx> {
720     fn repr(&self, _tcx: &ctxt<'tcx>) -> String {
721         format!("TypeParameterDef({:?}, {:?}/{})",
722                 self.def_id,
723                 self.space,
724                 self.index)
725     }
726 }
727
728 impl<'tcx> Repr<'tcx> for ty::RegionParameterDef {
729     fn repr(&self, tcx: &ctxt) -> String {
730         format!("RegionParameterDef(name={}, def_id={}, bounds={})",
731                 token::get_name(self.name),
732                 self.def_id.repr(tcx),
733                 self.bounds.repr(tcx))
734     }
735 }
736
737 impl<'tcx> Repr<'tcx> for ty::TyS<'tcx> {
738     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
739         ty_to_string(tcx, self)
740     }
741 }
742
743 impl<'tcx> Repr<'tcx> for ty::mt<'tcx> {
744     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
745         mt_to_string(tcx, self)
746     }
747 }
748
749 impl<'tcx> Repr<'tcx> for subst::Substs<'tcx> {
750     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
751         format!("Substs[types={}, regions={}]",
752                        self.types.repr(tcx),
753                        self.regions.repr(tcx))
754     }
755 }
756
757 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for subst::VecPerParamSpace<T> {
758     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
759         format!("[{};{};{}]",
760                 self.get_slice(subst::TypeSpace).repr(tcx),
761                 self.get_slice(subst::SelfSpace).repr(tcx),
762                 self.get_slice(subst::FnSpace).repr(tcx))
763     }
764 }
765
766 impl<'tcx> Repr<'tcx> for ty::ItemSubsts<'tcx> {
767     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
768         format!("ItemSubsts({})", self.substs.repr(tcx))
769     }
770 }
771
772 impl<'tcx> Repr<'tcx> for subst::RegionSubsts {
773     fn repr(&self, tcx: &ctxt) -> String {
774         match *self {
775             subst::ErasedRegions => "erased".to_string(),
776             subst::NonerasedRegions(ref regions) => regions.repr(tcx)
777         }
778     }
779 }
780
781 impl<'tcx> Repr<'tcx> for ty::BuiltinBounds {
782     fn repr(&self, _tcx: &ctxt) -> String {
783         let mut res = Vec::new();
784         for b in self {
785             res.push(match b {
786                 ty::BoundSend => "Send".to_string(),
787                 ty::BoundSized => "Sized".to_string(),
788                 ty::BoundCopy => "Copy".to_string(),
789                 ty::BoundSync => "Sync".to_string(),
790             });
791         }
792         res.connect("+")
793     }
794 }
795
796 impl<'tcx> Repr<'tcx> for ty::ParamBounds<'tcx> {
797     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
798         let mut res = Vec::new();
799         res.push(self.builtin_bounds.repr(tcx));
800         for t in &self.trait_bounds {
801             res.push(t.repr(tcx));
802         }
803         res.connect("+")
804     }
805 }
806
807 impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
808     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
809         // when printing out the debug representation, we don't need
810         // to enumerate the `for<...>` etc because the debruijn index
811         // tells you everything you need to know.
812         let base = ty::item_path_str(tcx, self.def_id);
813         let result = parameterized(tcx, &base, self.substs, self.def_id, &[],
814                       || ty::lookup_trait_def(tcx, self.def_id).generics.clone());
815         match self.substs.self_ty() {
816             None => result,
817             Some(sty) => format!("<{} as {}>", sty.repr(tcx), result)
818         }
819     }
820 }
821
822 impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
823     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
824         format!("TraitDef(generics={}, trait_ref={})",
825                 self.generics.repr(tcx),
826                 self.trait_ref.repr(tcx))
827     }
828 }
829
830 impl<'tcx> Repr<'tcx> for ast::TraitItem {
831     fn repr(&self, _tcx: &ctxt) -> String {
832         let kind = match self.node {
833             ast::MethodTraitItem(..) => "MethodTraitItem",
834             ast::TypeTraitItem(..) => "TypeTraitItem",
835         };
836         format!("{}({}, id={})", kind, self.ident, self.id)
837     }
838 }
839
840 impl<'tcx> Repr<'tcx> for ast::Expr {
841     fn repr(&self, _tcx: &ctxt) -> String {
842         format!("expr({}: {})", self.id, pprust::expr_to_string(self))
843     }
844 }
845
846 impl<'tcx> Repr<'tcx> for ast::Path {
847     fn repr(&self, _tcx: &ctxt) -> String {
848         format!("path({})", pprust::path_to_string(self))
849     }
850 }
851
852 impl<'tcx> UserString<'tcx> for ast::Path {
853     fn user_string(&self, _tcx: &ctxt) -> String {
854         pprust::path_to_string(self)
855     }
856 }
857
858 impl<'tcx> Repr<'tcx> for ast::Ty {
859     fn repr(&self, _tcx: &ctxt) -> String {
860         format!("type({})", pprust::ty_to_string(self))
861     }
862 }
863
864 impl<'tcx> Repr<'tcx> for ast::Item {
865     fn repr(&self, tcx: &ctxt) -> String {
866         format!("item({})", tcx.map.node_to_string(self.id))
867     }
868 }
869
870 impl<'tcx> Repr<'tcx> for ast::Lifetime {
871     fn repr(&self, _tcx: &ctxt) -> String {
872         format!("lifetime({}: {})", self.id, pprust::lifetime_to_string(self))
873     }
874 }
875
876 impl<'tcx> Repr<'tcx> for ast::Stmt {
877     fn repr(&self, _tcx: &ctxt) -> String {
878         format!("stmt({}: {})",
879                 ast_util::stmt_id(self),
880                 pprust::stmt_to_string(self))
881     }
882 }
883
884 impl<'tcx> Repr<'tcx> for ast::Pat {
885     fn repr(&self, _tcx: &ctxt) -> String {
886         format!("pat({}: {})", self.id, pprust::pat_to_string(self))
887     }
888 }
889
890 impl<'tcx> Repr<'tcx> for ty::BoundRegion {
891     fn repr(&self, tcx: &ctxt) -> String {
892         match *self {
893             ty::BrAnon(id) => format!("BrAnon({})", id),
894             ty::BrNamed(id, name) => {
895                 format!("BrNamed({}, {})", id.repr(tcx), token::get_name(name))
896             }
897             ty::BrFresh(id) => format!("BrFresh({})", id),
898             ty::BrEnv => "BrEnv".to_string()
899         }
900     }
901 }
902
903 impl<'tcx> Repr<'tcx> for ty::Region {
904     fn repr(&self, tcx: &ctxt) -> String {
905         match *self {
906             ty::ReEarlyBound(ref data) => {
907                 format!("ReEarlyBound({}, {:?}, {}, {})",
908                         data.param_id,
909                         data.space,
910                         data.index,
911                         token::get_name(data.name))
912             }
913
914             ty::ReLateBound(binder_id, ref bound_region) => {
915                 format!("ReLateBound({:?}, {})",
916                         binder_id,
917                         bound_region.repr(tcx))
918             }
919
920             ty::ReFree(ref fr) => fr.repr(tcx),
921
922             ty::ReScope(id) => {
923                 format!("ReScope({:?})", id)
924             }
925
926             ty::ReStatic => {
927                 "ReStatic".to_string()
928             }
929
930             ty::ReInfer(ReVar(ref vid)) => {
931                 format!("{:?}", vid)
932             }
933
934             ty::ReInfer(ReSkolemized(id, ref bound_region)) => {
935                 format!("re_skolemized({}, {})", id, bound_region.repr(tcx))
936             }
937
938             ty::ReEmpty => {
939                 "ReEmpty".to_string()
940             }
941         }
942     }
943 }
944
945 impl<'tcx> UserString<'tcx> for ty::Region {
946     fn user_string(&self, tcx: &ctxt) -> String {
947         region_to_string(tcx, "", false, *self)
948     }
949 }
950
951 impl<'tcx> Repr<'tcx> for ty::FreeRegion {
952     fn repr(&self, tcx: &ctxt) -> String {
953         format!("ReFree({}, {})",
954                 self.scope.repr(tcx),
955                 self.bound_region.repr(tcx))
956     }
957 }
958
959 impl<'tcx> Repr<'tcx> for region::CodeExtent {
960     fn repr(&self, _tcx: &ctxt) -> String {
961         match *self {
962             region::CodeExtent::ParameterScope { fn_id, body_id } =>
963                 format!("ParameterScope({}, {})", fn_id, body_id),
964             region::CodeExtent::Misc(node_id) =>
965                 format!("Misc({})", node_id),
966             region::CodeExtent::DestructionScope(node_id) =>
967                 format!("DestructionScope({})", node_id),
968             region::CodeExtent::Remainder(rem) =>
969                 format!("Remainder({}, {})", rem.block, rem.first_statement_index),
970         }
971     }
972 }
973
974 impl<'tcx> Repr<'tcx> for region::DestructionScopeData {
975     fn repr(&self, _tcx: &ctxt) -> String {
976         match *self {
977             region::DestructionScopeData{ node_id } =>
978                 format!("DestructionScopeData {{ node_id: {} }}", node_id),
979         }
980     }
981 }
982
983 impl<'tcx> Repr<'tcx> for ast::DefId {
984     fn repr(&self, tcx: &ctxt) -> String {
985         // Unfortunately, there seems to be no way to attempt to print
986         // a path for a def-id, so I'll just make a best effort for now
987         // and otherwise fallback to just printing the crate/node pair
988         if self.krate == ast::LOCAL_CRATE {
989             match tcx.map.find(self.node) {
990                 Some(ast_map::NodeItem(..)) |
991                 Some(ast_map::NodeForeignItem(..)) |
992                 Some(ast_map::NodeImplItem(..)) |
993                 Some(ast_map::NodeTraitItem(..)) |
994                 Some(ast_map::NodeVariant(..)) |
995                 Some(ast_map::NodeStructCtor(..)) => {
996                     return format!(
997                                 "{:?}:{}",
998                                 *self,
999                                 ty::item_path_str(tcx, *self))
1000                 }
1001                 _ => {}
1002             }
1003         }
1004         return format!("{:?}", *self)
1005     }
1006 }
1007
1008 impl<'tcx> Repr<'tcx> for ty::TypeScheme<'tcx> {
1009     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1010         format!("TypeScheme {{generics: {}, ty: {}}}",
1011                 self.generics.repr(tcx),
1012                 self.ty.repr(tcx))
1013     }
1014 }
1015
1016 impl<'tcx> Repr<'tcx> for ty::Generics<'tcx> {
1017     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1018         format!("Generics(types: {}, regions: {})",
1019                 self.types.repr(tcx),
1020                 self.regions.repr(tcx))
1021     }
1022 }
1023
1024 impl<'tcx> Repr<'tcx> for ty::GenericPredicates<'tcx> {
1025     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1026         format!("GenericPredicates(predicates: {})",
1027                 self.predicates.repr(tcx))
1028     }
1029 }
1030
1031 impl<'tcx> Repr<'tcx> for ty::InstantiatedPredicates<'tcx> {
1032     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1033         format!("InstantiatedPredicates({})",
1034                 self.predicates.repr(tcx))
1035     }
1036 }
1037
1038 impl<'tcx> Repr<'tcx> for ty::ItemVariances {
1039     fn repr(&self, tcx: &ctxt) -> String {
1040         format!("ItemVariances(types={}, \
1041                 regions={})",
1042                 self.types.repr(tcx),
1043                 self.regions.repr(tcx))
1044     }
1045 }
1046
1047 impl<'tcx> Repr<'tcx> for ty::Variance {
1048     fn repr(&self, _: &ctxt) -> String {
1049         // The first `.to_string()` returns a &'static str (it is not an implementation
1050         // of the ToString trait). Because of that, we need to call `.to_string()` again
1051         // if we want to have a `String`.
1052         let result: &'static str = (*self).to_string();
1053         result.to_string()
1054     }
1055 }
1056
1057 impl<'tcx> Repr<'tcx> for ty::Method<'tcx> {
1058     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1059         format!("method(name: {}, generics: {}, predicates: {}, fty: {}, \
1060                  explicit_self: {}, vis: {}, def_id: {})",
1061                 self.name.repr(tcx),
1062                 self.generics.repr(tcx),
1063                 self.predicates.repr(tcx),
1064                 self.fty.repr(tcx),
1065                 self.explicit_self.repr(tcx),
1066                 self.vis.repr(tcx),
1067                 self.def_id.repr(tcx))
1068     }
1069 }
1070
1071 impl<'tcx> Repr<'tcx> for ast::Name {
1072     fn repr(&self, _tcx: &ctxt) -> String {
1073         token::get_name(*self).to_string()
1074     }
1075 }
1076
1077 impl<'tcx> UserString<'tcx> for ast::Name {
1078     fn user_string(&self, _tcx: &ctxt) -> String {
1079         token::get_name(*self).to_string()
1080     }
1081 }
1082
1083 impl<'tcx> Repr<'tcx> for ast::Ident {
1084     fn repr(&self, _tcx: &ctxt) -> String {
1085         token::get_ident(*self).to_string()
1086     }
1087 }
1088
1089 impl<'tcx> Repr<'tcx> for ast::ExplicitSelf_ {
1090     fn repr(&self, _tcx: &ctxt) -> String {
1091         format!("{:?}", *self)
1092     }
1093 }
1094
1095 impl<'tcx> Repr<'tcx> for ast::Visibility {
1096     fn repr(&self, _tcx: &ctxt) -> String {
1097         format!("{:?}", *self)
1098     }
1099 }
1100
1101 impl<'tcx> Repr<'tcx> for ty::BareFnTy<'tcx> {
1102     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1103         format!("BareFnTy {{unsafety: {}, abi: {}, sig: {}}}",
1104                 self.unsafety,
1105                 self.abi.to_string(),
1106                 self.sig.repr(tcx))
1107     }
1108 }
1109
1110
1111 impl<'tcx> Repr<'tcx> for ty::FnSig<'tcx> {
1112     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1113         format!("fn{} -> {}", self.inputs.repr(tcx), self.output.repr(tcx))
1114     }
1115 }
1116
1117 impl<'tcx> Repr<'tcx> for ty::FnOutput<'tcx> {
1118     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1119         match *self {
1120             ty::FnConverging(ty) =>
1121                 format!("FnConverging({0})", ty.repr(tcx)),
1122             ty::FnDiverging =>
1123                 "FnDiverging".to_string()
1124         }
1125     }
1126 }
1127
1128 impl<'tcx> Repr<'tcx> for ty::MethodCallee<'tcx> {
1129     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1130         format!("MethodCallee {{origin: {}, ty: {}, {}}}",
1131                 self.origin.repr(tcx),
1132                 self.ty.repr(tcx),
1133                 self.substs.repr(tcx))
1134     }
1135 }
1136
1137 impl<'tcx> Repr<'tcx> for ty::MethodOrigin<'tcx> {
1138     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1139         match self {
1140             &ty::MethodStatic(def_id) => {
1141                 format!("MethodStatic({})", def_id.repr(tcx))
1142             }
1143             &ty::MethodStaticClosure(def_id) => {
1144                 format!("MethodStaticClosure({})", def_id.repr(tcx))
1145             }
1146             &ty::MethodTypeParam(ref p) => {
1147                 p.repr(tcx)
1148             }
1149             &ty::MethodTraitObject(ref p) => {
1150                 p.repr(tcx)
1151             }
1152         }
1153     }
1154 }
1155
1156 impl<'tcx> Repr<'tcx> for ty::MethodParam<'tcx> {
1157     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1158         format!("MethodParam({},{})",
1159                 self.trait_ref.repr(tcx),
1160                 self.method_num)
1161     }
1162 }
1163
1164 impl<'tcx> Repr<'tcx> for ty::MethodObject<'tcx> {
1165     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1166         format!("MethodObject({},{},{})",
1167                 self.trait_ref.repr(tcx),
1168                 self.method_num,
1169                 self.vtable_index)
1170     }
1171 }
1172
1173 impl<'tcx> Repr<'tcx> for ty::BuiltinBound {
1174     fn repr(&self, _tcx: &ctxt) -> String {
1175         format!("{:?}", *self)
1176     }
1177 }
1178
1179 impl<'tcx> UserString<'tcx> for ty::BuiltinBound {
1180     fn user_string(&self, _tcx: &ctxt) -> String {
1181         match *self {
1182             ty::BoundSend => "Send".to_string(),
1183             ty::BoundSized => "Sized".to_string(),
1184             ty::BoundCopy => "Copy".to_string(),
1185             ty::BoundSync => "Sync".to_string(),
1186         }
1187     }
1188 }
1189
1190 impl<'tcx> Repr<'tcx> for Span {
1191     fn repr(&self, tcx: &ctxt) -> String {
1192         tcx.sess.codemap().span_to_string(*self).to_string()
1193     }
1194 }
1195
1196 impl<'tcx, A:UserString<'tcx>> UserString<'tcx> for Rc<A> {
1197     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1198         let this: &A = &**self;
1199         this.user_string(tcx)
1200     }
1201 }
1202
1203 impl<'tcx> UserString<'tcx> for ty::ParamBounds<'tcx> {
1204     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1205         let mut result = Vec::new();
1206         let s = self.builtin_bounds.user_string(tcx);
1207         if !s.is_empty() {
1208             result.push(s);
1209         }
1210         for n in &self.trait_bounds {
1211             result.push(n.user_string(tcx));
1212         }
1213         result.connect(" + ")
1214     }
1215 }
1216
1217 impl<'tcx> Repr<'tcx> for ty::ExistentialBounds<'tcx> {
1218     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1219         let mut res = Vec::new();
1220
1221         let region_str = self.region_bound.repr(tcx);
1222         if !region_str.is_empty() {
1223             res.push(region_str);
1224         }
1225
1226         for bound in &self.builtin_bounds {
1227             res.push(bound.repr(tcx));
1228         }
1229
1230         for projection_bound in &self.projection_bounds {
1231             res.push(projection_bound.repr(tcx));
1232         }
1233
1234         res.connect("+")
1235     }
1236 }
1237
1238 impl<'tcx> UserString<'tcx> for ty::BuiltinBounds {
1239     fn user_string(&self, tcx: &ctxt) -> String {
1240         self.iter()
1241             .map(|bb| bb.user_string(tcx))
1242             .collect::<Vec<String>>()
1243             .connect("+")
1244             .to_string()
1245     }
1246 }
1247
1248 impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
1249     where T : UserString<'tcx> + TypeFoldable<'tcx>
1250 {
1251     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1252         // Replace any anonymous late-bound regions with named
1253         // variants, using gensym'd identifiers, so that we can
1254         // clearly differentiate between named and unnamed regions in
1255         // the output. We'll probably want to tweak this over time to
1256         // decide just how much information to give.
1257         let mut names = Vec::new();
1258         let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br| {
1259             ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
1260                 ty::BrNamed(_, name) => {
1261                     names.push(token::get_name(name));
1262                     br
1263                 }
1264                 ty::BrAnon(_) |
1265                 ty::BrFresh(_) |
1266                 ty::BrEnv => {
1267                     let name = token::gensym("'r");
1268                     names.push(token::get_name(name));
1269                     ty::BrNamed(ast_util::local_def(ast::DUMMY_NODE_ID), name)
1270                 }
1271             })
1272         });
1273         let names: Vec<_> = names.iter().map(|s| &s[..]).collect();
1274
1275         let value_str = unbound_value.user_string(tcx);
1276         if names.is_empty() {
1277             value_str
1278         } else {
1279             format!("for<{}> {}", names.connect(","), value_str)
1280         }
1281     }
1282 }
1283
1284 impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
1285     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1286         let path_str = ty::item_path_str(tcx, self.def_id);
1287         parameterized(tcx, &path_str, self.substs, self.def_id, &[],
1288                       || ty::lookup_trait_def(tcx, self.def_id).generics.clone())
1289     }
1290 }
1291
1292 impl<'tcx> UserString<'tcx> for Ty<'tcx> {
1293     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1294         ty_to_string(tcx, *self)
1295     }
1296 }
1297
1298 impl<'tcx> UserString<'tcx> for ast::Ident {
1299     fn user_string(&self, _tcx: &ctxt) -> String {
1300         token::get_name(self.name).to_string()
1301     }
1302 }
1303
1304 impl<'tcx> Repr<'tcx> for abi::Abi {
1305     fn repr(&self, _tcx: &ctxt) -> String {
1306         self.to_string()
1307     }
1308 }
1309
1310 impl<'tcx> UserString<'tcx> for abi::Abi {
1311     fn user_string(&self, _tcx: &ctxt) -> String {
1312         self.to_string()
1313     }
1314 }
1315
1316 impl<'tcx> Repr<'tcx> for ty::UpvarId {
1317     fn repr(&self, tcx: &ctxt) -> String {
1318         format!("UpvarId({};`{}`;{})",
1319                 self.var_id,
1320                 ty::local_var_name_str(tcx, self.var_id),
1321                 self.closure_expr_id)
1322     }
1323 }
1324
1325 impl<'tcx> Repr<'tcx> for ast::Mutability {
1326     fn repr(&self, _tcx: &ctxt) -> String {
1327         format!("{:?}", *self)
1328     }
1329 }
1330
1331 impl<'tcx> Repr<'tcx> for ty::BorrowKind {
1332     fn repr(&self, _tcx: &ctxt) -> String {
1333         format!("{:?}", *self)
1334     }
1335 }
1336
1337 impl<'tcx> Repr<'tcx> for ty::UpvarBorrow {
1338     fn repr(&self, tcx: &ctxt) -> String {
1339         format!("UpvarBorrow({}, {})",
1340                 self.kind.repr(tcx),
1341                 self.region.repr(tcx))
1342     }
1343 }
1344
1345 impl<'tcx> Repr<'tcx> for ty::UpvarCapture {
1346     fn repr(&self, tcx: &ctxt) -> String {
1347         match *self {
1348             ty::UpvarCapture::ByValue => format!("ByValue"),
1349             ty::UpvarCapture::ByRef(ref data) => format!("ByRef({})", data.repr(tcx)),
1350         }
1351     }
1352 }
1353
1354 impl<'tcx> Repr<'tcx> for ty::IntVid {
1355     fn repr(&self, _tcx: &ctxt) -> String {
1356         format!("{:?}", self)
1357     }
1358 }
1359
1360 impl<'tcx> Repr<'tcx> for ty::FloatVid {
1361     fn repr(&self, _tcx: &ctxt) -> String {
1362         format!("{:?}", self)
1363     }
1364 }
1365
1366 impl<'tcx> Repr<'tcx> for ty::RegionVid {
1367     fn repr(&self, _tcx: &ctxt) -> String {
1368         format!("{:?}", self)
1369     }
1370 }
1371
1372 impl<'tcx> Repr<'tcx> for ty::TyVid {
1373     fn repr(&self, _tcx: &ctxt) -> String {
1374         format!("{:?}", self)
1375     }
1376 }
1377
1378 impl<'tcx> Repr<'tcx> for ty::IntVarValue {
1379     fn repr(&self, _tcx: &ctxt) -> String {
1380         format!("{:?}", *self)
1381     }
1382 }
1383
1384 impl<'tcx> Repr<'tcx> for ast::IntTy {
1385     fn repr(&self, _tcx: &ctxt) -> String {
1386         format!("{:?}", *self)
1387     }
1388 }
1389
1390 impl<'tcx> Repr<'tcx> for ast::UintTy {
1391     fn repr(&self, _tcx: &ctxt) -> String {
1392         format!("{:?}", *self)
1393     }
1394 }
1395
1396 impl<'tcx> Repr<'tcx> for ast::FloatTy {
1397     fn repr(&self, _tcx: &ctxt) -> String {
1398         format!("{:?}", *self)
1399     }
1400 }
1401
1402 impl<'tcx> Repr<'tcx> for ty::ExplicitSelfCategory {
1403     fn repr(&self, _: &ctxt) -> String {
1404         explicit_self_category_to_str(self).to_string()
1405     }
1406 }
1407
1408 impl<'tcx> UserString<'tcx> for ParamTy {
1409     fn user_string(&self, _tcx: &ctxt) -> String {
1410         format!("{}", token::get_name(self.name))
1411     }
1412 }
1413
1414 impl<'tcx> Repr<'tcx> for ParamTy {
1415     fn repr(&self, tcx: &ctxt) -> String {
1416         let ident = self.user_string(tcx);
1417         format!("{}/{:?}.{}", ident, self.space, self.idx)
1418     }
1419 }
1420
1421 impl<'tcx, A:Repr<'tcx>, B:Repr<'tcx>> Repr<'tcx> for (A,B) {
1422     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1423         let &(ref a, ref b) = self;
1424         format!("({},{})", a.repr(tcx), b.repr(tcx))
1425     }
1426 }
1427
1428 impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
1429     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1430         format!("Binder({})", self.0.repr(tcx))
1431     }
1432 }
1433
1434 impl<'tcx, S, K, V> Repr<'tcx> for HashMap<K, V, S>
1435     where K: Hash + Eq + Repr<'tcx>,
1436           V: Repr<'tcx>,
1437           S: HashState,
1438 {
1439     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1440         format!("HashMap({})",
1441                 self.iter()
1442                     .map(|(k,v)| format!("{} => {}", k.repr(tcx), v.repr(tcx)))
1443                     .collect::<Vec<String>>()
1444                     .connect(", "))
1445     }
1446 }
1447
1448 impl<'tcx, T, U> Repr<'tcx> for ty::OutlivesPredicate<T,U>
1449     where T : Repr<'tcx> + TypeFoldable<'tcx>,
1450           U : Repr<'tcx> + TypeFoldable<'tcx>,
1451 {
1452     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1453         format!("OutlivesPredicate({}, {})",
1454                 self.0.repr(tcx),
1455                 self.1.repr(tcx))
1456     }
1457 }
1458
1459 impl<'tcx, T, U> UserString<'tcx> for ty::OutlivesPredicate<T,U>
1460     where T : UserString<'tcx> + TypeFoldable<'tcx>,
1461           U : UserString<'tcx> + TypeFoldable<'tcx>,
1462 {
1463     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1464         format!("{} : {}",
1465                 self.0.user_string(tcx),
1466                 self.1.user_string(tcx))
1467     }
1468 }
1469
1470 impl<'tcx> Repr<'tcx> for ty::EquatePredicate<'tcx> {
1471     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1472         format!("EquatePredicate({}, {})",
1473                 self.0.repr(tcx),
1474                 self.1.repr(tcx))
1475     }
1476 }
1477
1478 impl<'tcx> UserString<'tcx> for ty::EquatePredicate<'tcx> {
1479     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1480         format!("{} == {}",
1481                 self.0.user_string(tcx),
1482                 self.1.user_string(tcx))
1483     }
1484 }
1485
1486 impl<'tcx> Repr<'tcx> for ty::TraitPredicate<'tcx> {
1487     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1488         format!("TraitPredicate({})",
1489                 self.trait_ref.repr(tcx))
1490     }
1491 }
1492
1493 impl<'tcx> UserString<'tcx> for ty::TraitPredicate<'tcx> {
1494     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1495         format!("{} : {}",
1496                 self.trait_ref.self_ty().user_string(tcx),
1497                 self.trait_ref.user_string(tcx))
1498     }
1499 }
1500
1501 impl<'tcx> UserString<'tcx> for ty::ProjectionPredicate<'tcx> {
1502     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1503         format!("{} == {}",
1504                 self.projection_ty.user_string(tcx),
1505                 self.ty.user_string(tcx))
1506     }
1507 }
1508
1509 impl<'tcx> Repr<'tcx> for ty::ProjectionTy<'tcx> {
1510     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
1511         format!("{}::{}",
1512                 self.trait_ref.repr(tcx),
1513                 self.item_name.repr(tcx))
1514     }
1515 }
1516
1517 impl<'tcx> UserString<'tcx> for ty::ProjectionTy<'tcx> {
1518     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1519         format!("<{} as {}>::{}",
1520                 self.trait_ref.self_ty().user_string(tcx),
1521                 self.trait_ref.user_string(tcx),
1522                 self.item_name.user_string(tcx))
1523     }
1524 }
1525
1526 impl<'tcx> UserString<'tcx> for ty::Predicate<'tcx> {
1527     fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
1528         match *self {
1529             ty::Predicate::Trait(ref data) => data.user_string(tcx),
1530             ty::Predicate::Equate(ref predicate) => predicate.user_string(tcx),
1531             ty::Predicate::RegionOutlives(ref predicate) => predicate.user_string(tcx),
1532             ty::Predicate::TypeOutlives(ref predicate) => predicate.user_string(tcx),
1533             ty::Predicate::Projection(ref predicate) => predicate.user_string(tcx),
1534         }
1535     }
1536 }
1537
1538 impl<'tcx> Repr<'tcx> for ast::Unsafety {
1539     fn repr(&self, _: &ctxt<'tcx>) -> String {
1540         format!("{:?}", *self)
1541     }
1542 }