(index<- )        ./librustc/util/ppaux.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   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::ty::{ReSkolemized, ReVar};
  13  use middle::ty::{BoundRegion, BrAnon, BrNamed};
  14  use middle::ty::{BrFresh, ctxt};
  15  use middle::ty::{mt, t, param_ty};
  16  use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region,
  17                   ReEmpty};
  18  use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
  19  use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
  20  use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_self, ty_tup};
  21  use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
  22  use middle::ty;
  23  use middle::typeck;
  24  
  25  use std::rc::Rc;
  26  use std::strbuf::StrBuf;
  27  use syntax::abi;
  28  use syntax::ast_map;
  29  use syntax::codemap::{Span, Pos};
  30  use syntax::parse::token;
  31  use syntax::print::pprust;
  32  use syntax::{ast, ast_util};
  33  use syntax::owned_slice::OwnedSlice;
  34  
  35  /// Produces a string suitable for debugging output.
  36  pub trait Repr {
  37      fn repr(&self, tcx: &ctxt) -> ~str;
  38  }
  39  
  40  /// Produces a string suitable for showing to the user.
  41  pub trait UserString {
  42      fn user_string(&self, tcx: &ctxt) -> ~str;
  43  }
  44  
  45  pub fn note_and_explain_region(cx: &ctxt,
  46                                 prefix: &str,
  47                                 regionty::Region,
  48                                 suffix: &str) {
  49      match explain_region_and_span(cx, region) {
  50        (ref str, Some(span)) => {
  51          cx.sess.span_note(
  52              span,
  53              format!("{}{}{}", prefix, *str, suffix));
  54        }
  55        (ref str, None) => {
  56          cx.sess.note(
  57              format!("{}{}{}", prefix, *str, suffix));
  58        }
  59      }
  60  }
  61  
  62  pub fn explain_region_and_span(cx: &ctxt, regionty::Region)
  63                              -> (~str, Option<Span>) {
  64      return match region {
  65        ReScope(node_id) => {
  66          match cx.map.find(node_id) {
  67            Some(ast_map::NodeBlock(ref blk)) => {
  68              explain_span(cx, "block", blk.span)
  69            }
  70            Some(ast_map::NodeExpr(expr)) => {
  71              match expr.node {
  72                ast::ExprCall(..) => explain_span(cx, "call", expr.span),
  73                ast::ExprMethodCall(..) => {
  74                  explain_span(cx, "method call", expr.span)
  75                },
  76                ast::ExprMatch(..) => explain_span(cx, "match", expr.span),
  77                _ => explain_span(cx, "expression", expr.span)
  78              }
  79            }
  80            Some(ast_map::NodeStmt(stmt)) => {
  81                explain_span(cx, "statement", stmt.span)
  82            }
  83            Some(ast_map::NodeItem(it)) if (match it.node {
  84                  ast::ItemFn(..) => true, _ => false}) => {
  85                explain_span(cx, "function body", it.span)
  86            }
  87            Some(_) | None => {
  88              // this really should not happen
  89              (format!("unknown scope: {}.  Please report a bug.", node_id),
  90               None)
  91            }
  92          }
  93        }
  94  
  95        ReFree(ref fr) => {
  96          let prefix = match fr.bound_region {
  97            BrAnon(idx) => format!("the anonymous lifetime \\#{} defined on",
  98                                 idx + 1),
  99            BrFresh(_) => format!("an anonymous lifetime defined on"),
 100            _ => format!("the lifetime {} as defined on",
 101                      bound_region_ptr_to_str(cx, fr.bound_region))
 102          };
 103  
 104          match cx.map.find(fr.scope_id) {
 105            Some(ast_map::NodeBlock(ref blk)) => {
 106              let (msg, opt_span) = explain_span(cx, "block", blk.span);
 107              (format!("{} {}", prefix, msg), opt_span)
 108            }
 109            Some(ast_map::NodeItem(it)) if match it.node {
 110                  ast::ItemImpl(..) => true, _ => false} => {
 111              let (msg, opt_span) = explain_span(cx, "impl", it.span);
 112              (format!("{} {}", prefix, msg), opt_span)
 113            }
 114            Some(_) | None => {
 115              // this really should not happen
 116              (format!("{} node {}", prefix, fr.scope_id), None)
 117            }
 118          }
 119        }
 120  
 121        ReStatic => { ("the static lifetime".to_owned(), None) }
 122  
 123        ReEmpty => { ("the empty lifetime".to_owned(), None) }
 124  
 125        // I believe these cases should not occur (except when debugging,
 126        // perhaps)
 127        ty::ReInfer(_) | ty::ReEarlyBound(..) | ty::ReLateBound(..) => {
 128          (format!("lifetime {:?}", region), None)
 129        }
 130      };
 131  
 132      fn explain_span(cx&ctxt, heading&str, spanSpan)
 133          -> (~str, Option<Span>) {
 134          let lo = cx.sess.codemap().lookup_char_pos_adj(span.lo);
 135          (format!("the {} at {}:{}", heading,
 136                lo.line, lo.col.to_uint()), Some(span))
 137      }
 138  }
 139  
 140  pub fn bound_region_ptr_to_str(cx: &ctxt, brBoundRegion) -> ~str {
 141      bound_region_to_str(cx, "&", true, br)
 142  }
 143  
 144  pub fn bound_region_to_str(cx: &ctxt,
 145                             prefix: &str, space: bool,
 146                             brBoundRegion) -> ~str {
 147      let space_str = if space { " " } else { "" };
 148  
 149      if cx.sess.verbose() {
 150          return format!("{}{}{}", prefix, br.repr(cx), space_str);
 151      }
 152  
 153      match br {
 154          BrNamed(_, name)   => format!("{}'{}{}", prefix,
 155                                        token::get_name(name), space_str),
 156          BrAnon(_)           => prefix.to_str(),
 157          BrFresh(_)          => prefix.to_str(),
 158      }
 159  }
 160  
 161  // In general, if you are giving a region error message,
 162  // you should use `explain_region()` or, better yet,
 163  // `note_and_explain_region()`
 164  pub fn region_ptr_to_str(cx: &ctxt, regionRegion) -> ~str {
 165      region_to_str(cx, "&", true, region)
 166  }
 167  
 168  pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, regionRegion) -> ~str {
 169      let space_str = if space { " " } else { "" };
 170  
 171      if cx.sess.verbose() {
 172          return format!("{}{}{}", prefix, region.repr(cx), space_str);
 173      }
 174  
 175      // These printouts are concise.  They do not contain all the information
 176      // the user might want to diagnose an error, but there is basically no way
 177      // to fit that into a short string.  Hence the recommendation to use
 178      // `explain_region()` or `note_and_explain_region()`.
 179      match region {
 180          ty::ReScope(_) => prefix.to_str(),
 181          ty::ReEarlyBound(_, _, name) => token::get_name(name).get().to_str(),
 182          ty::ReLateBound(_, br) => bound_region_to_str(cx, prefix, space, br),
 183          ty::ReFree(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region),
 184          ty::ReInfer(ReSkolemized(_, br)) => {
 185              bound_region_to_str(cx, prefix, space, br)
 186          }
 187          ty::ReInfer(ReVar(_)) => prefix.to_str(),
 188          ty::ReStatic => format!("{}'static{}", prefix, space_str),
 189          ty::ReEmpty => format!("{}'<empty>{}", prefix, space_str)
 190      }
 191  }
 192  
 193  pub fn mutability_to_str(mast::Mutability) -> ~str {
 194      match m {
 195          ast::MutMutable => "mut ".to_owned(),
 196          ast::MutImmutable => "".to_owned(),
 197      }
 198  }
 199  
 200  pub fn mt_to_str(cx: &ctxt, m: &mt) -> ~str {
 201      format!("{}{}", mutability_to_str(m.mutbl), ty_to_str(cx, m.ty))
 202  }
 203  
 204  pub fn trait_store_to_str(cx: &ctxt, sty::TraitStore) -> ~str {
 205      match s {
 206          ty::UniqTraitStore => "Box ".to_owned(),
 207          ty::RegionTraitStore(r, m) => {
 208              format!("{}{}", region_ptr_to_str(cx, r), mutability_to_str(m))
 209          }
 210      }
 211  }
 212  
 213  pub fn vec_map_to_str<T>(ts: &[T], f: |t: &T-> ~str) -> ~str {
 214      let tstrs = ts.iter().map(f).collect::<Vec<~str>>();
 215      format!("[{}]", tstrs.connect(", "))
 216  }
 217  
 218  pub fn fn_sig_to_str(cx: &ctxt, typ: &ty::FnSig) -> ~str {
 219      format!("fn{}{} -> {}",
 220              typ.binder_id,
 221              typ.inputs.repr(cx),
 222              typ.output.repr(cx))
 223  }
 224  
 225  pub fn trait_ref_to_str(cx: &ctxt, trait_ref: &ty::TraitRef) -> ~str {
 226      trait_ref.user_string(cx)
 227  }
 228  
 229  pub fn ty_to_str(cx: &ctxt, typt) -> ~str {
 230      fn fn_input_to_str(cx: &ctxt, inputty::t) -> ~str {
 231          ty_to_str(cx, input)
 232      }
 233      fn bare_fn_to_str(cx&ctxt,
 234                        fn_styleast::FnStyle,
 235                        abiabi::Abi,
 236                        identOption<ast::Ident>,
 237                        sig&ty::FnSig)
 238                        -> ~str {
 239          let mut s = if abi == abi::Rust {
 240              StrBuf::new()
 241          } else {
 242              StrBuf::from_owned_str(format!("extern {} ", abi.to_str()))
 243          };
 244  
 245          match fn_style {
 246              ast::NormalFn => {}
 247              _ => {
 248                  s.push_str(fn_style.to_str());
 249                  s.push_char(' ');
 250              }
 251          };
 252  
 253          s.push_str("fn");
 254  
 255          match ident {
 256              Some(i) => {
 257                  s.push_char(' ');
 258                  s.push_str(token::get_ident(i).get());
 259              }
 260              _ => { }
 261          }
 262  
 263          push_sig_to_str(cx, &mut s, '(', ')', sig);
 264  
 265          s.into_owned()
 266      }
 267  
 268      fn closure_to_str(cx&ctxt, cty&ty::ClosureTy) -> ~str {
 269          let mut s = StrBuf::new();
 270  
 271          match cty.store {
 272              ty::UniqTraitStore => {}
 273              ty::RegionTraitStore(region, _) => {
 274                  s.push_str(region_to_str(cx, "", true, region));
 275              }
 276          }
 277  
 278          match cty.fn_style {
 279              ast::NormalFn => {}
 280              _ => {
 281                  s.push_str(cty.fn_style.to_str());
 282                  s.push_char(' ');
 283              }
 284          };
 285  
 286          match cty.store {
 287              ty::UniqTraitStore => {
 288                  assert_eq!(cty.onceness, ast::Once);
 289                  s.push_str("proc");
 290                  push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
 291              }
 292              ty::RegionTraitStore(..) => {
 293                  match cty.onceness {
 294                      ast::Many => {}
 295                      ast::Once => s.push_str("once ")
 296                  }
 297                  push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
 298              }
 299          }
 300  
 301          if !cty.bounds.is_empty() {
 302              s.push_str(":");
 303              s.push_str(cty.bounds.repr(cx));
 304          }
 305  
 306          s.into_owned()
 307      }
 308  
 309      fn push_sig_to_str(cx: &ctxt,
 310                         s&mut StrBuf,
 311                         bra: char,
 312                         ketchar,
 313                         sig&ty::FnSig) {
 314          s.push_char(bra);
 315          let strsVec<~str> = sig.inputs.iter().map(|a| fn_input_to_str(cx, *a)).collect();
 316          s.push_str(strs.connect(", "));
 317          if sig.variadic {
 318              s.push_str(", ...");
 319          }
 320          s.push_char(ket);
 321  
 322          if ty::get(sig.output).sty != ty_nil {
 323              s.push_str(-> ");
 324              if ty::type_is_bot(sig.output) {
 325                  s.push_char('!');
 326              } else {
 327                  s.push_str(ty_to_str(cx, sig.output));
 328              }
 329          }
 330      }
 331  
 332      // if there is an id, print that instead of the structural type:
 333      /*for def_id in ty::type_def_id(typ).iter() {
 334          // note that this typedef cannot have type parameters
 335          return ty::item_path_str(cx, *def_id);
 336      }*/
 337  
 338      // pretty print the structural type representation:
 339      return match ty::get(typ).sty {
 340        ty_nil => "()".to_owned(),
 341        ty_bot => "!".to_owned(),
 342        ty_bool => "bool".to_owned(),
 343        ty_char => "char".to_owned(),
 344        ty_int(t) => ast_util::int_ty_to_str(t, None).to_owned(),
 345        ty_uint(t) => ast_util::uint_ty_to_str(t, None).to_owned(),
 346        ty_float(t) => ast_util::float_ty_to_str(t).to_owned(),
 347        ty_box(typ) => "@".to_owned() + ty_to_str(cx, typ),
 348        ty_uniq(typ) => "~".to_owned() + ty_to_str(cx, typ),
 349        ty_ptr(ref tm) => "*".to_owned() + mt_to_str(cx, tm),
 350        ty_rptr(r, ref tm) => {
 351          region_ptr_to_str(cx, r) + mt_to_str(cx, tm)
 352        }
 353        ty_tup(ref elems) => {
 354          let strsVec<~str> = elems.iter().map(|elem| ty_to_str(cx, *elem)).collect();
 355          "(".to_owned() + strs.connect(",") + ")"
 356        }
 357        ty_closure(ref f) => {
 358            closure_to_str(cx, *f)
 359        }
 360        ty_bare_fn(ref f) => {
 361            bare_fn_to_str(cx, f.fn_style, f.abi, None, &f.sig)
 362        }
 363        ty_infer(infer_ty) => infer_ty.to_str(),
 364        ty_err => "[type error]".to_owned(),
 365        ty_param(param_ty {idx: id, def_id: did}) => {
 366            let ident = match cx.ty_param_defs.borrow().find(&did.node) {
 367                Some(def) => token::get_ident(def.ident).get().to_str(),
 368                // This can only happen when a type mismatch error happens and
 369                // the actual type has more type parameters than the expected one.
 370                None => format!("<generic \\#{}>", id)
 371            };
 372            if !cx.sess.verbose() {
 373                ident
 374            } else {
 375              format!("{}:{:?}", ident, did)
 376            }
 377        }
 378        ty_self(..) => "Self".to_owned(),
 379        ty_enum(did, ref substs) | ty_struct(did, ref substs) => {
 380          let base = ty::item_path_str(cx, did);
 381          parameterized(cx,
 382                        base,
 383                        &substs.regions,
 384                        substs.tps.as_slice(),
 385                        did,
 386                        false)
 387        }
 388        ty_trait(box ty::TyTrait {
 389            def_id: did, ref substs, store, ref bounds
 390        }) => {
 391          let base = ty::item_path_str(cx, did);
 392          let ty = parameterized(cx, base, &substs.regions,
 393                                 substs.tps.as_slice(), did, true);
 394          let bound_sep = if bounds.is_empty() { "" } else { ":" };
 395          let bound_str = bounds.repr(cx);
 396          format!("{}{}{}{}", trait_store_to_str(cx, store), ty, bound_sep, bound_str)
 397        }
 398        ty_str => "str".to_owned(),
 399        ty_vec(ref mt, sz) => {
 400            match sz {
 401                Some(n) => format!("[{}, .. {}]", mt_to_str(cx, mt), n),
 402                None => format!("[{}]", ty_to_str(cx, mt.ty)),
 403            }
 404        }
 405      }
 406  }
 407  
 408  pub fn parameterized(cx: &ctxt,
 409                       base: &str,
 410                       regions: &ty::RegionSubsts,
 411                       tps: &[ty::t],
 412                       didast::DefId,
 413                       is_trait: bool) -> ~str {
 414  
 415      let mut strs = Vec::new();
 416      match *regions {
 417          ty::ErasedRegions => { }
 418          ty::NonerasedRegions(ref regions) => {
 419              for &r in regions.iter() {
 420                  strs.push(region_to_str(cx, "", false, r))
 421              }
 422          }
 423      }
 424  
 425      let generics = if is_trait {
 426          ty::lookup_trait_def(cx, did).generics.clone()
 427      } else {
 428          ty::lookup_item_type(cx, did).generics
 429      };
 430      let ty_params = generics.type_param_defs();
 431      let has_defaults = ty_params.last().map_or(false, |def| def.default.is_some());
 432      let num_defaults = if has_defaults {
 433          // We should have a borrowed version of substs instead of cloning.
 434          let mut substs = ty::substs {
 435              tps: Vec::from_slice(tps),
 436              regions: regions.clone(),
 437              self_ty: None
 438          };
 439          ty_params.iter().zip(tps.iter()).rev().take_while(|&(def, &actual)| {
 440              substs.tps.pop();
 441              match def.default {
 442                  Some(default) => ty::subst(cx, &substs, default) == actual,
 443                  None => false
 444              }
 445          }).len()
 446      } else {
 447          0
 448      };
 449  
 450      for t in tps.slice_to(tps.len() - num_defaults).iter() {
 451          strs.push(ty_to_str(cx, *t))
 452      }
 453  
 454      if strs.len() > 0u {
 455          format!("{}<{}>", base, strs.connect(","))
 456      } else {
 457          format!("{}", base)
 458      }
 459  }
 460  
 461  pub fn ty_to_short_str(cx: &ctxt, typt) -> ~str {
 462      let mut s = typ.repr(cx);
 463      if s.len() >= 32u { s = s.slice(0u, 32u).to_owned(); }
 464      return s;
 465  }
 466  
 467  impl<T:Repr> Repr for Option<T> {
 468      fn repr(&self, tcx&ctxt) -> ~str {
 469          match self {
 470              &None => "None".to_owned(),
 471              &Some(ref t) => t.repr(tcx),
 472          }
 473      }
 474  }
 475  
 476  impl<T:Repr,U:Repr> Repr for Result<T,U> {
 477      fn repr(&self, tcx&ctxt) -> ~str {
 478          match self {
 479              &Ok(ref t) => t.repr(tcx),
 480              &Err(ref u) => format!("Err({})", u.repr(tcx))
 481          }
 482      }
 483  }
 484  
 485  impl Repr for () {
 486      fn repr(&self, _tcx&ctxt) -> ~str {
 487          "()".to_owned()
 488      }
 489  }
 490  
 491  impl<T:Repr> Repr for Rc<T> {
 492      fn repr(&self, tcx&ctxt) -> ~str {
 493          (&**self).repr(tcx)
 494      }
 495  }
 496  
 497  impl<T:Repr> Repr for @T {
 498      fn repr(&self, tcx&ctxt) -> ~str {
 499          (&**self).repr(tcx)
 500      }
 501  }
 502  
 503  impl<T:Repr> Repr for Box<T> {
 504      fn repr(&self, tcx&ctxt) -> ~str {
 505          (&**self).repr(tcx)
 506      }
 507  }
 508  
 509  fn repr_vec<T:Repr>(tcx: &ctxt, v: &[T]) -> ~str {
 510      vec_map_to_str(v, |t| t.repr(tcx))
 511  }
 512  
 513  impl<'a, T:Repr> Repr for &'a [T{
 514      fn repr(&self, tcx&ctxt) -> ~str {
 515          repr_vec(tcx, *self)
 516      }
 517  }
 518  
 519  impl<T:Repr> Repr for OwnedSlice<T> {
 520      fn repr(&self, tcx&ctxt) -> ~str {
 521          repr_vec(tcx, self.as_slice())
 522      }
 523  }
 524  
 525  // This is necessary to handle types like Option<~[T]>, for which
 526  // autoderef cannot convert the &[T] handler
 527  impl<T:Repr> Repr for Vec<T> {
 528      fn repr(&self, tcx&ctxt) -> ~str {
 529          repr_vec(tcx, self.as_slice())
 530      }
 531  }
 532  
 533  impl Repr for ty::TypeParameterDef {
 534      fn repr(&self, tcx&ctxt) -> ~str {
 535          format!("TypeParameterDef({:?}, {})",
 536                  self.def_id,
 537                  self.bounds.repr(tcx))
 538      }
 539  }
 540  
 541  impl Repr for ty::RegionParameterDef {
 542      fn repr(&self, _tcx&ctxt) -> ~str {
 543          format!("RegionParameterDef({}, {:?})",
 544                  token::get_name(self.name),
 545                  self.def_id)
 546      }
 547  }
 548  
 549  impl Repr for ty::t {
 550      fn repr(&self, tcx&ctxt) -> ~str {
 551          ty_to_str(tcx, *self)
 552      }
 553  }
 554  
 555  impl Repr for ty::substs {
 556      fn repr(&self, tcx&ctxt) -> ~str {
 557          format!("substs(regions={}, self_ty={}, tps={})",
 558               self.regions.repr(tcx),
 559               self.self_ty.repr(tcx),
 560               self.tps.repr(tcx))
 561      }
 562  }
 563  
 564  impl Repr for ty::RegionSubsts {
 565      fn repr(&self, tcx&ctxt) -> ~str {
 566          match *self {
 567              ty::ErasedRegions => "erased".to_owned(),
 568              ty::NonerasedRegions(ref regions) => regions.repr(tcx)
 569          }
 570      }
 571  }
 572  
 573  impl Repr for ty::ParamBounds {
 574      fn repr(&self, tcx&ctxt) -> ~str {
 575          let mut res = Vec::new();
 576          for b in self.builtin_bounds.iter() {
 577              res.push(match b {
 578                  ty::BoundStatic => "'static".to_owned(),
 579                  ty::BoundSend => "Send".to_owned(),
 580                  ty::BoundSized => "Sized".to_owned(),
 581                  ty::BoundCopy => "Pod".to_owned(),
 582                  ty::BoundShare => "Share".to_owned(),
 583              });
 584          }
 585          for t in self.trait_bounds.iter() {
 586              res.push(t.repr(tcx));
 587          }
 588          res.connect("+")
 589      }
 590  }
 591  
 592  impl Repr for ty::TraitRef {
 593      fn repr(&self, tcx&ctxt) -> ~str {
 594          trait_ref_to_str(tcx, self)
 595      }
 596  }
 597  
 598  impl Repr for ast::Expr {
 599      fn repr(&self, _tcx&ctxt) -> ~str {
 600          format!("expr({}{})", self.id, pprust::expr_to_str(self))
 601      }
 602  }
 603  
 604  impl Repr for ast::Item {
 605      fn repr(&self, tcx&ctxt) -> ~str {
 606          format!("item({})", tcx.map.node_to_str(self.id))
 607      }
 608  }
 609  
 610  impl Repr for ast::Stmt {
 611      fn repr(&self, _tcx&ctxt) -> ~str {
 612          format!("stmt({}{})",
 613                  ast_util::stmt_id(self),
 614                  pprust::stmt_to_str(self))
 615      }
 616  }
 617  
 618  impl Repr for ast::Pat {
 619      fn repr(&self, _tcx&ctxt) -> ~str {
 620          format!("pat({}{})",
 621               self.id,
 622               pprust::pat_to_str(self))
 623      }
 624  }
 625  
 626  impl Repr for ty::BoundRegion {
 627      fn repr(&self, tcx&ctxt) -> ~str {
 628          match *self {
 629              ty::BrAnon(id) => format!("BrAnon({})", id),
 630              ty::BrNamed(id, name) => format!("BrNamed({}, {})",
 631                                               id.repr(tcx),
 632                                               token::get_name(name)),
 633              ty::BrFresh(id) => format!("BrFresh({})", id),
 634          }
 635      }
 636  }
 637  
 638  impl Repr for ty::Region {
 639      fn repr(&self, tcx&ctxt) -> ~str {
 640          match *self {
 641              ty::ReEarlyBound(id, index, name) => {
 642                  format!("ReEarlyBound({}, {}, {})",
 643                          id, index, token::get_name(name))
 644              }
 645  
 646              ty::ReLateBound(binder_id, ref bound_region) => {
 647                  format!("ReLateBound({}, {})",
 648                          binder_id, bound_region.repr(tcx))
 649              }
 650  
 651              ty::ReFree(ref fr) => {
 652                  format!("ReFree({}, {})",
 653                          fr.scope_id,
 654                          fr.bound_region.repr(tcx))
 655              }
 656  
 657              ty::ReScope(id) => {
 658                  format!("ReScope({})", id)
 659              }
 660  
 661              ty::ReStatic => {
 662                  format!("ReStatic")
 663              }
 664  
 665              ty::ReInfer(ReVar(ref vid)) => {
 666                  format!("ReInfer({})", vid.id)
 667              }
 668  
 669              ty::ReInfer(ReSkolemized(id, ref bound_region)) => {
 670                  format!("re_skolemized({}, {})",
 671                          id, bound_region.repr(tcx))
 672              }
 673  
 674              ty::ReEmpty => {
 675                  format!("ReEmpty")
 676              }
 677          }
 678      }
 679  }
 680  
 681  impl Repr for ast::DefId {
 682      fn repr(&self, tcx&ctxt) -> ~str {
 683          // Unfortunately, there seems to be no way to attempt to print
 684          // a path for a def-id, so I'll just make a best effort for now
 685          // and otherwise fallback to just printing the crate/node pair
 686          if self.krate == ast::LOCAL_CRATE {
 687              {
 688                  match tcx.map.find(self.node) {
 689                      Some(ast_map::NodeItem(..)) |
 690                      Some(ast_map::NodeForeignItem(..)) |
 691                      Some(ast_map::NodeMethod(..)) |
 692                      Some(ast_map::NodeTraitMethod(..)) |
 693                      Some(ast_map::NodeVariant(..)) |
 694                      Some(ast_map::NodeStructCtor(..)) => {
 695                          return format!("{:?}:{}",
 696                                         *self,
 697                                         ty::item_path_str(tcx, *self));
 698                      }
 699                      _ => {}
 700                  }
 701              }
 702          }
 703          return format!("{:?}", *self);
 704      }
 705  }
 706  
 707  impl Repr for ty::ty_param_bounds_and_ty {
 708      fn repr(&self, tcx&ctxt) -> ~str {
 709          format!("ty_param_bounds_and_ty \\{generics: {}, ty: {}\\}",
 710               self.generics.repr(tcx),
 711               self.ty.repr(tcx))
 712      }
 713  }
 714  
 715  impl Repr for ty::Generics {
 716      fn repr(&self, tcx&ctxt) -> ~str {
 717          format!("Generics(type_param_defs: {}, region_param_defs: {})",
 718                  self.type_param_defs().repr(tcx),
 719                  self.region_param_defs().repr(tcx))
 720      }
 721  }
 722  
 723  impl Repr for ty::ItemVariances {
 724      fn repr(&self, tcx&ctxt) -> ~str {
 725          format!("IterVariances(self_param={}, type_params={}, region_params={})",
 726                  self.self_param.repr(tcx),
 727                  self.type_params.repr(tcx),
 728                  self.region_params.repr(tcx))
 729      }
 730  }
 731  
 732  impl Repr for ty::Variance {
 733      fn repr(&self, _&ctxt) -> ~str {
 734          self.to_str().to_owned()
 735      }
 736  }
 737  
 738  impl Repr for ty::Method {
 739      fn repr(&self, tcx&ctxt) -> ~str {
 740          format!("method(ident: {}, generics: {}, fty: {}, \
 741                  explicit_self: {}, vis: {}, def_id: {})",
 742                  self.ident.repr(tcx),
 743                  self.generics.repr(tcx),
 744                  self.fty.repr(tcx),
 745                  self.explicit_self.repr(tcx),
 746                  self.vis.repr(tcx),
 747                  self.def_id.repr(tcx))
 748      }
 749  }
 750  
 751  impl Repr for ast::Name {
 752      fn repr(&self, _tcx&ctxt) -> ~str {
 753          token::get_name(*self).get().to_str()
 754      }
 755  }
 756  
 757  impl Repr for ast::Ident {
 758      fn repr(&self, _tcx&ctxt) -> ~str {
 759          token::get_ident(*self).get().to_str()
 760      }
 761  }
 762  
 763  impl Repr for ast::ExplicitSelf_ {
 764      fn repr(&self, _tcx&ctxt) -> ~str {
 765          format!("{:?}", *self)
 766      }
 767  }
 768  
 769  impl Repr for ast::Visibility {
 770      fn repr(&self, _tcx&ctxt) -> ~str {
 771          format!("{:?}", *self)
 772      }
 773  }
 774  
 775  impl Repr for ty::BareFnTy {
 776      fn repr(&self, tcx&ctxt) -> ~str {
 777          format!("BareFnTy \\{fn_style: {:?}, abi: {}, sig: {}\\}",
 778               self.fn_style,
 779               self.abi.to_str(),
 780               self.sig.repr(tcx))
 781      }
 782  }
 783  
 784  impl Repr for ty::FnSig {
 785      fn repr(&self, tcx&ctxt) -> ~str {
 786          fn_sig_to_str(tcx, self)
 787      }
 788  }
 789  
 790  impl Repr for typeck::MethodCallee {
 791      fn repr(&self, tcx&ctxt) -> ~str {
 792          format!("MethodCallee \\{origin: {}, ty: {}, {}\\}",
 793              self.origin.repr(tcx),
 794              self.ty.repr(tcx),
 795              self.substs.repr(tcx))
 796      }
 797  }
 798  
 799  impl Repr for typeck::MethodOrigin {
 800      fn repr(&self, tcx&ctxt) -> ~str {
 801          match self {
 802              &typeck::MethodStatic(def_id) => {
 803                  format!("MethodStatic({})", def_id.repr(tcx))
 804              }
 805              &typeck::MethodParam(ref p) => {
 806                  p.repr(tcx)
 807              }
 808              &typeck::MethodObject(ref p) => {
 809                  p.repr(tcx)
 810              }
 811          }
 812      }
 813  }
 814  
 815  impl Repr for typeck::MethodParam {
 816      fn repr(&self, tcx&ctxt) -> ~str {
 817          format!("MethodParam({},{:?},{:?},{:?})",
 818               self.trait_id.repr(tcx),
 819               self.method_num,
 820               self.param_num,
 821               self.bound_num)
 822      }
 823  }
 824  
 825  impl Repr for typeck::MethodObject {
 826      fn repr(&self, tcx&ctxt) -> ~str {
 827          format!("MethodObject({},{:?},{:?})",
 828               self.trait_id.repr(tcx),
 829               self.method_num,
 830               self.real_index)
 831      }
 832  }
 833  
 834  
 835  impl Repr for ty::RegionVid {
 836      fn repr(&self, _tcx&ctxt) -> ~str {
 837          format!("{:?}", *self)
 838      }
 839  }
 840  
 841  impl Repr for ty::TraitStore {
 842      fn repr(&self, tcx&ctxt) -> ~str {
 843          trait_store_to_str(tcx, *self)
 844      }
 845  }
 846  
 847  impl Repr for ty::BuiltinBound {
 848      fn repr(&self, _tcx&ctxt) -> ~str {
 849          format!("{:?}", *self)
 850      }
 851  }
 852  
 853  impl UserString for ty::BuiltinBound {
 854      fn user_string(&self, _tcx&ctxt) -> ~str {
 855          match *self {
 856              ty::BoundStatic => "'static".to_owned(),
 857              ty::BoundSend => "Send".to_owned(),
 858              ty::BoundSized => "Sized".to_owned(),
 859              ty::BoundCopy => "Pod".to_owned(),
 860              ty::BoundShare => "Share".to_owned(),
 861          }
 862      }
 863  }
 864  
 865  impl Repr for ty::BuiltinBounds {
 866      fn repr(&self, tcx&ctxt) -> ~str {
 867          self.user_string(tcx)
 868      }
 869  }
 870  
 871  impl Repr for Span {
 872      fn repr(&self, tcx&ctxt) -> ~str {
 873          tcx.sess.codemap().span_to_str(*self).to_owned()
 874      }
 875  }
 876  
 877  impl<A:UserString> UserString for Rc<A> {
 878      fn user_string(&self, tcx&ctxt) -> ~str {
 879          let this&A = &**self;
 880          this.user_string(tcx)
 881      }
 882  }
 883  
 884  impl UserString for ty::BuiltinBounds {
 885      fn user_string(&self, tcx&ctxt) -> ~str {
 886          if self.is_empty() { "<no-bounds>".to_owned() } else {
 887              let mut result = Vec::new();
 888              for bb in self.iter() {
 889                  result.push(bb.user_string(tcx));
 890              }
 891              result.connect("+")
 892          }
 893      }
 894  }
 895  
 896  impl UserString for ty::TraitRef {
 897      fn user_string(&self, tcx&ctxt) -> ~str {
 898          let base = ty::item_path_str(tcx, self.def_id);
 899          if tcx.sess.verbose() && self.substs.self_ty.is_some() {
 900              let mut all_tps = self.substs.tps.clone();
 901              for &t in self.substs.self_ty.iter() { all_tps.push(t); }
 902              parameterized(tcx, base, &self.substs.regions,
 903                            all_tps.as_slice(), self.def_id, true)
 904          } else {
 905              parameterized(tcx, base, &self.substs.regions,
 906                            self.substs.tps.as_slice(), self.def_id, true)
 907          }
 908      }
 909  }
 910  
 911  impl UserString for ty::t {
 912      fn user_string(&self, tcx&ctxt) -> ~str {
 913          ty_to_str(tcx, *self)
 914      }
 915  }
 916  
 917  impl UserString for ast::Ident {
 918      fn user_string(&self, _tcx&ctxt) -> ~str {
 919          token::get_name(self.name).get().to_owned()
 920      }
 921  }
 922  
 923  impl Repr for abi::Abi {
 924      fn repr(&self, _tcx&ctxt) -> ~str {
 925          self.to_str()
 926      }
 927  }
 928  
 929  impl UserString for abi::Abi {
 930      fn user_string(&self, _tcx&ctxt) -> ~str {
 931          self.to_str()
 932      }
 933  }
 934  
 935  impl Repr for ty::UpvarId {
 936      fn repr(&self, tcx&ctxt) -> ~str {
 937          format!("UpvarId({};`{}`;{})",
 938               self.var_id,
 939               ty::local_var_name_str(tcx, self.var_id),
 940               self.closure_expr_id)
 941      }
 942  }
 943  
 944  impl Repr for ast::Mutability {
 945      fn repr(&self, _tcx&ctxt) -> ~str {
 946          format!("{:?}", *self)
 947      }
 948  }
 949  
 950  impl Repr for ty::BorrowKind {
 951      fn repr(&self, _tcx&ctxt) -> ~str {
 952          format!("{:?}", *self)
 953      }
 954  }
 955  
 956  impl Repr for ty::UpvarBorrow {
 957      fn repr(&self, tcx&ctxt) -> ~str {
 958          format!("UpvarBorrow({}, {})",
 959               self.kind.repr(tcx),
 960               self.region.repr(tcx))
 961      }
 962  }


librustc/util/ppaux.rs:508:1-508:1 -fn- definition:
fn repr_vec<T:Repr>(tcx: &ctxt, v: &[T]) -> ~str {
    vec_map_to_str(v, |t| t.repr(tcx))
}
references:- 3
528:     fn repr(&self, tcx: &ctxt) -> ~str {
529:         repr_vec(tcx, self.as_slice())
530:     }


librustc/util/ppaux.rs:167:1-167:1 -fn- definition:
pub fn region_to_str(cx: &ctxt, prefix: &str, space: bool, region: Region) -> ~str {
    let space_str = if space { " " } else { "" };
    if cx.sess.verbose() {
references:- 4
273:             ty::RegionTraitStore(region, _) => {
274:                 s.push_str(region_to_str(cx, "", true, region));
275:             }
librustc/middle/typeck/check/regionck.rs:
1003:     debug!("constrain_regions_in_type(minimum_lifetime={}, ty={})",
1004:            region_to_str(tcx, "", false, minimum_lifetime),
1005:            ty_to_str(tcx, ty));
librustc/util/ppaux.rs:
419:             for &r in regions.iter() {
420:                 strs.push(region_to_str(cx, "", false, r))
421:             }


librustc/util/ppaux.rs:139:1-139:1 -fn- definition:
pub fn bound_region_ptr_to_str(cx: &ctxt, br: BoundRegion) -> ~str {
    bound_region_to_str(cx, "&", true, br)
}
references:- 3
100:           _ => format!("the lifetime {} as defined on",
101:                     bound_region_ptr_to_str(cx, fr.bound_region))
102:         };
librustc/middle/ty.rs:
3362:                   but found concrete lifetime",
3363:                  bound_region_ptr_to_str(cx, br))
3364:         }
--
3367:                   but found bound lifetime parameter {}",
3368:                  bound_region_ptr_to_str(cx, br))
3369:         }


librustc/util/ppaux.rs:143:1-143:1 -fn- definition:
pub fn bound_region_to_str(cx: &ctxt,
                           prefix: &str, space: bool,
                           br: BoundRegion) -> ~str {
references:- 8
182:         ty::ReLateBound(_, br) => bound_region_to_str(cx, prefix, space, br),
183:         ty::ReFree(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region),
184:         ty::ReInfer(ReSkolemized(_, br)) => {
185:             bound_region_to_str(cx, prefix, space, br)
186:         }
librustc/middle/typeck/infer/sub.rs:
179:                 debug!("Bound region {} skolemized to {:?}",
180:                        bound_region_to_str(self.get_ref().infcx.tcx, "", false, br),
181:                        skol);
librustc/middle/typeck/infer/error_reporting.rs:
1225:                 format!(" for {}in function call",
1226:                         bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
1227:             }
--
1229:                 format!(" for {}in function type",
1230:                         bound_region_to_str(self.tcx, "lifetime parameter ", true, br))
1231:             }
librustc/middle/typeck/infer/mod.rs:
798:                 debug!("Bound region {} maps to {:?}",
799:                        bound_region_to_str(self.tcx, "", false, br),
800:                        rvar);


librustc/util/ppaux.rs:224:1-224:1 -fn- definition:
pub fn trait_ref_to_str(cx: &ctxt, trait_ref: &ty::TraitRef) -> ~str {
    trait_ref.user_string(cx)
}
references:- 6
593:     fn repr(&self, tcx: &ctxt) -> ~str {
594:         trait_ref_to_str(tcx, self)
595:     }
librustc/middle/typeck/check/vtable.rs:
207:                     format!("expected {}, but found {} ({})",
208:                          ppaux::trait_ref_to_str(tcx, &r_exp_trait_ref),
209:                          ppaux::trait_ref_to_str(tcx, &r_act_trait_ref),
librustc/middle/typeck/infer/mod.rs:
663:         let t = self.resolve_type_vars_in_trait_ref_if_possible(t);
664:         trait_ref_to_str(self.tcx, &t)
665:     }
librustc/middle/typeck/infer/to_str.rs:
91:     fn inf_str(&self, cx: &InferCtxt) -> ~str {
92:         trait_ref_to_str(cx.tcx, self)
93:     }
librustc/middle/typeck/collect.rs:
1151:                         token::get_ident(ident),
1152:                         ppaux::trait_ref_to_str(tcx, &*trait_ref)));
1153:                 }
librustc/middle/typeck/check/vtable.rs:
208:                          ppaux::trait_ref_to_str(tcx, &r_exp_trait_ref),
209:                          ppaux::trait_ref_to_str(tcx, &r_act_trait_ref),
210:                          ty::type_err_to_str(tcx, err)));


librustc/util/ppaux.rs:35:53-35:53 -trait- definition:
/// Produces a string suitable for debugging output.
pub trait Repr {
    fn repr(&self, tcx: &ctxt) -> ~str;
references:- 76
librustc/middle/trans/common.rs:
librustc/middle/trans/_match.rs:
librustc/middle/typeck/mod.rs:
librustc/middle/typeck/check/method.rs:
librustc/middle/typeck/infer/mod.rs:
librustc/middle/typeck/infer/region_inference/mod.rs:
librustc/middle/borrowck/mod.rs:
librustc/middle/mem_categorization.rs:


librustc/util/ppaux.rs:203:1-203:1 -fn- definition:
pub fn trait_store_to_str(cx: &ctxt, s: ty::TraitStore) -> ~str {
    match s {
        ty::UniqTraitStore => "Box ".to_owned(),
references:- 5
842:     fn repr(&self, tcx: &ctxt) -> ~str {
843:         trait_store_to_str(tcx, *self)
844:     }
librustc/middle/trans/debuginfo.rs:
2119:     let ident_string = token::get_name(last.name());
2120:     let name = ppaux::trait_store_to_str(cx.tcx(), trait_store) +
2121:                ident_string.get();
librustc/middle/ty.rs:
3371:             format!("trait storage differs: expected `{}` but found `{}`",
3372:                  trait_store_to_str(cx, (*values).expected),
3373:                  trait_store_to_str(cx, (*values).found))
3374:         }


librustc/util/ppaux.rs:228:1-228:1 -fn- definition:
pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
    fn fn_input_to_str(cx: &ctxt, input: ty::t) -> ~str {
        ty_to_str(cx, input)
references:- 108
librustc/middle/trans/glue.rs:
librustc/middle/trans/datum.rs:
librustc/middle/trans/consts.rs:
librustc/middle/trans/base.rs:
librustc/middle/trans/closure.rs:
librustc/middle/trans/tvec.rs:
librustc/middle/trans/intrinsic.rs:
librustc/middle/trans/reflect.rs:
librustc/middle/trans/debuginfo.rs:
librustc/middle/trans/adt.rs:
librustc/middle/ty.rs:
librustc/middle/typeck/mod.rs:
librustc/middle/typeck/check/mod.rs:
librustc/middle/typeck/check/regionmanip.rs:
librustc/middle/typeck/check/regionck.rs:
librustc/middle/typeck/check/method.rs:
librustc/middle/typeck/infer/mod.rs:
librustc/middle/typeck/infer/resolve.rs:
librustc/middle/typeck/infer/to_str.rs:
librustc/middle/typeck/collect.rs:
librustc/middle/check_match.rs:
librustc/middle/check_const.rs:
librustc/middle/lint.rs:
librustc/middle/mem_categorization.rs:
librustc/middle/kind.rs:
librustc/middle/astencode.rs:
librustc/middle/effect.rs:
librustc/back/link.rs:
librustc/driver/driver.rs:
librustc/middle/check_match.rs:


librustc/util/ppaux.rs:407:1-407:1 -fn- definition:
pub fn parameterized(cx: &ctxt,
                     base: &str,
                     regions: &ty::RegionSubsts,
references:- 6
904:         } else {
905:             parameterized(tcx, base, &self.substs.regions,
906:                           self.substs.tps.as_slice(), self.def_id, true)
librustc/middle/trans/type_of.rs:
308:     };
309:     let tstr = ppaux::parameterized(cx.tcx(), ty::item_path_str(cx.tcx(), did),
310:                                     &ty::NonerasedRegions(OwnedSlice::empty()),
librustc/middle/trans/debuginfo.rs:
2122:     // Add type and region parameters
2123:     let name = ppaux::parameterized(cx.tcx(), name, &substs.regions,
2124:                                     substs.tps.as_slice(), def_id, true);
librustc/util/ppaux.rs:
901:             for &t in self.substs.self_ty.iter() { all_tps.push(t); }
902:             parameterized(tcx, base, &self.substs.regions,
903:                           all_tps.as_slice(), self.def_id, true)


librustc/util/ppaux.rs:44:1-44:1 -fn- definition:
pub fn note_and_explain_region(cx: &ctxt,
                               prefix: &str,
                               region: ty::Region,
references:- 37
librustc/middle/ty.rs:
librustc/middle/typeck/infer/error_reporting.rs:
librustc/middle/borrowck/mod.rs:
librustc/middle/typeck/infer/error_reporting.rs:


librustc/util/ppaux.rs:132:4-132:4 -fn- definition:
    fn explain_span(cx: &ctxt, heading: &str, span: Span)
        -> (~str, Option<Span>) {
        let lo = cx.sess.codemap().lookup_char_pos_adj(span.lo);
references:- 9
67:           Some(ast_map::NodeBlock(ref blk)) => {
68:             explain_span(cx, "block", blk.span)
69:           }
--
105:           Some(ast_map::NodeBlock(ref blk)) => {
106:             let (msg, opt_span) = explain_span(cx, "block", blk.span);
107:             (format!("{} {}", prefix, msg), opt_span)
--
110:                 ast::ItemImpl(..) => true, _ => false} => {
111:             let (msg, opt_span) = explain_span(cx, "impl", it.span);
112:             (format!("{} {}", prefix, msg), opt_span)


librustc/util/ppaux.rs:212:1-212:1 -fn- definition:
pub fn vec_map_to_str<T>(ts: &[T], f: |t: &T| -> ~str) -> ~str {
    let tstrs = ts.iter().map(f).collect::<Vec<~str>>();
    format!("[{}]", tstrs.connect(", "))
references:- 3
509: fn repr_vec<T:Repr>(tcx: &ctxt, v: &[T]) -> ~str {
510:     vec_map_to_str(v, |t| t.repr(tcx))
511: }
librustc/middle/trans/_match.rs:
1425:            m.repr(bcx.tcx()),
1426:            vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
1427:     let _indenter = indenter();


librustc/util/ppaux.rs:40:56-40:56 -trait- definition:
/// Produces a string suitable for showing to the user.
pub trait UserString {
    fn user_string(&self, tcx: &ctxt) -> ~str;
references:- 10
877: impl<A:UserString> UserString for Rc<A> {
878:     fn user_string(&self, tcx: &ctxt) -> ~str {
--
929: impl UserString for abi::Abi {
930:     fn user_string(&self, _tcx: &ctxt) -> ~str {
librustc/middle/typeck/infer/error_reporting.rs:
108:     fn expected_found_str<T:UserString+Resolvable>(
109:         &self,
--
383:     fn expected_found_str<T:UserString+Resolvable>(
384:         &self,
librustc/util/ppaux.rs:
853: impl UserString for ty::BuiltinBound {
854:     fn user_string(&self, _tcx: &ctxt) -> ~str {


librustc/util/ppaux.rs:309:4-309:4 -fn- definition:
    fn push_sig_to_str(cx: &ctxt,
                       s: &mut StrBuf,
                       bra: char,
references:- 3
263:         push_sig_to_str(cx, &mut s, '(', ')', sig);
--
296:                 }
297:                 push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
298:             }


librustc/util/ppaux.rs:192:1-192:1 -fn- definition:
pub fn mutability_to_str(m: ast::Mutability) -> ~str {
    match m {
        ast::MutMutable => "mut ".to_owned(),
references:- 2
200: pub fn mt_to_str(cx: &ctxt, m: &mt) -> ~str {
201:     format!("{}{}", mutability_to_str(m.mutbl), ty_to_str(cx, m.ty))
202: }
--
207:         ty::RegionTraitStore(r, m) => {
208:             format!("{}{}", region_ptr_to_str(cx, r), mutability_to_str(m))
209:         }


librustc/util/ppaux.rs:199:1-199:1 -fn- definition:
pub fn mt_to_str(cx: &ctxt, m: &mt) -> ~str {
    format!("{}{}", mutability_to_str(m.mutbl), ty_to_str(cx, m.ty))
}
references:- 8
350:       ty_rptr(r, ref tm) => {
351:         region_ptr_to_str(cx, r) + mt_to_str(cx, tm)
352:       }
--
400:           match sz {
401:               Some(n) => format!("[{}, .. {}]", mt_to_str(cx, mt), n),
402:               None => format!("[{}]", ty_to_str(cx, mt.ty)),
librustc/middle/typeck/infer/glb.rs:
52:                mt_to_str(tcx, a),
53:                mt_to_str(tcx, b));
librustc/middle/typeck/infer/lub.rs:
51:                mt_to_str(tcx, a),
52:                mt_to_str(tcx, b));
librustc/middle/typeck/infer/to_str.rs:
41:     fn inf_str(&self, cx: &InferCtxt) -> ~str {
42:         mt_to_str(cx.tcx, self)
43:     }
librustc/middle/typeck/infer/glb.rs:
51:                self.tag(),
52:                mt_to_str(tcx, a),
53:                mt_to_str(tcx, b));


librustc/util/ppaux.rs:163:31-163:31 -fn- definition:
// `note_and_explain_region()`
pub fn region_ptr_to_str(cx: &ctxt, region: Region) -> ~str {
    region_to_str(cx, "&", true, region)
references:- 2
207:         ty::RegionTraitStore(r, m) => {
208:             format!("{}{}", region_ptr_to_str(cx, r), mutability_to_str(m))
209:         }
--
350:       ty_rptr(r, ref tm) => {
351:         region_ptr_to_str(cx, r) + mt_to_str(cx, tm)
352:       }