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.
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.
12 use metadata::encoder;
13 use middle::ty::{ReSkolemized, ReVar};
14 use middle::ty::{BoundRegion, BrAnon, BrNamed};
15 use middle::ty::{BrFresh, ctxt};
16 use middle::ty::{mt, t, param_ty};
17 use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region,
19 use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
20 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
21 use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_self, ty_tup};
22 use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_unboxed_vec, ty_infer};
26 use syntax::abi::AbiSet;
28 use syntax::codemap::{Span, Pos};
29 use syntax::parse::token;
30 use syntax::print::pprust;
31 use syntax::{ast, ast_util};
32 use syntax::owned_slice::OwnedSlice;
34 /// Produces a string suitable for debugging output.
36 fn repr(&self, tcx: &ctxt) -> ~str;
39 /// Produces a string suitable for showing to the user.
40 pub trait UserString {
41 fn user_string(&self, tcx: &ctxt) -> ~str;
44 pub fn note_and_explain_region(cx: &ctxt,
48 match explain_region_and_span(cx, region) {
49 (ref str, Some(span)) => {
52 format!("{}{}{}", prefix, *str, suffix));
56 format!("{}{}{}", prefix, *str, suffix));
61 /// Returns a string like "the block at 27:31" that attempts to explain a
62 /// lifetime in a way it might plausibly be understood.
63 pub fn explain_region(cx: &ctxt, region: ty::Region) -> ~str {
64 let (res, _) = explain_region_and_span(cx, region);
69 pub fn explain_region_and_span(cx: &ctxt, region: ty::Region)
70 -> (~str, Option<Span>) {
73 match cx.map.find(node_id) {
74 Some(ast_map::NodeBlock(ref blk)) => {
75 explain_span(cx, "block", blk.span)
77 Some(ast_map::NodeExpr(expr)) => {
79 ast::ExprCall(..) => explain_span(cx, "call", expr.span),
80 ast::ExprMethodCall(..) => {
81 explain_span(cx, "method call", expr.span)
83 ast::ExprMatch(..) => explain_span(cx, "match", expr.span),
84 _ => explain_span(cx, "expression", expr.span)
87 Some(ast_map::NodeStmt(stmt)) => {
88 explain_span(cx, "statement", stmt.span)
90 Some(ast_map::NodeItem(it)) if (match it.node {
91 ast::ItemFn(..) => true, _ => false}) => {
92 explain_span(cx, "function body", it.span)
95 // this really should not happen
96 (format!("unknown scope: {}. Please report a bug.", node_id),
103 let prefix = match fr.bound_region {
104 BrAnon(idx) => format!("the anonymous lifetime \\#{} defined on",
106 BrFresh(_) => format!("an anonymous lifetime defined on"),
107 _ => format!("the lifetime {} as defined on",
108 bound_region_ptr_to_str(cx, fr.bound_region))
111 match cx.map.find(fr.scope_id) {
112 Some(ast_map::NodeBlock(ref blk)) => {
113 let (msg, opt_span) = explain_span(cx, "block", blk.span);
114 (format!("{} {}", prefix, msg), opt_span)
116 Some(ast_map::NodeItem(it)) if match it.node {
117 ast::ItemImpl(..) => true, _ => false} => {
118 let (msg, opt_span) = explain_span(cx, "impl", it.span);
119 (format!("{} {}", prefix, msg), opt_span)
122 // this really should not happen
123 (format!("{} node {}", prefix, fr.scope_id), None)
128 ReStatic => { (~"the static lifetime", None) }
130 ReEmpty => { (~"the empty lifetime", None) }
132 // I believe these cases should not occur (except when debugging,
134 ty::ReInfer(_) | ty::ReEarlyBound(..) | ty::ReLateBound(..) => {
135 (format!("lifetime {:?}", region), None)
139 fn explain_span(cx: &ctxt, heading: &str, span: Span)
140 -> (~str, Option<Span>) {
141 let lo = cx.sess.codemap().lookup_char_pos_adj(span.lo);
142 (format!("the {} at {}:{}", heading,
143 lo.line, lo.col.to_uint()), Some(span))
147 pub fn bound_region_ptr_to_str(cx: &ctxt, br: BoundRegion) -> ~str {
148 bound_region_to_str(cx, "&", true, br)
151 pub fn bound_region_to_str(cx: &ctxt,
152 prefix: &str, space: bool,
153 br: BoundRegion) -> ~str {
154 let space_str = if space { " " } else { "" };
156 if cx.sess.verbose() {
157 return format!("{}{}{}", prefix, br.repr(cx), space_str);
161 BrNamed(_, name) => format!("{}'{}{}", prefix,
162 token::get_name(name), space_str),
163 BrAnon(_) => prefix.to_str(),
164 BrFresh(_) => prefix.to_str(),
168 pub fn ReScope_id_to_str(cx: &ctxt, node_id: ast::NodeId) -> ~str {
169 match cx.map.find(node_id) {
170 Some(ast_map::NodeBlock(ref blk)) => {
171 format!("<block at {}>",
172 cx.sess.codemap().span_to_str(blk.span))
174 Some(ast_map::NodeExpr(expr)) => {
176 ast::ExprCall(..) => {
177 format!("<call at {}>",
178 cx.sess.codemap().span_to_str(expr.span))
180 ast::ExprMatch(..) => {
181 format!("<match at {}>",
182 cx.sess.codemap().span_to_str(expr.span))
184 ast::ExprAssignOp(..) |
186 ast::ExprBinary(..) |
187 ast::ExprIndex(..) => {
188 format!("<method at {}>",
189 cx.sess.codemap().span_to_str(expr.span))
192 format!("<expression at {}>",
193 cx.sess.codemap().span_to_str(expr.span))
198 format!("<unknown-{}>", node_id)
200 _ => cx.sess.bug(format!("ReScope refers to {}", cx.map.node_to_str(node_id)))
204 // In general, if you are giving a region error message,
205 // you should use `explain_region()` or, better yet,
206 // `note_and_explain_region()`
207 pub fn region_ptr_to_str(cx: &ctxt, region: Region) -> ~str {
208 region_to_str(cx, "&", true, region)
211 pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> ~str {
212 let space_str = if space { " " } else { "" };
214 if cx.sess.verbose() {
215 return format!("{}{}{}", prefix, region.repr(cx), space_str);
218 // These printouts are concise. They do not contain all the information
219 // the user might want to diagnose an error, but there is basically no way
220 // to fit that into a short string. Hence the recommendation to use
221 // `explain_region()` or `note_and_explain_region()`.
223 ty::ReScope(_) => prefix.to_str(),
224 ty::ReEarlyBound(_, _, name) => token::get_name(name).get().to_str(),
225 ty::ReLateBound(_, br) => bound_region_to_str(cx, prefix, space, br),
226 ty::ReFree(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region),
227 ty::ReInfer(ReSkolemized(_, br)) => {
228 bound_region_to_str(cx, prefix, space, br)
230 ty::ReInfer(ReVar(_)) => prefix.to_str(),
231 ty::ReStatic => format!("{}'static{}", prefix, space_str),
232 ty::ReEmpty => format!("{}'<empty>{}", prefix, space_str)
236 pub fn mutability_to_str(m: ast::Mutability) -> ~str {
238 ast::MutMutable => ~"mut ",
239 ast::MutImmutable => ~"",
243 pub fn mt_to_str(cx: &ctxt, m: &mt) -> ~str {
244 mt_to_str_wrapped(cx, "", m, "")
247 pub fn mt_to_str_wrapped(cx: &ctxt, before: &str, m: &mt, after: &str) -> ~str {
248 let mstr = mutability_to_str(m.mutbl);
249 return format!("{}{}{}{}", mstr, before, ty_to_str(cx, m.ty), after);
252 pub fn vstore_to_str(cx: &ctxt, vs: ty::vstore) -> ~str {
254 ty::vstore_fixed(n) => format!("{}", n),
255 ty::vstore_uniq => ~"~",
256 ty::vstore_slice(r) => region_ptr_to_str(cx, r)
260 pub fn trait_store_to_str(cx: &ctxt, s: ty::TraitStore) -> ~str {
262 ty::UniqTraitStore => ~"~",
263 ty::RegionTraitStore(r) => region_ptr_to_str(cx, r)
267 pub fn vstore_ty_to_str(cx: &ctxt, mt: &mt, vs: ty::vstore) -> ~str {
269 ty::vstore_fixed(_) => {
270 format!("[{}, .. {}]", mt_to_str(cx, mt), vstore_to_str(cx, vs))
273 format!("{}{}", vstore_to_str(cx, vs), mt_to_str_wrapped(cx, "[", mt, "]"))
278 pub fn vec_map_to_str<T>(ts: &[T], f: |t: &T| -> ~str) -> ~str {
279 let tstrs = ts.map(f);
280 format!("[{}]", tstrs.connect(", "))
283 pub fn tys_to_str(cx: &ctxt, ts: &[t]) -> ~str {
284 vec_map_to_str(ts, |t| ty_to_str(cx, *t))
287 pub fn fn_sig_to_str(cx: &ctxt, typ: &ty::FnSig) -> ~str {
288 format!("fn{}{} -> {}",
294 pub fn trait_ref_to_str(cx: &ctxt, trait_ref: &ty::TraitRef) -> ~str {
295 trait_ref.user_string(cx)
298 pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
299 fn fn_input_to_str(cx: &ctxt, input: ty::t) -> ~str {
302 fn bare_fn_to_str(cx: &ctxt,
305 ident: Option<ast::Ident>,
308 let mut s = if abis.is_rust() {
311 format!("extern {} ", abis.to_str())
317 s.push_str(purity.to_str());
327 s.push_str(token::get_ident(i).get());
332 push_sig_to_str(cx, &mut s, '(', ')', sig);
336 fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> ~str {
338 (cty.sigil, cty.onceness) == (ast::OwnedSigil, ast::Once);
339 let is_borrowed_closure = cty.sigil == ast::BorrowedSigil;
341 let mut s = if is_proc || is_borrowed_closure {
347 match (cty.sigil, cty.region) {
348 (ast::ManagedSigil, ty::ReStatic) |
349 (ast::OwnedSigil, ty::ReStatic) => {}
352 s.push_str(region_to_str(cx, "", true, region));
359 s.push_str(cty.purity.to_str());
370 s.push_str(cty.onceness.to_str());
375 if !is_borrowed_closure {
380 if !is_borrowed_closure {
381 // Print bounds before `fn` if this is not a borrowed closure.
382 if !cty.bounds.is_empty() {
384 s.push_str(cty.bounds.repr(cx));
387 push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
389 // Print bounds after the signature if this is a borrowed closure.
390 push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
392 if is_borrowed_closure {
393 if !cty.bounds.is_empty() {
395 s.push_str(cty.bounds.repr(cx));
402 fn push_sig_to_str(cx: &ctxt,
408 let strs = sig.inputs.map(|a| fn_input_to_str(cx, *a));
409 s.push_str(strs.connect(", "));
415 if ty::get(sig.output).sty != ty_nil {
417 if ty::type_is_bot(sig.output) {
420 s.push_str(ty_to_str(cx, sig.output));
425 // if there is an id, print that instead of the structural type:
426 /*for def_id in ty::type_def_id(typ).iter() {
427 // note that this typedef cannot have type parameters
428 return ty::item_path_str(cx, *def_id);
431 // pretty print the structural type representation:
432 return match ty::get(typ).sty {
437 ty_int(ast::TyI) => ~"int",
438 ty_int(t) => ast_util::int_ty_to_str(t),
439 ty_uint(ast::TyU) => ~"uint",
440 ty_uint(t) => ast_util::uint_ty_to_str(t),
441 ty_float(t) => ast_util::float_ty_to_str(t),
442 ty_box(typ) => ~"@" + ty_to_str(cx, typ),
443 ty_uniq(typ) => ~"~" + ty_to_str(cx, typ),
444 ty_ptr(ref tm) => ~"*" + mt_to_str(cx, tm),
445 ty_rptr(r, ref tm) => {
446 region_ptr_to_str(cx, r) + mt_to_str(cx, tm)
448 ty_unboxed_vec(ref tm) => { format!("unboxed_vec<{}>", mt_to_str(cx, tm)) }
449 ty_tup(ref elems) => {
450 let strs = elems.map(|elem| ty_to_str(cx, *elem));
451 ~"(" + strs.connect(",") + ")"
453 ty_closure(ref f) => {
454 closure_to_str(cx, *f)
456 ty_bare_fn(ref f) => {
457 bare_fn_to_str(cx, f.purity, f.abis, None, &f.sig)
459 ty_infer(infer_ty) => infer_ty.to_str(),
460 ty_err => ~"[type error]",
461 ty_param(param_ty {idx: id, def_id: did}) => {
462 let ident = match cx.ty_param_defs.borrow().find(&did.node) {
463 Some(def) => token::get_ident(def.ident).get().to_str(),
464 // This should not happen...
465 None => format!("BUG[{:?}]", id)
467 if !cx.sess.verbose() {
470 format!("{}:{:?}", ident, did)
473 ty_self(..) => ~"Self",
474 ty_enum(did, ref substs) | ty_struct(did, ref substs) => {
475 let base = ty::item_path_str(cx, did);
479 substs.tps.as_slice(),
483 ty_trait(~ty::TyTrait {
484 def_id: did, ref substs, store: s, mutability: mutbl, ref bounds
486 let base = ty::item_path_str(cx, did);
487 let ty = parameterized(cx, base, &substs.regions,
488 substs.tps.as_slice(), did, true);
489 let bound_sep = if bounds.is_empty() { "" } else { ":" };
490 let bound_str = bounds.repr(cx);
491 format!("{}{}{}{}{}", trait_store_to_str(cx, s), mutability_to_str(mutbl), ty,
492 bound_sep, bound_str)
494 ty_vec(ref mt, vs) => {
495 vstore_ty_to_str(cx, mt, vs)
497 ty_str(vs) => format!("{}{}", vstore_to_str(cx, vs), "str")
501 pub fn parameterized(cx: &ctxt,
503 regions: &ty::RegionSubsts,
506 is_trait: bool) -> ~str {
508 let mut strs = Vec::new();
510 ty::ErasedRegions => { }
511 ty::NonerasedRegions(ref regions) => {
512 for &r in regions.iter() {
513 strs.push(region_to_str(cx, "", false, r))
518 let generics = if is_trait {
519 ty::lookup_trait_def(cx, did).generics.clone()
521 ty::lookup_item_type(cx, did).generics
523 let ty_params = generics.type_param_defs();
524 let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
525 let num_defaults = if has_defaults {
526 // We should have a borrowed version of substs instead of cloning.
527 let mut substs = ty::substs {
528 tps: Vec::from_slice(tps),
529 regions: regions.clone(),
532 ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
535 Some(default) => ty::subst(cx, &substs, default) == actual,
543 for t in tps.slice_to(tps.len() - num_defaults).iter() {
544 strs.push(ty_to_str(cx, *t))
548 format!("{}<{}>", base, strs.connect(","))
554 pub fn ty_to_short_str(cx: &ctxt, typ: t) -> ~str {
555 let mut s = encoder::encoded_ty(cx, typ);
556 if s.len() >= 32u { s = s.slice(0u, 32u).to_owned(); }
560 impl<T:Repr> Repr for Option<T> {
561 fn repr(&self, tcx: &ctxt) -> ~str {
564 &Some(ref t) => t.repr(tcx),
569 impl<T:Repr,U:Repr> Repr for Result<T,U> {
570 fn repr(&self, tcx: &ctxt) -> ~str {
572 &Ok(ref t) => t.repr(tcx),
573 &Err(ref u) => format!("Err({})", u.repr(tcx))
579 fn repr(&self, _tcx: &ctxt) -> ~str {
584 impl<T:Repr> Repr for @T {
585 fn repr(&self, tcx: &ctxt) -> ~str {
590 impl<T:Repr> Repr for ~T {
591 fn repr(&self, tcx: &ctxt) -> ~str {
596 fn repr_vec<T:Repr>(tcx: &ctxt, v: &[T]) -> ~str {
597 vec_map_to_str(v, |t| t.repr(tcx))
600 impl<'a, T:Repr> Repr for &'a [T] {
601 fn repr(&self, tcx: &ctxt) -> ~str {
606 impl<T:Repr> Repr for OwnedSlice<T> {
607 fn repr(&self, tcx: &ctxt) -> ~str {
608 repr_vec(tcx, self.as_slice())
612 // This is necessary to handle types like Option<~[T]>, for which
613 // autoderef cannot convert the &[T] handler
614 impl<T:Repr> Repr for Vec<T> {
615 fn repr(&self, tcx: &ctxt) -> ~str {
616 repr_vec(tcx, self.as_slice())
620 impl Repr for ty::TypeParameterDef {
621 fn repr(&self, tcx: &ctxt) -> ~str {
622 format!("TypeParameterDef({:?}, {})",
624 self.bounds.repr(tcx))
628 impl Repr for ty::RegionParameterDef {
629 fn repr(&self, _tcx: &ctxt) -> ~str {
630 format!("RegionParameterDef({}, {:?})",
631 token::get_name(self.name),
636 impl Repr for ty::t {
637 fn repr(&self, tcx: &ctxt) -> ~str {
638 ty_to_str(tcx, *self)
642 impl Repr for ty::substs {
643 fn repr(&self, tcx: &ctxt) -> ~str {
644 format!("substs(regions={}, self_ty={}, tps={})",
645 self.regions.repr(tcx),
646 self.self_ty.repr(tcx),
651 impl Repr for ty::RegionSubsts {
652 fn repr(&self, tcx: &ctxt) -> ~str {
654 ty::ErasedRegions => ~"erased",
655 ty::NonerasedRegions(ref regions) => regions.repr(tcx)
660 impl Repr for ty::ParamBounds {
661 fn repr(&self, tcx: &ctxt) -> ~str {
662 let mut res = Vec::new();
663 for b in self.builtin_bounds.iter() {
665 ty::BoundStatic => ~"'static",
666 ty::BoundSend => ~"Send",
667 ty::BoundSized => ~"Sized",
668 ty::BoundPod => ~"Pod",
669 ty::BoundShare => ~"Share",
672 for t in self.trait_bounds.iter() {
673 res.push(t.repr(tcx));
679 impl Repr for ty::TraitRef {
680 fn repr(&self, tcx: &ctxt) -> ~str {
681 trait_ref_to_str(tcx, self)
685 impl Repr for ast::Expr {
686 fn repr(&self, _tcx: &ctxt) -> ~str {
687 format!("expr({}: {})", self.id, pprust::expr_to_str(self))
691 impl Repr for ast::Item {
692 fn repr(&self, tcx: &ctxt) -> ~str {
693 format!("item({})", tcx.map.node_to_str(self.id))
697 impl Repr for ast::Stmt {
698 fn repr(&self, _tcx: &ctxt) -> ~str {
699 format!("stmt({}: {})",
700 ast_util::stmt_id(self),
701 pprust::stmt_to_str(self))
705 impl Repr for ast::Pat {
706 fn repr(&self, _tcx: &ctxt) -> ~str {
707 format!("pat({}: {})",
709 pprust::pat_to_str(self))
713 impl Repr for ty::BoundRegion {
714 fn repr(&self, tcx: &ctxt) -> ~str {
716 ty::BrAnon(id) => format!("BrAnon({})", id),
717 ty::BrNamed(id, name) => format!("BrNamed({}, {})",
719 token::get_name(name)),
720 ty::BrFresh(id) => format!("BrFresh({})", id),
725 impl Repr for ty::Region {
726 fn repr(&self, tcx: &ctxt) -> ~str {
728 ty::ReEarlyBound(id, index, name) => {
729 format!("ReEarlyBound({}, {}, {})",
730 id, index, token::get_name(name))
733 ty::ReLateBound(binder_id, ref bound_region) => {
734 format!("ReLateBound({}, {})",
735 binder_id, bound_region.repr(tcx))
738 ty::ReFree(ref fr) => {
739 format!("ReFree({}, {})",
741 fr.bound_region.repr(tcx))
745 format!("ReScope({})", id)
752 ty::ReInfer(ReVar(ref vid)) => {
753 format!("ReInfer({})", vid.id)
756 ty::ReInfer(ReSkolemized(id, ref bound_region)) => {
757 format!("re_skolemized({}, {})",
758 id, bound_region.repr(tcx))
768 impl Repr for ast::DefId {
769 fn repr(&self, tcx: &ctxt) -> ~str {
770 // Unfortunately, there seems to be no way to attempt to print
771 // a path for a def-id, so I'll just make a best effort for now
772 // and otherwise fallback to just printing the crate/node pair
773 if self.krate == ast::LOCAL_CRATE {
775 match tcx.map.find(self.node) {
776 Some(ast_map::NodeItem(..)) |
777 Some(ast_map::NodeForeignItem(..)) |
778 Some(ast_map::NodeMethod(..)) |
779 Some(ast_map::NodeTraitMethod(..)) |
780 Some(ast_map::NodeVariant(..)) |
781 Some(ast_map::NodeStructCtor(..)) => {
782 return format!("{:?}:{}",
784 ty::item_path_str(tcx, *self));
790 return format!("{:?}", *self);
794 impl Repr for ty::ty_param_bounds_and_ty {
795 fn repr(&self, tcx: &ctxt) -> ~str {
796 format!("ty_param_bounds_and_ty \\{generics: {}, ty: {}\\}",
797 self.generics.repr(tcx),
802 impl Repr for ty::Generics {
803 fn repr(&self, tcx: &ctxt) -> ~str {
804 format!("Generics(type_param_defs: {}, region_param_defs: {})",
805 self.type_param_defs().repr(tcx),
806 self.region_param_defs().repr(tcx))
810 impl Repr for ty::ItemVariances {
811 fn repr(&self, tcx: &ctxt) -> ~str {
812 format!("IterVariances(self_param={}, type_params={}, region_params={})",
813 self.self_param.repr(tcx),
814 self.type_params.repr(tcx),
815 self.region_params.repr(tcx))
819 impl Repr for ty::Variance {
820 fn repr(&self, _: &ctxt) -> ~str {
821 self.to_str().to_owned()
825 impl Repr for ty::Method {
826 fn repr(&self, tcx: &ctxt) -> ~str {
827 format!("method(ident: {}, generics: {}, fty: {}, \
828 explicit_self: {}, vis: {}, def_id: {})",
829 self.ident.repr(tcx),
830 self.generics.repr(tcx),
832 self.explicit_self.repr(tcx),
834 self.def_id.repr(tcx))
838 impl Repr for ast::Name {
839 fn repr(&self, _tcx: &ctxt) -> ~str {
840 token::get_name(*self).get().to_str()
844 impl Repr for ast::Ident {
845 fn repr(&self, _tcx: &ctxt) -> ~str {
846 token::get_ident(*self).get().to_str()
850 impl Repr for ast::ExplicitSelf_ {
851 fn repr(&self, _tcx: &ctxt) -> ~str {
852 format!("{:?}", *self)
856 impl Repr for ast::Visibility {
857 fn repr(&self, _tcx: &ctxt) -> ~str {
858 format!("{:?}", *self)
862 impl Repr for ty::BareFnTy {
863 fn repr(&self, tcx: &ctxt) -> ~str {
864 format!("BareFnTy \\{purity: {:?}, abis: {}, sig: {}\\}",
871 impl Repr for ty::FnSig {
872 fn repr(&self, tcx: &ctxt) -> ~str {
873 fn_sig_to_str(tcx, self)
877 impl Repr for typeck::MethodCallee {
878 fn repr(&self, tcx: &ctxt) -> ~str {
879 format!("MethodCallee \\{origin: {}, ty: {}, {}\\}",
880 self.origin.repr(tcx),
882 self.substs.repr(tcx))
886 impl Repr for typeck::MethodOrigin {
887 fn repr(&self, tcx: &ctxt) -> ~str {
889 &typeck::MethodStatic(def_id) => {
890 format!("MethodStatic({})", def_id.repr(tcx))
892 &typeck::MethodParam(ref p) => {
895 &typeck::MethodObject(ref p) => {
902 impl Repr for typeck::MethodParam {
903 fn repr(&self, tcx: &ctxt) -> ~str {
904 format!("MethodParam({},{:?},{:?},{:?})",
905 self.trait_id.repr(tcx),
912 impl Repr for typeck::MethodObject {
913 fn repr(&self, tcx: &ctxt) -> ~str {
914 format!("MethodObject({},{:?},{:?})",
915 self.trait_id.repr(tcx),
922 impl Repr for ty::RegionVid {
923 fn repr(&self, _tcx: &ctxt) -> ~str {
924 format!("{:?}", *self)
928 impl Repr for ty::TraitStore {
929 fn repr(&self, tcx: &ctxt) -> ~str {
931 &ty::UniqTraitStore => ~"~Trait",
932 &ty::RegionTraitStore(r) => format!("&{} Trait", r.repr(tcx))
937 impl Repr for ty::vstore {
938 fn repr(&self, tcx: &ctxt) -> ~str {
939 vstore_to_str(tcx, *self)
943 impl Repr for ty::BuiltinBound {
944 fn repr(&self, _tcx: &ctxt) -> ~str {
945 format!("{:?}", *self)
949 impl UserString for ty::BuiltinBound {
950 fn user_string(&self, _tcx: &ctxt) -> ~str {
952 ty::BoundStatic => ~"'static",
953 ty::BoundSend => ~"Send",
954 ty::BoundSized => ~"Sized",
955 ty::BoundPod => ~"Pod",
956 ty::BoundShare => ~"Share",
961 impl Repr for ty::BuiltinBounds {
962 fn repr(&self, tcx: &ctxt) -> ~str {
963 self.user_string(tcx)
968 fn repr(&self, tcx: &ctxt) -> ~str {
969 tcx.sess.codemap().span_to_str(*self)
973 impl<A:UserString> UserString for @A {
974 fn user_string(&self, tcx: &ctxt) -> ~str {
975 let this: &A = &**self;
976 this.user_string(tcx)
980 impl UserString for ty::BuiltinBounds {
981 fn user_string(&self, tcx: &ctxt) -> ~str {
982 if self.is_empty() { ~"<no-bounds>" } else {
983 let mut result = Vec::new();
984 for bb in self.iter() {
985 result.push(bb.user_string(tcx));
992 impl UserString for ty::TraitRef {
993 fn user_string(&self, tcx: &ctxt) -> ~str {
994 let base = ty::item_path_str(tcx, self.def_id);
995 if tcx.sess.verbose() && self.substs.self_ty.is_some() {
996 let mut all_tps = self.substs.tps.clone();
997 for &t in self.substs.self_ty.iter() { all_tps.push(t); }
998 parameterized(tcx, base, &self.substs.regions,
999 all_tps.as_slice(), self.def_id, true)
1001 parameterized(tcx, base, &self.substs.regions,
1002 self.substs.tps.as_slice(), self.def_id, true)
1007 impl UserString for ty::t {
1008 fn user_string(&self, tcx: &ctxt) -> ~str {
1009 ty_to_str(tcx, *self)
1013 impl UserString for ast::Ident {
1014 fn user_string(&self, _tcx: &ctxt) -> ~str {
1015 token::get_name(self.name).get().to_owned()
1019 impl Repr for AbiSet {
1020 fn repr(&self, _tcx: &ctxt) -> ~str {
1025 impl UserString for AbiSet {
1026 fn user_string(&self, _tcx: &ctxt) -> ~str {
1031 impl Repr for ty::UpvarId {
1032 fn repr(&self, tcx: &ctxt) -> ~str {
1033 format!("UpvarId({};`{}`;{})",
1035 ty::local_var_name_str(tcx, self.var_id),
1036 self.closure_expr_id)
1040 impl Repr for ast::Mutability {
1041 fn repr(&self, _tcx: &ctxt) -> ~str {
1042 format!("{:?}", *self)
1046 impl Repr for ty::BorrowKind {
1047 fn repr(&self, _tcx: &ctxt) -> ~str {
1048 format!("{:?}", *self)
1052 impl Repr for ty::UpvarBorrow {
1053 fn repr(&self, tcx: &ctxt) -> ~str {
1054 format!("UpvarBorrow({}, {})",
1055 self.kind.repr(tcx),
1056 self.region.repr(tcx))