(index<- )        ./libsyntax/print/pprust.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  use abi;
   12  use ast::{P, StaticRegionTyParamBound, OtherRegionTyParamBound,
   13            TraitTyParamBound, Required, Provided};
   14  use ast;
   15  use ast_util;
   16  use owned_slice::OwnedSlice;
   17  use attr::{AttrMetaMethods, AttributeMethods};
   18  use codemap::{CodeMap, BytePos};
   19  use codemap;
   20  use diagnostic;
   21  use parse::classify::expr_is_simple_block;
   22  use parse::token::IdentInterner;
   23  use parse::{comments, token};
   24  use parse;
   25  use print::pp::{break_offset, word, space, zerobreak, hardbreak};
   26  use print::pp::{Breaks, Consistent, Inconsistent, eof};
   27  use print::pp;
   28  
   29  use std::cast;
   30  use std::io::{IoResult, MemWriter};
   31  use std::io;
   32  use std::rc::Rc;
   33  use std::str;
   34  use std::strbuf::StrBuf;
   35  
   36  pub enum AnnNode<'a> {
   37      NodeBlock(&'a ast::Block),
   38      NodeItem(&'a ast::Item),
   39      NodeExpr(&'a ast::Expr),
   40      NodePat(&'a ast::Pat),
   41  }
   42  
   43  pub trait PpAnn {
   44      fn pre(&self, _state&mut State, _nodeAnnNode) -> IoResult<()> { Ok(()) }
   45      fn post(&self, _state&mut State, _nodeAnnNode) -> IoResult<()> { Ok(()) }
   46  }
   47  
   48  pub struct NoAnn;
   49  
   50  impl PpAnn for NoAnn {}
   51  
   52  pub struct CurrentCommentAndLiteral {
   53      cur_cmnt: uint,
   54      cur_lit: uint,
   55  }
   56  
   57  pub struct State<'a> {
   58      pub s: pp::Printer,
   59      cm: Option<&'a CodeMap>,
   60      intr: Rc<token::IdentInterner>,
   61      comments: Option<Vec<comments::Comment> >,
   62      literals: Option<Vec<comments::Literal> >,
   63      cur_cmnt_and_lit: CurrentCommentAndLiteral,
   64      boxes: Vec<pp::Breaks>,
   65      ann: &'a PpAnn
   66  }
   67  
   68  pub fn rust_printer(writerBox<io::Writer>) -> State<'static> {
   69      static NO_ANN: NoAnn = NoAnn;
   70      rust_printer_annotated(writer, &NO_ANN)
   71  }
   72  
   73  pub fn rust_printer_annotated<'a>(writerBox<io::Writer>,
   74                                    ann: &'a PpAnn) -> State<'a> {
   75      State {
   76          s: pp::mk_printer(writer, default_columns),
   77          cm: None,
   78          intr: token::get_ident_interner(),
   79          comments: None,
   80          literals: None,
   81          cur_cmnt_and_lit: CurrentCommentAndLiteral {
   82              cur_cmnt: 0,
   83              cur_lit: 0
   84          },
   85          boxes: Vec::new(),
   86          ann: ann
   87      }
   88  }
   89  
   90  pub static indent_unit: uint = 4u;
   91  
   92  pub static default_columns: uint = 78u;
   93  
   94  // Requires you to pass an input filename and reader so that
   95  // it can scan the input text for comments and literals to
   96  // copy forward.
   97  pub fn print_crate<'a>(cm: &'a CodeMap,
   98                         span_diagnostic: &diagnostic::SpanHandler,
   99                         krate: &ast::Crate,
  100                         filenameStrBuf,
  101                         input: &mut io::Reader,
  102                         outBox<io::Writer>,
  103                         ann: &'a PpAnn,
  104                         is_expanded: bool) -> IoResult<()> {
  105      let (cmnts, lits) = comments::gather_comments_and_literals(
  106          span_diagnostic,
  107          filename,
  108          input
  109      );
  110      let mut s = State {
  111          s: pp::mk_printer(out, default_columns),
  112          cm: Some(cm),
  113          intr: token::get_ident_interner(),
  114          comments: Some(cmnts),
  115          // If the code is post expansion, don't use the table of
  116          // literals, since it doesn't correspond with the literals
  117          // in the AST anymore.
  118          literals: if is_expanded {
  119              None
  120          } else {
  121              Some(lits)
  122          },
  123          cur_cmnt_and_lit: CurrentCommentAndLiteral {
  124              cur_cmnt: 0,
  125              cur_lit: 0
  126          },
  127          boxes: Vec::new(),
  128          ann: ann
  129      };
  130      try!(s.print_mod(&krate.module, krate.attrs.as_slice()));
  131      try!(s.print_remaining_comments());
  132      eof(&mut s.s)
  133  }
  134  
  135  pub fn to_str(f: |&mut State-> IoResult<()>) -> StrBuf {
  136      let mut s = rust_printer(box MemWriter::new());
  137      f(&mut s).unwrap();
  138      eof(&mut s.s).unwrap();
  139      unsafe {
  140          // FIXME(pcwalton): A nasty function to extract the string from an `io::Writer`
  141          // that we "know" to be a `MemWriter` that works around the lack of checked
  142          // downcasts.
  143          let (_, wr)(uint, Box<MemWriter>) = cast::transmute_copy(&s.s.out);
  144          let result = str::from_utf8_owned(wr.get_ref().to_owned()).unwrap();
  145          cast::forget(wr);
  146          result.to_strbuf()
  147      }
  148  }
  149  
  150  pub fn ty_to_str(ty: &ast::Ty) -> StrBuf {
  151      to_str(|s| s.print_type(ty))
  152  }
  153  
  154  pub fn pat_to_str(pat: &ast::Pat) -> StrBuf {
  155      to_str(|s| s.print_pat(pat))
  156  }
  157  
  158  pub fn expr_to_str(e: &ast::Expr) -> StrBuf {
  159      to_str(|s| s.print_expr(e))
  160  }
  161  
  162  pub fn lifetime_to_str(e: &ast::Lifetime) -> StrBuf {
  163      to_str(|s| s.print_lifetime(e))
  164  }
  165  
  166  pub fn tt_to_str(tt: &ast::TokenTree) -> StrBuf {
  167      to_str(|s| s.print_tt(tt))
  168  }
  169  
  170  pub fn tts_to_str(tts: &[ast::TokenTree]) -> StrBuf {
  171      to_str(|s| s.print_tts(&tts))
  172  }
  173  
  174  pub fn stmt_to_str(stmt: &ast::Stmt) -> StrBuf {
  175      to_str(|s| s.print_stmt(stmt))
  176  }
  177  
  178  pub fn item_to_str(i: &ast::Item) -> StrBuf {
  179      to_str(|s| s.print_item(i))
  180  }
  181  
  182  pub fn generics_to_str(generics: &ast::Generics) -> StrBuf {
  183      to_str(|s| s.print_generics(generics))
  184  }
  185  
  186  pub fn ty_method_to_str(p: &ast::TypeMethod) -> StrBuf {
  187      to_str(|s| s.print_ty_method(p))
  188  }
  189  
  190  pub fn method_to_str(p: &ast::Method) -> StrBuf {
  191      to_str(|s| s.print_method(p))
  192  }
  193  
  194  pub fn fn_block_to_str(p: &ast::FnDecl) -> StrBuf {
  195      to_str(|s| s.print_fn_block_args(p))
  196  }
  197  
  198  pub fn path_to_str(p: &ast::Path) -> StrBuf {
  199      to_str(|s| s.print_path(p, false))
  200  }
  201  
  202  pub fn fun_to_str(decl: &ast::FnDecl, fn_styleast::FnStyle, nameast::Ident,
  203                    opt_explicit_selfOption<ast::ExplicitSelf_>,
  204                    generics: &ast::Generics) -> StrBuf {
  205      to_str(|s| {
  206          try!(s.print_fn(decl, Some(fn_style), abi::Rust,
  207                          name, generics, opt_explicit_self, ast::Inherited));
  208          try!(s.end()); // Close the head box
  209          s.end() // Close the outer box
  210      })
  211  }
  212  
  213  pub fn block_to_str(blk: &ast::Block) -> StrBuf {
  214      to_str(|s| {
  215          // containing cbox, will be closed by print-block at }
  216          try!(s.cbox(indent_unit));
  217          // head-ibox, will be closed by print-block after {
  218          try!(s.ibox(0u));
  219          s.print_block(blk)
  220      })
  221  }
  222  
  223  pub fn meta_item_to_str(mi: &ast::MetaItem) -> StrBuf {
  224      to_str(|s| s.print_meta_item(mi))
  225  }
  226  
  227  pub fn attribute_to_str(attr: &ast::Attribute) -> StrBuf {
  228      to_str(|s| s.print_attribute(attr))
  229  }
  230  
  231  pub fn lit_to_str(l: &ast::Lit) -> StrBuf {
  232      to_str(|s| s.print_literal(l))
  233  }
  234  
  235  pub fn explicit_self_to_str(explicit_selfast::ExplicitSelf_) -> StrBuf {
  236      to_str(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
  237  }
  238  
  239  pub fn variant_to_str(var: &ast::Variant) -> StrBuf {
  240      to_str(|s| s.print_variant(var))
  241  }
  242  
  243  pub fn visibility_qualified(visast::Visibility, s: &str) -> StrBuf {
  244      match vis {
  245          ast::Public => format!("pub {}", s).to_strbuf(),
  246          ast::Inherited => s.to_strbuf()
  247      }
  248  }
  249  
  250  impl<'a> State<'a> {
  251      pub fn ibox(&mut self, uuint) -> IoResult<()> {
  252          self.boxes.push(pp::Inconsistent);
  253          pp::ibox(&mut self.s, u)
  254      }
  255  
  256      pub fn end(&mut self) -> IoResult<()> {
  257          self.boxes.pop().unwrap();
  258          pp::end(&mut self.s)
  259      }
  260  
  261      pub fn cbox(&mut self, uuint) -> IoResult<()> {
  262          self.boxes.push(pp::Consistent);
  263          pp::cbox(&mut self.s, u)
  264      }
  265  
  266      // "raw box"
  267      pub fn rbox(&mut self, uuint, bpp::Breaks) -> IoResult<()> {
  268          self.boxes.push(b);
  269          pp::rbox(&mut self.s, u, b)
  270      }
  271  
  272      pub fn nbsp(&mut self) -> IoResult<()> { word(&mut self.s, " ") }
  273  
  274      pub fn word_nbsp(&mut self, w&str) -> IoResult<()> {
  275          try!(word(&mut self.s, w));
  276          self.nbsp()
  277      }
  278  
  279      pub fn word_space(&mut self, w&str) -> IoResult<()> {
  280          try!(word(&mut self.s, w));
  281          space(&mut self.s)
  282      }
  283  
  284      pub fn popen(&mut self) -> IoResult<()> { word(&mut self.s, "(") }
  285  
  286      pub fn pclose(&mut self) -> IoResult<()> { word(&mut self.s, ")") }
  287  
  288      pub fn head(&mut self, w&str) -> IoResult<()> {
  289          // outer-box is consistent
  290          try!(self.cbox(indent_unit));
  291          // head-box is inconsistent
  292          try!(self.ibox(w.len() + 1));
  293          // keyword that starts the head
  294          if !w.is_empty() {
  295              try!(self.word_nbsp(w));
  296          }
  297          Ok(())
  298      }
  299  
  300      pub fn bopen(&mut self) -> IoResult<()> {
  301          try!(word(&mut self.s, "{"));
  302          self.end() // close the head-box
  303      }
  304  
  305      pub fn bclose_(&mut self, spancodemap::Span,
  306                     indenteduint) -> IoResult<()> {
  307          self.bclose_maybe_open(span, indented, true)
  308      }
  309      pub fn bclose_maybe_open (&mut self, spancodemap::Span,
  310                                indenteduint, close_boxbool) -> IoResult<()> {
  311          try!(self.maybe_print_comment(span.hi));
  312          try!(self.break_offset_if_not_bol(1u, -(indented as int)));
  313          try!(word(&mut self.s, "}"));
  314          if close_box {
  315              try!(self.end()); // close the outer-box
  316          }
  317          Ok(())
  318      }
  319      pub fn bclose(&mut self, spancodemap::Span) -> IoResult<()> {
  320          self.bclose_(span, indent_unit)
  321      }
  322  
  323      pub fn is_begin(&mut self) -> bool {
  324          match self.s.last_token() { pp::Begin(_) => true, _ => false }
  325      }
  326  
  327      pub fn is_end(&mut self) -> bool {
  328          match self.s.last_token() { pp::End => true, _ => false }
  329      }
  330  
  331      pub fn is_bol(&mut self) -> bool {
  332          self.s.last_token().is_eof() || self.s.last_token().is_hardbreak_tok()
  333      }
  334  
  335      pub fn in_cbox(&self) -> bool {
  336          match self.boxes.last() {
  337              Some(&last_box) => last_box == pp::Consistent,
  338              None => false
  339          }
  340      }
  341  
  342      pub fn hardbreak_if_not_bol(&mut self) -> IoResult<()> {
  343          if !self.is_bol() {
  344              try!(hardbreak(&mut self.s))
  345          }
  346          Ok(())
  347      }
  348      pub fn space_if_not_bol(&mut self) -> IoResult<()> {
  349          if !self.is_bol() { try!(space(&mut self.s)); }
  350          Ok(())
  351      }
  352      pub fn break_offset_if_not_bol(&mut self, nuint,
  353                                     offint) -> IoResult<()> {
  354          if !self.is_bol() {
  355              break_offset(&mut self.s, n, off)
  356          } else {
  357              if off != 0 && self.s.last_token().is_hardbreak_tok() {
  358                  // We do something pretty sketchy here: tuck the nonzero
  359                  // offset-adjustment we were going to deposit along with the
  360                  // break into the previous hardbreak.
  361                  self.s.replace_last_token(pp::hardbreak_tok_offset(off));
  362              }
  363              Ok(())
  364          }
  365      }
  366  
  367      // Synthesizes a comment that was not textually present in the original source
  368      // file.
  369      pub fn synth_comment(&mut self, textStrBuf) -> IoResult<()> {
  370          try!(word(&mut self.s, "/*"));
  371          try!(space(&mut self.s));
  372          try!(word(&mut self.s, text.as_slice()));
  373          try!(space(&mut self.s));
  374          word(&mut self.s, "*/")
  375      }
  376  
  377      pub fn commasep<T>(&mut self, bBreaks, elts&[T],
  378                         op|&mut State, &T-> IoResult<()>)
  379          -> IoResult<()> {
  380          try!(self.rbox(0u, b));
  381          let mut first = true;
  382          for elt in elts.iter() {
  383              if first { first = false; } else { try!(self.word_space(",")); }
  384              try!(op(self, elt));
  385          }
  386          self.end()
  387      }
  388  
  389  
  390      pub fn commasep_cmnt<T>(
  391                           &mut self,
  392                           bBreaks,
  393                           elts&[T],
  394                           op|&mut State, &T-> IoResult<()>,
  395                           get_span|&T-> codemap::Span) -> IoResult<()> {
  396          try!(self.rbox(0u, b));
  397          let len = elts.len();
  398          let mut i = 0u;
  399          for elt in elts.iter() {
  400              try!(self.maybe_print_comment(get_span(elt).hi));
  401              try!(op(self, elt));
  402              i += 1u;
  403              if i < len {
  404                  try!(word(&mut self.s, ","));
  405                  try!(self.maybe_print_trailing_comment(get_span(elt),
  406                                                      Some(get_span(&elts[i]).hi)));
  407                  try!(self.space_if_not_bol());
  408              }
  409          }
  410          self.end()
  411      }
  412  
  413      pub fn commasep_exprs(&mut self, bBreaks,
  414                            exprs&[@ast::Expr]) -> IoResult<()> {
  415          self.commasep_cmnt(b, exprs, |s, &e| s.print_expr(e), |e| e.span)
  416      }
  417  
  418      pub fn print_mod(&mut self, _mod&ast::Mod,
  419                       attrs&[ast::Attribute]) -> IoResult<()> {
  420          try!(self.print_inner_attributes(attrs));
  421          for vitem in _mod.view_items.iter() {
  422              try!(self.print_view_item(vitem));
  423          }
  424          for item in _mod.items.iter() {
  425              try!(self.print_item(*item));
  426          }
  427          Ok(())
  428      }
  429  
  430      pub fn print_foreign_mod(&mut self, nmod&ast::ForeignMod,
  431                               attrs&[ast::Attribute]) -> IoResult<()> {
  432          try!(self.print_inner_attributes(attrs));
  433          for vitem in nmod.view_items.iter() {
  434              try!(self.print_view_item(vitem));
  435          }
  436          for item in nmod.items.iter() {
  437              try!(self.print_foreign_item(*item));
  438          }
  439          Ok(())
  440      }
  441  
  442      pub fn print_opt_lifetime(&mut self,
  443                                lifetime&Option<ast::Lifetime>) -> IoResult<()> {
  444          for l in lifetime.iter() {
  445              try!(self.print_lifetime(l));
  446              try!(self.nbsp());
  447          }
  448          Ok(())
  449      }
  450  
  451      pub fn print_type(&mut self, ty&ast::Ty) -> IoResult<()> {
  452          try!(self.maybe_print_comment(ty.span.lo));
  453          try!(self.ibox(0u));
  454          match ty.node {
  455              ast::TyNil => try!(word(&mut self.s, "()")),
  456              ast::TyBot => try!(word(&mut self.s, "!")),
  457              ast::TyBox(ty) => {
  458                  try!(word(&mut self.s, "@"));
  459                  try!(self.print_type(ty));
  460              }
  461              ast::TyUniq(ty) => {
  462                  try!(word(&mut self.s, "~"));
  463                  try!(self.print_type(ty));
  464              }
  465              ast::TyVec(ty) => {
  466                  try!(word(&mut self.s, "["));
  467                  try!(self.print_type(ty));
  468                  try!(word(&mut self.s, "]"));
  469              }
  470              ast::TyPtr(ref mt) => {
  471                  try!(word(&mut self.s, "*"));
  472                  try!(self.print_mt(mt));
  473              }
  474              ast::TyRptr(ref lifetime, ref mt) => {
  475                  try!(word(&mut self.s, "&"));
  476                  try!(self.print_opt_lifetime(lifetime));
  477                  try!(self.print_mt(mt));
  478              }
  479              ast::TyTup(ref elts) => {
  480                  try!(self.popen());
  481                  try!(self.commasep(Inconsistent, elts.as_slice(),
  482                                     |s, ty| s.print_type_ref(ty)));
  483                  if elts.len() == 1 {
  484                      try!(word(&mut self.s, ","));
  485                  }
  486                  try!(self.pclose());
  487              }
  488              ast::TyBareFn(f) => {
  489                  let generics = ast::Generics {
  490                      lifetimes: f.lifetimes.clone(),
  491                      ty_params: OwnedSlice::empty()
  492                  };
  493                  try!(self.print_ty_fn(Some(f.abi), None, &None,
  494                                     f.fn_style, ast::Many, f.decl, None, &None,
  495                                     Some(&generics), None));
  496              }
  497              ast::TyClosure(f, ref region) => {
  498                  let generics = ast::Generics {
  499                      lifetimes: f.lifetimes.clone(),
  500                      ty_params: OwnedSlice::empty()
  501                  };
  502                  try!(self.print_ty_fn(None, Some('&'), region, f.fn_style,
  503                                        f.onceness, f.decl, None, &f.bounds,
  504                                        Some(&generics), None));
  505              }
  506              ast::TyProc(f) => {
  507                  let generics = ast::Generics {
  508                      lifetimes: f.lifetimes.clone(),
  509                      ty_params: OwnedSlice::empty()
  510                  };
  511                  try!(self.print_ty_fn(None, Some('~'), &None, f.fn_style,
  512                                        f.onceness, f.decl, None, &f.bounds,
  513                                        Some(&generics), None));
  514              }
  515              ast::TyPath(ref path, ref bounds, _) => {
  516                  try!(self.print_bounded_path(path, bounds));
  517              }
  518              ast::TyFixedLengthVec(ty, v) => {
  519                  try!(word(&mut self.s, "["));
  520                  try!(self.print_type(ty));
  521                  try!(word(&mut self.s, ", .."));
  522                  try!(self.print_expr(v));
  523                  try!(word(&mut self.s, "]"));
  524              }
  525              ast::TyTypeof(e) => {
  526                  try!(word(&mut self.s, "typeof("));
  527                  try!(self.print_expr(e));
  528                  try!(word(&mut self.s, ")"));
  529              }
  530              ast::TyInfer => {
  531                  try!(word(&mut self.s, "_"));
  532              }
  533          }
  534          self.end()
  535      }
  536  
  537      pub fn print_type_ref(&mut self, ty&P<ast::Ty>) -> IoResult<()> {
  538          self.print_type(*ty)
  539      }
  540  
  541      pub fn print_foreign_item(&mut self,
  542                                item&ast::ForeignItem) -> IoResult<()> {
  543          try!(self.hardbreak_if_not_bol());
  544          try!(self.maybe_print_comment(item.span.lo));
  545          try!(self.print_outer_attributes(item.attrs.as_slice()));
  546          match item.node {
  547              ast::ForeignItemFn(decl, ref generics) => {
  548                  try!(self.print_fn(decl, None, abi::Rust, item.ident, generics,
  549                  None, item.vis));
  550                  try!(self.end()); // end head-ibox
  551                  try!(word(&mut self.s, ";"));
  552                  self.end() // end the outer fn box
  553              }
  554              ast::ForeignItemStatic(t, m) => {
  555                  try!(self.head(visibility_qualified(item.vis,
  556                                                      "static").as_slice()));
  557                  if m {
  558                      try!(self.word_space("mut"));
  559                  }
  560                  try!(self.print_ident(item.ident));
  561                  try!(self.word_space(":"));
  562                  try!(self.print_type(t));
  563                  try!(word(&mut self.s, ";"));
  564                  try!(self.end()); // end the head-ibox
  565                  self.end() // end the outer cbox
  566              }
  567          }
  568      }
  569  
  570      pub fn print_item(&mut self, item&ast::Item) -> IoResult<()> {
  571          try!(self.hardbreak_if_not_bol());
  572          try!(self.maybe_print_comment(item.span.lo));
  573          try!(self.print_outer_attributes(item.attrs.as_slice()));
  574          try!(self.ann.pre(self, NodeItem(item)));
  575          match item.node {
  576              ast::ItemStatic(ty, m, expr) => {
  577                  try!(self.head(visibility_qualified(item.vis,
  578                                                      "static").as_slice()));
  579                  if m == ast::MutMutable {
  580                      try!(self.word_space("mut"));
  581                  }
  582                  try!(self.print_ident(item.ident));
  583                  try!(self.word_space(":"));
  584                  try!(self.print_type(ty));
  585                  try!(space(&mut self.s));
  586                  try!(self.end()); // end the head-ibox
  587  
  588                  try!(self.word_space("="));
  589                  try!(self.print_expr(expr));
  590                  try!(word(&mut self.s, ";"));
  591                  try!(self.end()); // end the outer cbox
  592              }
  593              ast::ItemFn(decl, fn_style, abi, ref typarams, body) => {
  594                  try!(self.print_fn(
  595                      decl,
  596                      Some(fn_style),
  597                      abi,
  598                      item.ident,
  599                      typarams,
  600                      None,
  601                      item.vis
  602                  ));
  603                  try!(word(&mut self.s, " "));
  604                  try!(self.print_block_with_attrs(body, item.attrs.as_slice()));
  605              }
  606              ast::ItemMod(ref _mod) => {
  607                  try!(self.head(visibility_qualified(item.vis,
  608                                                      "mod").as_slice()));
  609                  try!(self.print_ident(item.ident));
  610                  try!(self.nbsp());
  611                  try!(self.bopen());
  612                  try!(self.print_mod(_mod, item.attrs.as_slice()));
  613                  try!(self.bclose(item.span));
  614              }
  615              ast::ItemForeignMod(ref nmod) => {
  616                  try!(self.head("extern"));
  617                  try!(self.word_nbsp(nmod.abi.to_str()));
  618                  try!(self.bopen());
  619                  try!(self.print_foreign_mod(nmod, item.attrs.as_slice()));
  620                  try!(self.bclose(item.span));
  621              }
  622              ast::ItemTy(ty, ref params) => {
  623                  try!(self.ibox(indent_unit));
  624                  try!(self.ibox(0u));
  625                  try!(self.word_nbsp(visibility_qualified(item.vis,
  626                                                           "type").as_slice()));
  627                  try!(self.print_ident(item.ident));
  628                  try!(self.print_generics(params));
  629                  try!(self.end()); // end the inner ibox
  630  
  631                  try!(space(&mut self.s));
  632                  try!(self.word_space("="));
  633                  try!(self.print_type(ty));
  634                  try!(word(&mut self.s, ";"));
  635                  try!(self.end()); // end the outer ibox
  636              }
  637              ast::ItemEnum(ref enum_definition, ref params) => {
  638                  try!(self.print_enum_def(
  639                      enum_definition,
  640                      params,
  641                      item.ident,
  642                      item.span,
  643                      item.vis
  644                  ));
  645              }
  646              ast::ItemStruct(struct_def, ref generics) => {
  647                  if struct_def.is_virtual {
  648                      try!(self.word_space("virtual"));
  649                  }
  650                  try!(self.head(visibility_qualified(item.vis,
  651                                                      "struct").as_slice()));
  652                  try!(self.print_struct(struct_def, generics, item.ident, item.span));
  653              }
  654  
  655              ast::ItemImpl(ref generics, ref opt_trait, ty, ref methods) => {
  656                  try!(self.head(visibility_qualified(item.vis,
  657                                                      "impl").as_slice()));
  658                  if generics.is_parameterized() {
  659                      try!(self.print_generics(generics));
  660                      try!(space(&mut self.s));
  661                  }
  662  
  663                  match opt_trait {
  664                      &Some(ref t) => {
  665                          try!(self.print_trait_ref(t));
  666                          try!(space(&mut self.s));
  667                          try!(self.word_space("for"));
  668                      }
  669                      &None => {}
  670                  }
  671  
  672                  try!(self.print_type(ty));
  673  
  674                  try!(space(&mut self.s));
  675                  try!(self.bopen());
  676                  try!(self.print_inner_attributes(item.attrs.as_slice()));
  677                  for meth in methods.iter() {
  678                      try!(self.print_method(*meth));
  679                  }
  680                  try!(self.bclose(item.span));
  681              }
  682              ast::ItemTrait(ref generics, ref sized, ref traits, ref methods) => {
  683                  try!(self.head(visibility_qualified(item.vis,
  684                                                      "trait").as_slice()));
  685                  try!(self.print_ident(item.ident));
  686                  try!(self.print_generics(generics));
  687                  if *sized == ast::DynSize {
  688                      try!(space(&mut self.s));
  689                      try!(word(&mut self.s, "for type"));
  690                  }
  691                  if traits.len() != 0u {
  692                      try!(word(&mut self.s, ":"));
  693                      for (i, trait_) in traits.iter().enumerate() {
  694                          try!(self.nbsp());
  695                          if i != 0 {
  696                              try!(self.word_space("+"));
  697                          }
  698                          try!(self.print_path(&trait_.path, false));
  699                      }
  700                  }
  701                  try!(word(&mut self.s, " "));
  702                  try!(self.bopen());
  703                  for meth in methods.iter() {
  704                      try!(self.print_trait_method(meth));
  705                  }
  706                  try!(self.bclose(item.span));
  707              }
  708              // I think it's reasonable to hide the context here:
  709              ast::ItemMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
  710                                              ..}) => {
  711                  try!(self.print_visibility(item.vis));
  712                  try!(self.print_path(pth, false));
  713                  try!(word(&mut self.s, "! "));
  714                  try!(self.print_ident(item.ident));
  715                  try!(self.cbox(indent_unit));
  716                  try!(self.popen());
  717                  try!(self.print_tts(&(tts.as_slice())));
  718                  try!(self.pclose());
  719                  try!(self.end());
  720              }
  721          }
  722          self.ann.post(self, NodeItem(item))
  723      }
  724  
  725      fn print_trait_ref(&mut self, t&ast::TraitRef) -> IoResult<()> {
  726          self.print_path(&t.path, false)
  727      }
  728  
  729      pub fn print_enum_def(&mut self, enum_definition&ast::EnumDef,
  730                            generics&ast::Generics, identast::Ident,
  731                            spancodemap::Span,
  732                            visibilityast::Visibility) -> IoResult<()> {
  733          try!(self.head(visibility_qualified(visibility, "enum").as_slice()));
  734          try!(self.print_ident(ident));
  735          try!(self.print_generics(generics));
  736          try!(space(&mut self.s));
  737          self.print_variants(enum_definition.variants.as_slice(), span)
  738      }
  739  
  740      pub fn print_variants(&mut self,
  741                            variants&[P<ast::Variant>],
  742                            spancodemap::Span) -> IoResult<()> {
  743          try!(self.bopen());
  744          for &v in variants.iter() {
  745              try!(self.space_if_not_bol());
  746              try!(self.maybe_print_comment(v.span.lo));
  747              try!(self.print_outer_attributes(v.node.attrs.as_slice()));
  748              try!(self.ibox(indent_unit));
  749              try!(self.print_variant(v));
  750              try!(word(&mut self.s, ","));
  751              try!(self.end());
  752              try!(self.maybe_print_trailing_comment(v.span, None));
  753          }
  754          self.bclose(span)
  755      }
  756  
  757      pub fn print_visibility(&mut self, visast::Visibility) -> IoResult<()> {
  758          match vis {
  759              ast::Public => self.word_nbsp("pub"),
  760              ast::Inherited => Ok(())
  761          }
  762      }
  763  
  764      pub fn print_struct(&mut self,
  765                          struct_def&ast::StructDef,
  766                          generics&ast::Generics,
  767                          identast::Ident,
  768                          spancodemap::Span) -> IoResult<()> {
  769          try!(self.print_ident(ident));
  770          try!(self.print_generics(generics));
  771          match struct_def.super_struct {
  772              Some(t) => {
  773                  try!(self.word_space(":"));
  774                  try!(self.print_type(t));
  775              },
  776              None => {},
  777          }
  778          if ast_util::struct_def_is_tuple_like(struct_def) {
  779              if !struct_def.fields.is_empty() {
  780                  try!(self.popen());
  781                  try!(self.commasep(
  782                      Inconsistent, struct_def.fields.as_slice(),
  783                      |s, field| {
  784                          match field.node.kind {
  785                              ast::NamedField(..) => fail!("unexpected named field"),
  786                              ast::UnnamedField(vis) => {
  787                                  try!(s.print_visibility(vis));
  788                                  try!(s.maybe_print_comment(field.span.lo));
  789                                  s.print_type(field.node.ty)
  790                              }
  791                          }
  792                      }
  793                  ));
  794                  try!(self.pclose());
  795              }
  796              try!(word(&mut self.s, ";"));
  797              try!(self.end());
  798              self.end() // close the outer-box
  799          } else {
  800              try!(self.nbsp());
  801              try!(self.bopen());
  802              try!(self.hardbreak_if_not_bol());
  803  
  804              for field in struct_def.fields.iter() {
  805                  match field.node.kind {
  806                      ast::UnnamedField(..) => fail!("unexpected unnamed field"),
  807                      ast::NamedField(ident, visibility) => {
  808                          try!(self.hardbreak_if_not_bol());
  809                          try!(self.maybe_print_comment(field.span.lo));
  810                          try!(self.print_outer_attributes(field.node.attrs.as_slice()));
  811                          try!(self.print_visibility(visibility));
  812                          try!(self.print_ident(ident));
  813                          try!(self.word_nbsp(":"));
  814                          try!(self.print_type(field.node.ty));
  815                          try!(word(&mut self.s, ","));
  816                      }
  817                  }
  818              }
  819  
  820              self.bclose(span)
  821          }
  822      }
  823  
  824      /// This doesn't deserve to be called "pretty" printing, but it should be
  825      /// meaning-preserving. A quick hack that might help would be to look at the
  826      /// spans embedded in the TTs to decide where to put spaces and newlines.
  827      /// But it'd be better to parse these according to the grammar of the
  828      /// appropriate macro, transcribe back into the grammar we just parsed from,
  829      /// and then pretty-print the resulting AST nodes (so, e.g., we print
  830      /// expression arguments as expressions). It can be done! I think.
  831      pub fn print_tt(&mut self, tt&ast::TokenTree) -> IoResult<()> {
  832          match *tt {
  833              ast::TTDelim(ref tts) => self.print_tts(&(tts.as_slice())),
  834              ast::TTTok(_, ref tk) => {
  835                  word(&mut self.s, parse::token::to_str(tk).as_slice())
  836              }
  837              ast::TTSeq(_, ref tts, ref sep, zerok) => {
  838                  try!(word(&mut self.s, "$("));
  839                  for tt_elt in (*tts).iter() {
  840                      try!(self.print_tt(tt_elt));
  841                  }
  842                  try!(word(&mut self.s, ")"));
  843                  match *sep {
  844                      Some(ref tk) => {
  845                          try!(word(&mut self.s,
  846                                    parse::token::to_str(tk).as_slice()));
  847                      }
  848                      None => ()
  849                  }
  850                  word(&mut self.s, if zerok { "*" } else { "+" })
  851              }
  852              ast::TTNonterminal(_, name) => {
  853                  try!(word(&mut self.s, "$"));
  854                  self.print_ident(name)
  855              }
  856          }
  857      }
  858  
  859      pub fn print_tts(&mut self, tts& &[ast::TokenTree]) -> IoResult<()> {
  860          try!(self.ibox(0));
  861          for (i, tt) in tts.iter().enumerate() {
  862              if i != 0 {
  863                  try!(space(&mut self.s));
  864              }
  865              try!(self.print_tt(tt));
  866          }
  867          self.end()
  868      }
  869  
  870      pub fn print_variant(&mut self, v&ast::Variant) -> IoResult<()> {
  871          try!(self.print_visibility(v.node.vis));
  872          match v.node.kind {
  873              ast::TupleVariantKind(ref args) => {
  874                  try!(self.print_ident(v.node.name));
  875                  if !args.is_empty() {
  876                      try!(self.popen());
  877                      try!(self.commasep(Consistent,
  878                                         args.as_slice(),
  879                                         |s, arg| s.print_type(arg.ty)));
  880                      try!(self.pclose());
  881                  }
  882              }
  883              ast::StructVariantKind(struct_def) => {
  884                  try!(self.head(""));
  885                  let generics = ast_util::empty_generics();
  886                  try!(self.print_struct(struct_def, &generics, v.node.name, v.span));
  887              }
  888          }
  889          match v.node.disr_expr {
  890              Some(d) => {
  891                  try!(space(&mut self.s));
  892                  try!(self.word_space("="));
  893                  self.print_expr(d)
  894              }
  895              _ => Ok(())
  896          }
  897      }
  898  
  899      pub fn print_ty_method(&mut self, m&ast::TypeMethod) -> IoResult<()> {
  900          try!(self.hardbreak_if_not_bol());
  901          try!(self.maybe_print_comment(m.span.lo));
  902          try!(self.print_outer_attributes(m.attrs.as_slice()));
  903          try!(self.print_ty_fn(None,
  904                                None,
  905                                &None,
  906                                m.fn_style,
  907                                ast::Many,
  908                                m.decl,
  909                                Some(m.ident),
  910                                &None,
  911                                Some(&m.generics),
  912                                Some(m.explicit_self.node)));
  913          word(&mut self.s, ";")
  914      }
  915  
  916      pub fn print_trait_method(&mut self,
  917                                m&ast::TraitMethod) -> IoResult<()> {
  918          match *m {
  919              Required(ref ty_m) => self.print_ty_method(ty_m),
  920              Provided(m) => self.print_method(m)
  921          }
  922      }
  923  
  924      pub fn print_method(&mut self, meth&ast::Method) -> IoResult<()> {
  925          try!(self.hardbreak_if_not_bol());
  926          try!(self.maybe_print_comment(meth.span.lo));
  927          try!(self.print_outer_attributes(meth.attrs.as_slice()));
  928          try!(self.print_fn(meth.decl, Some(meth.fn_style), abi::Rust,
  929                          meth.ident, &meth.generics, Some(meth.explicit_self.node),
  930                          meth.vis));
  931          try!(word(&mut self.s, " "));
  932          self.print_block_with_attrs(meth.body, meth.attrs.as_slice())
  933      }
  934  
  935      pub fn print_outer_attributes(&mut self,
  936                                    attrs&[ast::Attribute]) -> IoResult<()> {
  937          let mut count = 0;
  938          for attr in attrs.iter() {
  939              match attr.node.style {
  940                  ast::AttrOuter => {
  941                      try!(self.print_attribute(attr));
  942                      count += 1;
  943                  }
  944                  _ => {/* fallthrough */ }
  945              }
  946          }
  947          if count > 0 {
  948              try!(self.hardbreak_if_not_bol());
  949          }
  950          Ok(())
  951      }
  952  
  953      pub fn print_inner_attributes(&mut self,
  954                                    attrs&[ast::Attribute]) -> IoResult<()> {
  955          let mut count = 0;
  956          for attr in attrs.iter() {
  957              match attr.node.style {
  958                  ast::AttrInner => {
  959                      try!(self.print_attribute(attr));
  960                      count += 1;
  961                  }
  962                  _ => {/* fallthrough */ }
  963              }
  964          }
  965          if count > 0 {
  966              try!(self.hardbreak_if_not_bol());
  967          }
  968          Ok(())
  969      }
  970  
  971      pub fn print_attribute(&mut self, attr&ast::Attribute) -> IoResult<()> {
  972          try!(self.hardbreak_if_not_bol());
  973          try!(self.maybe_print_comment(attr.span.lo));
  974          if attr.node.is_sugared_doc {
  975              word(&mut self.s, attr.value_str().unwrap().get())
  976          } else {
  977              match attr.node.style {
  978                  ast::AttrInner => try!(word(&mut self.s, "#![")),
  979                  ast::AttrOuter => try!(word(&mut self.s, "#[")),
  980              }
  981              try!(self.print_meta_item(attr.meta()));
  982              word(&mut self.s, "]")
  983          }
  984      }
  985  
  986  
  987      pub fn print_stmt(&mut self, st&ast::Stmt) -> IoResult<()> {
  988          try!(self.maybe_print_comment(st.span.lo));
  989          match st.node {
  990              ast::StmtDecl(decl, _) => {
  991                  try!(self.print_decl(decl));
  992              }
  993              ast::StmtExpr(expr, _) => {
  994                  try!(self.space_if_not_bol());
  995                  try!(self.print_expr(expr));
  996              }
  997              ast::StmtSemi(expr, _) => {
  998                  try!(self.space_if_not_bol());
  999                  try!(self.print_expr(expr));
 1000                  try!(word(&mut self.s, ";"));
 1001              }
 1002              ast::StmtMac(ref mac, semi) => {
 1003                  try!(self.space_if_not_bol());
 1004                  try!(self.print_mac(mac));
 1005                  if semi {
 1006                      try!(word(&mut self.s, ";"));
 1007                  }
 1008              }
 1009          }
 1010          if parse::classify::stmt_ends_with_semi(st) {
 1011              try!(word(&mut self.s, ";"));
 1012          }
 1013          self.maybe_print_trailing_comment(st.span, None)
 1014      }
 1015  
 1016      pub fn print_block(&mut self, blk&ast::Block) -> IoResult<()> {
 1017          self.print_block_with_attrs(blk, &[])
 1018      }
 1019  
 1020      pub fn print_block_unclosed(&mut self, blk&ast::Block) -> IoResult<()> {
 1021          self.print_block_unclosed_indent(blk, indent_unit)
 1022      }
 1023  
 1024      pub fn print_block_unclosed_indent(&mut self, blk&ast::Block,
 1025                                         indenteduint) -> IoResult<()> {
 1026          self.print_block_maybe_unclosed(blk, indented, &[], false)
 1027      }
 1028  
 1029      pub fn print_block_with_attrs(&mut self,
 1030                                    blk&ast::Block,
 1031                                    attrs&[ast::Attribute]) -> IoResult<()> {
 1032          self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
 1033      }
 1034  
 1035      pub fn print_block_maybe_unclosed(&mut self,
 1036                                        blk&ast::Block,
 1037                                        indenteduint,
 1038                                        attrs&[ast::Attribute],
 1039                                        close_boxbool) -> IoResult<()> {
 1040          match blk.rules {
 1041              ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
 1042              ast::DefaultBlock => ()
 1043          }
 1044          try!(self.maybe_print_comment(blk.span.lo));
 1045          try!(self.ann.pre(self, NodeBlock(blk)));
 1046          try!(self.bopen());
 1047  
 1048          try!(self.print_inner_attributes(attrs));
 1049  
 1050          for vi in blk.view_items.iter() {
 1051              try!(self.print_view_item(vi));
 1052          }
 1053          for st in blk.stmts.iter() {
 1054              try!(self.print_stmt(*st));
 1055          }
 1056          match blk.expr {
 1057              Some(expr) => {
 1058                  try!(self.space_if_not_bol());
 1059                  try!(self.print_expr(expr));
 1060                  try!(self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi)));
 1061              }
 1062              _ => ()
 1063          }
 1064          try!(self.bclose_maybe_open(blk.span, indented, close_box));
 1065          self.ann.post(self, NodeBlock(blk))
 1066      }
 1067  
 1068      fn print_else(&mut self, elsOption<@ast::Expr>) -> IoResult<()> {
 1069          match els {
 1070              Some(_else) => {
 1071                  match _else.node {
 1072                      // "another else-if"
 1073                      ast::ExprIf(i, t, e) => {
 1074                          try!(self.cbox(indent_unit - 1u));
 1075                          try!(self.ibox(0u));
 1076                          try!(word(&mut self.s, " else if "));
 1077                          try!(self.print_expr(i));
 1078                          try!(space(&mut self.s));
 1079                          try!(self.print_block(t));
 1080                          self.print_else(e)
 1081                      }
 1082                      // "final else"
 1083                      ast::ExprBlock(b) => {
 1084                          try!(self.cbox(indent_unit - 1u));
 1085                          try!(self.ibox(0u));
 1086                          try!(word(&mut self.s, " else "));
 1087                          self.print_block(b)
 1088                      }
 1089                      // BLEAH, constraints would be great here
 1090                      _ => {
 1091                          fail!("print_if saw if with weird alternative");
 1092                      }
 1093                  }
 1094              }
 1095              _ => Ok(())
 1096          }
 1097      }
 1098  
 1099      pub fn print_if(&mut self, test&ast::Expr, blk&ast::Block,
 1100                      elseoptOption<@ast::Expr>, chkbool) -> IoResult<()> {
 1101          try!(self.head("if"));
 1102          if chk { try!(self.word_nbsp("check")); }
 1103          try!(self.print_expr(test));
 1104          try!(space(&mut self.s));
 1105          try!(self.print_block(blk));
 1106          self.print_else(elseopt)
 1107      }
 1108  
 1109      pub fn print_mac(&mut self, m&ast::Mac) -> IoResult<()> {
 1110          match m.node {
 1111              // I think it's reasonable to hide the ctxt here:
 1112              ast::MacInvocTT(ref pth, ref tts, _) => {
 1113                  try!(self.print_path(pth, false));
 1114                  try!(word(&mut self.s, "!"));
 1115                  try!(self.popen());
 1116                  try!(self.print_tts(&tts.as_slice()));
 1117                  self.pclose()
 1118              }
 1119          }
 1120      }
 1121  
 1122      pub fn print_expr_vstore(&mut self, tast::ExprVstore) -> IoResult<()> {
 1123          match t {
 1124              ast::ExprVstoreUniq => word(&mut self.s, "box "),
 1125              ast::ExprVstoreSlice => word(&mut self.s, "&"),
 1126              ast::ExprVstoreMutSlice => {
 1127                  try!(word(&mut self.s, "&"));
 1128                  word(&mut self.s, "mut")
 1129              }
 1130          }
 1131      }
 1132  
 1133      fn print_call_post(&mut self, args&[@ast::Expr]) -> IoResult<()> {
 1134          try!(self.popen());
 1135          try!(self.commasep_exprs(Inconsistent, args));
 1136          self.pclose()
 1137      }
 1138  
 1139      pub fn print_expr(&mut self, expr&ast::Expr) -> IoResult<()> {
 1140          try!(self.maybe_print_comment(expr.span.lo));
 1141          try!(self.ibox(indent_unit));
 1142          try!(self.ann.pre(self, NodeExpr(expr)));
 1143          match expr.node {
 1144              ast::ExprVstore(e, v) => {
 1145                  try!(self.print_expr_vstore(v));
 1146                  try!(self.print_expr(e));
 1147              },
 1148              ast::ExprBox(p, e) => {
 1149                  try!(word(&mut self.s, "box"));
 1150                  try!(word(&mut self.s, "("));
 1151                  try!(self.print_expr(p));
 1152                  try!(self.word_space(")"));
 1153                  try!(self.print_expr(e));
 1154              }
 1155              ast::ExprVec(ref exprs) => {
 1156                  try!(self.ibox(indent_unit));
 1157                  try!(word(&mut self.s, "["));
 1158                  try!(self.commasep_exprs(Inconsistent, exprs.as_slice()));
 1159                  try!(word(&mut self.s, "]"));
 1160                  try!(self.end());
 1161              }
 1162  
 1163              ast::ExprRepeat(element, count) => {
 1164                  try!(self.ibox(indent_unit));
 1165                  try!(word(&mut self.s, "["));
 1166                  try!(self.print_expr(element));
 1167                  try!(word(&mut self.s, ","));
 1168                  try!(word(&mut self.s, ".."));
 1169                  try!(self.print_expr(count));
 1170                  try!(word(&mut self.s, "]"));
 1171                  try!(self.end());
 1172              }
 1173  
 1174              ast::ExprStruct(ref path, ref fields, wth) => {
 1175                  try!(self.print_path(path, true));
 1176                  try!(word(&mut self.s, "{"));
 1177                  try!(self.commasep_cmnt(
 1178                      Consistent,
 1179                      fields.as_slice(),
 1180                      |s, field| {
 1181                          try!(s.ibox(indent_unit));
 1182                          try!(s.print_ident(field.ident.node));
 1183                          try!(s.word_space(":"));
 1184                          try!(s.print_expr(field.expr));
 1185                          s.end()
 1186                      },
 1187                      |f| f.span));
 1188                  match wth {
 1189                      Some(expr) => {
 1190                          try!(self.ibox(indent_unit));
 1191                          if !fields.is_empty() {
 1192                              try!(word(&mut self.s, ","));
 1193                              try!(space(&mut self.s));
 1194                          }
 1195                          try!(word(&mut self.s, ".."));
 1196                          try!(self.print_expr(expr));
 1197                          try!(self.end());
 1198                      }
 1199                      _ => try!(word(&mut self.s, ","))
 1200                  }
 1201                  try!(word(&mut self.s, "}"));
 1202              }
 1203              ast::ExprTup(ref exprs) => {
 1204                  try!(self.popen());
 1205                  try!(self.commasep_exprs(Inconsistent, exprs.as_slice()));
 1206                  if exprs.len() == 1 {
 1207                      try!(word(&mut self.s, ","));
 1208                  }
 1209                  try!(self.pclose());
 1210              }
 1211              ast::ExprCall(func, ref args) => {
 1212                  try!(self.print_expr(func));
 1213                  try!(self.print_call_post(args.as_slice()));
 1214              }
 1215              ast::ExprMethodCall(ident, ref tys, ref args) => {
 1216                  let base_args = args.slice_from(1);
 1217                  try!(self.print_expr(*args.get(0)));
 1218                  try!(word(&mut self.s, "."));
 1219                  try!(self.print_ident(ident.node));
 1220                  if tys.len() > 0u {
 1221                      try!(word(&mut self.s, "::<"));
 1222                      try!(self.commasep(Inconsistent, tys.as_slice(),
 1223                                         |s, ty| s.print_type_ref(ty)));
 1224                      try!(word(&mut self.s, ">"));
 1225                  }
 1226                  try!(self.print_call_post(base_args));
 1227              }
 1228              ast::ExprBinary(op, lhs, rhs) => {
 1229                  try!(self.print_expr(lhs));
 1230                  try!(space(&mut self.s));
 1231                  try!(self.word_space(ast_util::binop_to_str(op)));
 1232                  try!(self.print_expr(rhs));
 1233              }
 1234              ast::ExprUnary(op, expr) => {
 1235                  try!(word(&mut self.s, ast_util::unop_to_str(op)));
 1236                  try!(self.print_expr(expr));
 1237              }
 1238              ast::ExprAddrOf(m, expr) => {
 1239                  try!(word(&mut self.s, "&"));
 1240                  try!(self.print_mutability(m));
 1241                  // Avoid `& &e` => `&&e`.
 1242                  match (m, &expr.node) {
 1243                      (ast::MutImmutable, &ast::ExprAddrOf(..)) => try!(space(&mut self.s)),
 1244                      _ => { }
 1245                  }
 1246                  try!(self.print_expr(expr));
 1247              }
 1248              ast::ExprLit(lit) => try!(self.print_literal(lit)),
 1249              ast::ExprCast(expr, ty) => {
 1250                  try!(self.print_expr(expr));
 1251                  try!(space(&mut self.s));
 1252                  try!(self.word_space("as"));
 1253                  try!(self.print_type(ty));
 1254              }
 1255              ast::ExprIf(test, blk, elseopt) => {
 1256                  try!(self.print_if(test, blk, elseopt, false));
 1257              }
 1258              ast::ExprWhile(test, blk) => {
 1259                  try!(self.head("while"));
 1260                  try!(self.print_expr(test));
 1261                  try!(space(&mut self.s));
 1262                  try!(self.print_block(blk));
 1263              }
 1264              ast::ExprForLoop(pat, iter, blk, opt_ident) => {
 1265                  for ident in opt_ident.iter() {
 1266                      try!(word(&mut self.s, "'"));
 1267                      try!(self.print_ident(*ident));
 1268                      try!(self.word_space(":"));
 1269                  }
 1270                  try!(self.head("for"));
 1271                  try!(self.print_pat(pat));
 1272                  try!(space(&mut self.s));
 1273                  try!(self.word_space("in"));
 1274                  try!(self.print_expr(iter));
 1275                  try!(space(&mut self.s));
 1276                  try!(self.print_block(blk));
 1277              }
 1278              ast::ExprLoop(blk, opt_ident) => {
 1279                  for ident in opt_ident.iter() {
 1280                      try!(word(&mut self.s, "'"));
 1281                      try!(self.print_ident(*ident));
 1282                      try!(self.word_space(":"));
 1283                  }
 1284                  try!(self.head("loop"));
 1285                  try!(space(&mut self.s));
 1286                  try!(self.print_block(blk));
 1287              }
 1288              ast::ExprMatch(expr, ref arms) => {
 1289                  try!(self.cbox(indent_unit));
 1290                  try!(self.ibox(4));
 1291                  try!(self.word_nbsp("match"));
 1292                  try!(self.print_expr(expr));
 1293                  try!(space(&mut self.s));
 1294                  try!(self.bopen());
 1295                  let len = arms.len();
 1296                  for (i, arm) in arms.iter().enumerate() {
 1297                      // I have no idea why this check is necessary, but here it
 1298                      // is :(
 1299                      if arm.attrs.is_empty() {
 1300                          try!(space(&mut self.s));
 1301                      }
 1302                      try!(self.cbox(indent_unit));
 1303                      try!(self.ibox(0u));
 1304                      try!(self.print_outer_attributes(arm.attrs.as_slice()));
 1305                      let mut first = true;
 1306                      for p in arm.pats.iter() {
 1307                          if first {
 1308                              first = false;
 1309                          } else {
 1310                              try!(space(&mut self.s));
 1311                              try!(self.word_space("|"));
 1312                          }
 1313                          try!(self.print_pat(*p));
 1314                      }
 1315                      try!(space(&mut self.s));
 1316                      match arm.guard {
 1317                          Some(e) => {
 1318                              try!(self.word_space("if"));
 1319                              try!(self.print_expr(e));
 1320                              try!(space(&mut self.s));
 1321                          }
 1322                          None => ()
 1323                      }
 1324                      try!(self.word_space("=>"));
 1325  
 1326                      match arm.body.node {
 1327                          ast::ExprBlock(blk) => {
 1328                              // the block will close the pattern's ibox
 1329                              try!(self.print_block_unclosed_indent(blk, indent_unit));
 1330                          }
 1331                          _ => {
 1332                              try!(self.end()); // close the ibox for the pattern
 1333                              try!(self.print_expr(arm.body));
 1334                          }
 1335                      }
 1336                      if !expr_is_simple_block(expr)
 1337                          && i < len - 1 {
 1338                          try!(word(&mut self.s, ","));
 1339                      }
 1340                      try!(self.end()); // close enclosing cbox
 1341                  }
 1342                  try!(self.bclose_(expr.span, indent_unit));
 1343              }
 1344              ast::ExprFnBlock(decl, body) => {
 1345                  // in do/for blocks we don't want to show an empty
 1346                  // argument list, but at this point we don't know which
 1347                  // we are inside.
 1348                  //
 1349                  // if !decl.inputs.is_empty() {
 1350                  try!(self.print_fn_block_args(decl));
 1351                  try!(space(&mut self.s));
 1352                  // }
 1353  
 1354                  if !body.stmts.is_empty() || !body.expr.is_some() {
 1355                      try!(self.print_block_unclosed(body));
 1356                  } else {
 1357                      // we extract the block, so as not to create another set of boxes
 1358                      match body.expr.unwrap().node {
 1359                          ast::ExprBlock(blk) => {
 1360                              try!(self.print_block_unclosed(blk));
 1361                          }
 1362                          _ => {
 1363                              // this is a bare expression
 1364                              try!(self.print_expr(body.expr.unwrap()));
 1365                              try!(self.end()); // need to close a box
 1366                          }
 1367                      }
 1368                  }
 1369                  // a box will be closed by print_expr, but we didn't want an overall
 1370                  // wrapper so we closed the corresponding opening. so create an
 1371                  // empty box to satisfy the close.
 1372                  try!(self.ibox(0));
 1373              }
 1374              ast::ExprProc(decl, body) => {
 1375                  // in do/for blocks we don't want to show an empty
 1376                  // argument list, but at this point we don't know which
 1377                  // we are inside.
 1378                  //
 1379                  // if !decl.inputs.is_empty() {
 1380                  try!(self.print_proc_args(decl));
 1381                  try!(space(&mut self.s));
 1382                  // }
 1383                  assert!(body.stmts.is_empty());
 1384                  assert!(body.expr.is_some());
 1385                  // we extract the block, so as not to create another set of boxes
 1386                  match body.expr.unwrap().node {
 1387                      ast::ExprBlock(blk) => {
 1388                          try!(self.print_block_unclosed(blk));
 1389                      }
 1390                      _ => {
 1391                          // this is a bare expression
 1392                          try!(self.print_expr(body.expr.unwrap()));
 1393                          try!(self.end()); // need to close a box
 1394                      }
 1395                  }
 1396                  // a box will be closed by print_expr, but we didn't want an overall
 1397                  // wrapper so we closed the corresponding opening. so create an
 1398                  // empty box to satisfy the close.
 1399                  try!(self.ibox(0));
 1400              }
 1401              ast::ExprBlock(blk) => {
 1402                  // containing cbox, will be closed by print-block at }
 1403                  try!(self.cbox(indent_unit));
 1404                  // head-box, will be closed by print-block after {
 1405                  try!(self.ibox(0u));
 1406                  try!(self.print_block(blk));
 1407              }
 1408              ast::ExprAssign(lhs, rhs) => {
 1409                  try!(self.print_expr(lhs));
 1410                  try!(space(&mut self.s));
 1411                  try!(self.word_space("="));
 1412                  try!(self.print_expr(rhs));
 1413              }
 1414              ast::ExprAssignOp(op, lhs, rhs) => {
 1415                  try!(self.print_expr(lhs));
 1416                  try!(space(&mut self.s));
 1417                  try!(word(&mut self.s, ast_util::binop_to_str(op)));
 1418                  try!(self.word_space("="));
 1419                  try!(self.print_expr(rhs));
 1420              }
 1421              ast::ExprField(expr, id, ref tys) => {
 1422                  try!(self.print_expr(expr));
 1423                  try!(word(&mut self.s, "."));
 1424                  try!(self.print_ident(id));
 1425                  if tys.len() > 0u {
 1426                      try!(word(&mut self.s, "::<"));
 1427                      try!(self.commasep(
 1428                          Inconsistent, tys.as_slice(),
 1429                          |s, ty| s.print_type_ref(ty)));
 1430                      try!(word(&mut self.s, ">"));
 1431                  }
 1432              }
 1433              ast::ExprIndex(expr, index) => {
 1434                  try!(self.print_expr(expr));
 1435                  try!(word(&mut self.s, "["));
 1436                  try!(self.print_expr(index));
 1437                  try!(word(&mut self.s, "]"));
 1438              }
 1439              ast::ExprPath(ref path) => try!(self.print_path(path, true)),
 1440              ast::ExprBreak(opt_ident) => {
 1441                  try!(word(&mut self.s, "break"));
 1442                  try!(space(&mut self.s));
 1443                  for ident in opt_ident.iter() {
 1444                      try!(word(&mut self.s, "'"));
 1445                      try!(self.print_ident(*ident));
 1446                      try!(space(&mut self.s));
 1447                  }
 1448              }
 1449              ast::ExprAgain(opt_ident) => {
 1450                  try!(word(&mut self.s, "continue"));
 1451                  try!(space(&mut self.s));
 1452                  for ident in opt_ident.iter() {
 1453                      try!(word(&mut self.s, "'"));
 1454                      try!(self.print_ident(*ident));
 1455                      try!(space(&mut self.s))
 1456                  }
 1457              }
 1458              ast::ExprRet(result) => {
 1459                  try!(word(&mut self.s, "return"));
 1460                  match result {
 1461                      Some(expr) => {
 1462                          try!(word(&mut self.s, " "));
 1463                          try!(self.print_expr(expr));
 1464                      }
 1465                      _ => ()
 1466                  }
 1467              }
 1468              ast::ExprInlineAsm(ref a) => {
 1469                  if a.volatile {
 1470                      try!(word(&mut self.s, "__volatile__ asm!"));
 1471                  } else {
 1472                      try!(word(&mut self.s, "asm!"));
 1473                  }
 1474                  try!(self.popen());
 1475                  try!(self.print_string(a.asm.get(), a.asm_str_style));
 1476                  try!(self.word_space(":"));
 1477                  for &(ref co, o) in a.outputs.iter() {
 1478                      try!(self.print_string(co.get(), ast::CookedStr));
 1479                      try!(self.popen());
 1480                      try!(self.print_expr(o));
 1481                      try!(self.pclose());
 1482                      try!(self.word_space(","));
 1483                  }
 1484                  try!(self.word_space(":"));
 1485                  for &(ref co, o) in a.inputs.iter() {
 1486                      try!(self.print_string(co.get(), ast::CookedStr));
 1487                      try!(self.popen());
 1488                      try!(self.print_expr(o));
 1489                      try!(self.pclose());
 1490                      try!(self.word_space(","));
 1491                  }
 1492                  try!(self.word_space(":"));
 1493                  try!(self.print_string(a.clobbers.get(), ast::CookedStr));
 1494                  try!(self.pclose());
 1495              }
 1496              ast::ExprMac(ref m) => try!(self.print_mac(m)),
 1497              ast::ExprParen(e) => {
 1498                  try!(self.popen());
 1499                  try!(self.print_expr(e));
 1500                  try!(self.pclose());
 1501              }
 1502          }
 1503          try!(self.ann.post(self, NodeExpr(expr)));
 1504          self.end()
 1505      }
 1506  
 1507      pub fn print_local_decl(&mut self, loc&ast::Local) -> IoResult<()> {
 1508          try!(self.print_pat(loc.pat));
 1509          match loc.ty.node {
 1510              ast::TyInfer => Ok(()),
 1511              _ => {
 1512                  try!(self.word_space(":"));
 1513                  self.print_type(loc.ty)
 1514              }
 1515          }
 1516      }
 1517  
 1518      pub fn print_decl(&mut self, decl&ast::Decl) -> IoResult<()> {
 1519          try!(self.maybe_print_comment(decl.span.lo));
 1520          match decl.node {
 1521              ast::DeclLocal(loc) => {
 1522                  try!(self.space_if_not_bol());
 1523                  try!(self.ibox(indent_unit));
 1524                  try!(self.word_nbsp("let"));
 1525  
 1526                  try!(self.ibox(indent_unit));
 1527                  try!(self.print_local_decl(loc));
 1528                  try!(self.end());
 1529                  match loc.init {
 1530                      Some(init) => {
 1531                          try!(self.nbsp());
 1532                          try!(self.word_space("="));
 1533                          try!(self.print_expr(init));
 1534                      }
 1535                      _ => {}
 1536                  }
 1537                  self.end()
 1538              }
 1539              ast::DeclItem(item) => self.print_item(item)
 1540          }
 1541      }
 1542  
 1543      pub fn print_ident(&mut self, identast::Ident) -> IoResult<()> {
 1544          word(&mut self.s, token::get_ident(ident).get())
 1545      }
 1546  
 1547      pub fn print_name(&mut self, nameast::Name) -> IoResult<()> {
 1548          word(&mut self.s, token::get_name(name).get())
 1549      }
 1550  
 1551      pub fn print_for_decl(&mut self, loc&ast::Local,
 1552                            coll&ast::Expr) -> IoResult<()> {
 1553          try!(self.print_local_decl(loc));
 1554          try!(space(&mut self.s));
 1555          try!(self.word_space("in"));
 1556          self.print_expr(coll)
 1557      }
 1558  
 1559      fn print_path_(&mut self,
 1560                     path&ast::Path,
 1561                     colons_before_paramsbool,
 1562                     opt_bounds&Option<OwnedSlice<ast::TyParamBound>>)
 1563          -> IoResult<()> {
 1564          try!(self.maybe_print_comment(path.span.lo));
 1565          if path.global {
 1566              try!(word(&mut self.s, "::"));
 1567          }
 1568  
 1569          let mut first = true;
 1570          for segment in path.segments.iter() {
 1571              if first {
 1572                  first = false
 1573              } else {
 1574                  try!(word(&mut self.s, "::"))
 1575              }
 1576  
 1577              try!(self.print_ident(segment.identifier));
 1578  
 1579              if !segment.lifetimes.is_empty() || !segment.types.is_empty() {
 1580                  if colons_before_params {
 1581                      try!(word(&mut self.s, "::"))
 1582                  }
 1583                  try!(word(&mut self.s, "<"));
 1584  
 1585                  let mut comma = false;
 1586                  for lifetime in segment.lifetimes.iter() {
 1587                      if comma {
 1588                          try!(self.word_space(","))
 1589                      }
 1590                      try!(self.print_lifetime(lifetime));
 1591                      comma = true;
 1592                  }
 1593  
 1594                  if !segment.types.is_empty() {
 1595                      if comma {
 1596                          try!(self.word_space(","))
 1597                      }
 1598                      try!(self.commasep(
 1599                          Inconsistent,
 1600                          segment.types.as_slice(),
 1601                          |s, ty| s.print_type_ref(ty)));
 1602                  }
 1603  
 1604                  try!(word(&mut self.s, ">"))
 1605              }
 1606          }
 1607  
 1608          match *opt_bounds {
 1609              None => Ok(()),
 1610              Some(ref bounds) => self.print_bounds(&None, bounds, true),
 1611          }
 1612      }
 1613  
 1614      fn print_path(&mut self, path&ast::Path,
 1615                    colons_before_paramsbool) -> IoResult<()> {
 1616          self.print_path_(path, colons_before_params, &None)
 1617      }
 1618  
 1619      fn print_bounded_path(&mut self, path&ast::Path,
 1620                            bounds&Option<OwnedSlice<ast::TyParamBound>>)
 1621          -> IoResult<()> {
 1622          self.print_path_(path, false, bounds)
 1623      }
 1624  
 1625      pub fn print_pat(&mut self, pat&ast::Pat) -> IoResult<()> {
 1626          try!(self.maybe_print_comment(pat.span.lo));
 1627          try!(self.ann.pre(self, NodePat(pat)));
 1628          /* Pat isn't normalized, but the beauty of it
 1629           is that it doesn't matter */
 1630          match pat.node {
 1631              ast::PatWild => try!(word(&mut self.s, "_")),
 1632              ast::PatWildMulti => try!(word(&mut self.s, "..")),
 1633              ast::PatIdent(binding_mode, ref path, sub) => {
 1634                  match binding_mode {
 1635                      ast::BindByRef(mutbl) => {
 1636                          try!(self.word_nbsp("ref"));
 1637                          try!(self.print_mutability(mutbl));
 1638                      }
 1639                      ast::BindByValue(ast::MutImmutable) => {}
 1640                      ast::BindByValue(ast::MutMutable) => {
 1641                          try!(self.word_nbsp("mut"));
 1642                      }
 1643                  }
 1644                  try!(self.print_path(path, true));
 1645                  match sub {
 1646                      Some(p) => {
 1647                          try!(word(&mut self.s, "@"));
 1648                          try!(self.print_pat(p));
 1649                      }
 1650                      None => ()
 1651                  }
 1652              }
 1653              ast::PatEnum(ref path, ref args_) => {
 1654                  try!(self.print_path(path, true));
 1655                  match *args_ {
 1656                      None => try!(word(&mut self.s, "(..)")),
 1657                      Some(ref args) => {
 1658                          if !args.is_empty() {
 1659                              try!(self.popen());
 1660                              try!(self.commasep(Inconsistent, args.as_slice(),
 1661                                                |s, &p| s.print_pat(p)));
 1662                              try!(self.pclose());
 1663                          }
 1664                      }
 1665                  }
 1666              }
 1667              ast::PatStruct(ref path, ref fields, etc) => {
 1668                  try!(self.print_path(path, true));
 1669                  try!(word(&mut self.s, "{"));
 1670                  try!(self.commasep_cmnt(
 1671                      Consistent, fields.as_slice(),
 1672                      |s, f| {
 1673                          try!(s.cbox(indent_unit));
 1674                          try!(s.print_ident(f.ident));
 1675                          try!(s.word_space(":"));
 1676                          try!(s.print_pat(f.pat));
 1677                          s.end()
 1678                      },
 1679                      |f| f.pat.span));
 1680                  if etc {
 1681                      if fields.len() != 0u { try!(self.word_space(",")); }
 1682                      try!(word(&mut self.s, ".."));
 1683                  }
 1684                  try!(word(&mut self.s, "}"));
 1685              }
 1686              ast::PatTup(ref elts) => {
 1687                  try!(self.popen());
 1688                  try!(self.commasep(Inconsistent,
 1689                                     elts.as_slice(),
 1690                                     |s, &p| s.print_pat(p)));
 1691                  if elts.len() == 1 {
 1692                      try!(word(&mut self.s, ","));
 1693                  }
 1694                  try!(self.pclose());
 1695              }
 1696              ast::PatUniq(inner) => {
 1697                  try!(word(&mut self.s, "box "));
 1698                  try!(self.print_pat(inner));
 1699              }
 1700              ast::PatRegion(inner) => {
 1701                  try!(word(&mut self.s, "&"));
 1702                  try!(self.print_pat(inner));
 1703              }
 1704              ast::PatLit(e) => try!(self.print_expr(e)),
 1705              ast::PatRange(begin, end) => {
 1706                  try!(self.print_expr(begin));
 1707                  try!(space(&mut self.s));
 1708                  try!(word(&mut self.s, ".."));
 1709                  try!(self.print_expr(end));
 1710              }
 1711              ast::PatVec(ref before, slice, ref after) => {
 1712                  try!(word(&mut self.s, "["));
 1713                  try!(self.commasep(Inconsistent,
 1714                                     before.as_slice(),
 1715                                     |s, &p| s.print_pat(p)));
 1716                  for &p in slice.iter() {
 1717                      if !before.is_empty() { try!(self.word_space(",")); }
 1718                      match *p {
 1719                          ast::Pat { node: ast::PatWildMulti, .. } => {
 1720                              // this case is handled by print_pat
 1721                          }
 1722                          _ => try!(word(&mut self.s, "..")),
 1723                      }
 1724                      try!(self.print_pat(p));
 1725                      if !after.is_empty() { try!(self.word_space(",")); }
 1726                  }
 1727                  try!(self.commasep(Inconsistent,
 1728                                     after.as_slice(),
 1729                                     |s, &p| s.print_pat(p)));
 1730                  try!(word(&mut self.s, "]"));
 1731              }
 1732          }
 1733          self.ann.post(self, NodePat(pat))
 1734      }
 1735  
 1736      // Returns whether it printed anything
 1737      fn print_explicit_self(&mut self,
 1738                             explicit_selfast::ExplicitSelf_,
 1739                             mutblast::Mutability) -> IoResult<bool> {
 1740          try!(self.print_mutability(mutbl));
 1741          match explicit_self {
 1742              ast::SelfStatic => { return Ok(false); }
 1743              ast::SelfValue => {
 1744                  try!(word(&mut self.s, "self"));
 1745              }
 1746              ast::SelfUniq => {
 1747                  try!(word(&mut self.s, "~self"));
 1748              }
 1749              ast::SelfRegion(ref lt, m) => {
 1750                  try!(word(&mut self.s, "&"));
 1751                  try!(self.print_opt_lifetime(lt));
 1752                  try!(self.print_mutability(m));
 1753                  try!(word(&mut self.s, "self"));
 1754              }
 1755          }
 1756          return Ok(true);
 1757      }
 1758  
 1759      pub fn print_fn(&mut self,
 1760                      decl&ast::FnDecl,
 1761                      fn_styleOption<ast::FnStyle>,
 1762                      abiabi::Abi,
 1763                      nameast::Ident,
 1764                      generics&ast::Generics,
 1765                      opt_explicit_selfOption<ast::ExplicitSelf_>,
 1766                      visast::Visibility) -> IoResult<()> {
 1767          try!(self.head(""));
 1768          try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi, vis));
 1769          try!(self.nbsp());
 1770          try!(self.print_ident(name));
 1771          try!(self.print_generics(generics));
 1772          self.print_fn_args_and_ret(decl, opt_explicit_self)
 1773      }
 1774  
 1775      pub fn print_fn_args(&mut self, decl&ast::FnDecl,
 1776                           opt_explicit_selfOption<ast::ExplicitSelf_>)
 1777          -> IoResult<()> {
 1778          // It is unfortunate to duplicate the commasep logic, but we want the
 1779          // self type and the args all in the same box.
 1780          try!(self.rbox(0u, Inconsistent));
 1781          let mut first = true;
 1782          for &explicit_self in opt_explicit_self.iter() {
 1783              let m = match explicit_self {
 1784                  ast::SelfStatic => ast::MutImmutable,
 1785                  _ => match decl.inputs.get(0).pat.node {
 1786                      ast::PatIdent(ast::BindByValue(m), _, _) => m,
 1787                      _ => ast::MutImmutable
 1788                  }
 1789              };
 1790              first = !try!(self.print_explicit_self(explicit_self, m));
 1791          }
 1792  
 1793          // HACK(eddyb) ignore the separately printed self argument.
 1794          let args = if first {
 1795              decl.inputs.as_slice()
 1796          } else {
 1797              decl.inputs.slice_from(1)
 1798          };
 1799  
 1800          for arg in args.iter() {
 1801              if first { first = false; } else { try!(self.word_space(",")); }
 1802              try!(self.print_arg(arg));
 1803          }
 1804  
 1805          self.end()
 1806      }
 1807  
 1808      pub fn print_fn_args_and_ret(&mut self, decl&ast::FnDecl,
 1809                                   opt_explicit_selfOption<ast::ExplicitSelf_>)
 1810          -> IoResult<()> {
 1811          try!(self.popen());
 1812          try!(self.print_fn_args(decl, opt_explicit_self));
 1813          if decl.variadic {
 1814              try!(word(&mut self.s, ", ..."));
 1815          }
 1816          try!(self.pclose());
 1817  
 1818          try!(self.maybe_print_comment(decl.output.span.lo));
 1819          match decl.output.node {
 1820              ast::TyNil => Ok(()),
 1821              _ => {
 1822                  try!(self.space_if_not_bol());
 1823                  try!(self.word_space("->"));
 1824                  self.print_type(decl.output)
 1825              }
 1826          }
 1827      }
 1828  
 1829      pub fn print_fn_block_args(&mut self,
 1830                                 decl&ast::FnDecl) -> IoResult<()> {
 1831          try!(word(&mut self.s, "|"));
 1832          try!(self.print_fn_args(decl, None));
 1833          try!(word(&mut self.s, "|"));
 1834  
 1835          match decl.output.node {
 1836              ast::TyInfer => {}
 1837              _ => {
 1838                  try!(self.space_if_not_bol());
 1839                  try!(self.word_space("->"));
 1840                  try!(self.print_type(decl.output));
 1841              }
 1842          }
 1843  
 1844          self.maybe_print_comment(decl.output.span.lo)
 1845      }
 1846  
 1847      pub fn print_proc_args(&mut self, decl&ast::FnDecl) -> IoResult<()> {
 1848          try!(word(&mut self.s, "proc"));
 1849          try!(word(&mut self.s, "("));
 1850          try!(self.print_fn_args(decl, None));
 1851          try!(word(&mut self.s, ")"));
 1852  
 1853          match decl.output.node {
 1854              ast::TyInfer => {}
 1855              _ => {
 1856                  try!(self.space_if_not_bol());
 1857                  try!(self.word_space("->"));
 1858                  try!(self.print_type(decl.output));
 1859              }
 1860          }
 1861  
 1862          self.maybe_print_comment(decl.output.span.lo)
 1863      }
 1864  
 1865      pub fn print_bounds(&mut self,
 1866                          region&Option<ast::Lifetime>,
 1867                          bounds&OwnedSlice<ast::TyParamBound>,
 1868                          print_colon_anywaybool) -> IoResult<()> {
 1869          if !bounds.is_empty() || region.is_some() {
 1870              try!(word(&mut self.s, ":"));
 1871              let mut first = true;
 1872              match *region {
 1873                  Some(ref lt) => {
 1874                      let token = token::get_name(lt.name);
 1875                      if token.get() != "static{
 1876                          try!(self.nbsp());
 1877                          first = false;
 1878                          try!(self.print_lifetime(lt));
 1879                      }
 1880                  }
 1881                  None => {}
 1882              }
 1883              for bound in bounds.iter() {
 1884                  try!(self.nbsp());
 1885                  if first {
 1886                      first = false;
 1887                  } else {
 1888                      try!(self.word_space("+"));
 1889                  }
 1890  
 1891                  try!(match *bound {
 1892                      TraitTyParamBound(ref tref) => self.print_trait_ref(tref),
 1893                      StaticRegionTyParamBound => word(&mut self.s, "'static"),
 1894                      OtherRegionTyParamBound(_) => Ok(())
 1895                  })
 1896              }
 1897              Ok(())
 1898          } else if print_colon_anyway {
 1899              word(&mut self.s, ":")
 1900          } else {
 1901              Ok(())
 1902          }
 1903      }
 1904  
 1905      pub fn print_lifetime(&mut self,
 1906                            lifetime&ast::Lifetime) -> IoResult<()> {
 1907          try!(word(&mut self.s, "'"));
 1908          self.print_name(lifetime.name)
 1909      }
 1910  
 1911      pub fn print_generics(&mut self,
 1912                            generics&ast::Generics) -> IoResult<()> {
 1913          let total = generics.lifetimes.len() + generics.ty_params.len();
 1914          if total > 0 {
 1915              try!(word(&mut self.s, "<"));
 1916  
 1917              let mut ints = Vec::new();
 1918              for i in range(0u, total) {
 1919                  ints.push(i);
 1920              }
 1921  
 1922              try!(self.commasep(
 1923                  Inconsistent, ints.as_slice(),
 1924                  |s, &idx| {
 1925                      if idx < generics.lifetimes.len() {
 1926                          let lifetime = generics.lifetimes.get(idx);
 1927                          s.print_lifetime(lifetime)
 1928                      } else {
 1929                          let idx = idx - generics.lifetimes.len();
 1930                          let param = generics.ty_params.get(idx);
 1931                          if param.sized == ast::DynSize {
 1932                              try!(s.word_space("type"));
 1933                          }
 1934                          try!(s.print_ident(param.ident));
 1935                          try!(s.print_bounds(&None, &param.bounds, false));
 1936                          match param.default {
 1937                              Some(default) => {
 1938                                  try!(space(&mut s.s));
 1939                                  try!(s.word_space("="));
 1940                                  s.print_type(default)
 1941                              }
 1942                              _ => Ok(())
 1943                          }
 1944                      }
 1945                  }));
 1946              word(&mut self.s, ">")
 1947          } else {
 1948              Ok(())
 1949          }
 1950      }
 1951  
 1952      pub fn print_meta_item(&mut self, item&ast::MetaItem) -> IoResult<()> {
 1953          try!(self.ibox(indent_unit));
 1954          match item.node {
 1955              ast::MetaWord(ref name) => {
 1956                  try!(word(&mut self.s, name.get()));
 1957              }
 1958              ast::MetaNameValue(ref name, ref value) => {
 1959                  try!(self.word_space(name.get()));
 1960                  try!(self.word_space("="));
 1961                  try!(self.print_literal(value));
 1962              }
 1963              ast::MetaList(ref name, ref items) => {
 1964                  try!(word(&mut self.s, name.get()));
 1965                  try!(self.popen());
 1966                  try!(self.commasep(Consistent,
 1967                                     items.as_slice(),
 1968                                     |s, &i| s.print_meta_item(i)));
 1969                  try!(self.pclose());
 1970              }
 1971          }
 1972          self.end()
 1973      }
 1974  
 1975      pub fn print_view_path(&mut self, vp&ast::ViewPath) -> IoResult<()> {
 1976          match vp.node {
 1977              ast::ViewPathSimple(ident, ref path, _) => {
 1978                  // FIXME(#6993) can't compare identifiers directly here
 1979                  if path.segments.last().unwrap().identifier.name != ident.name {
 1980                      try!(self.print_ident(ident));
 1981                      try!(space(&mut self.s));
 1982                      try!(self.word_space("="));
 1983                  }
 1984                  self.print_path(path, false)
 1985              }
 1986  
 1987              ast::ViewPathGlob(ref path, _) => {
 1988                  try!(self.print_path(path, false));
 1989                  word(&mut self.s, "::*")
 1990              }
 1991  
 1992              ast::ViewPathList(ref path, ref idents, _) => {
 1993                  if path.segments.is_empty() {
 1994                      try!(word(&mut self.s, "{"));
 1995                  } else {
 1996                      try!(self.print_path(path, false));
 1997                      try!(word(&mut self.s, "::{"));
 1998                  }
 1999                  try!(self.commasep(Inconsistent, idents.as_slice(), |s, w| {
 2000                      s.print_ident(w.node.name)
 2001                  }));
 2002                  word(&mut self.s, "}")
 2003              }
 2004          }
 2005      }
 2006  
 2007      pub fn print_view_item(&mut self, item&ast::ViewItem) -> IoResult<()> {
 2008          try!(self.hardbreak_if_not_bol());
 2009          try!(self.maybe_print_comment(item.span.lo));
 2010          try!(self.print_outer_attributes(item.attrs.as_slice()));
 2011          try!(self.print_visibility(item.vis));
 2012          match item.node {
 2013              ast::ViewItemExternCrate(id, ref optional_path, _) => {
 2014                  try!(self.head("extern crate"));
 2015                  try!(self.print_ident(id));
 2016                  for &(ref p, style) in optional_path.iter() {
 2017                      try!(space(&mut self.s));
 2018                      try!(word(&mut self.s, "="));
 2019                      try!(space(&mut self.s));
 2020                      try!(self.print_string(p.get(), style));
 2021                  }
 2022              }
 2023  
 2024              ast::ViewItemUse(ref vp) => {
 2025                  try!(self.head("use"));
 2026                  try!(self.print_view_path(*vp));
 2027              }
 2028          }
 2029          try!(word(&mut self.s, ";"));
 2030          try!(self.end()); // end inner head-block
 2031          self.end() // end outer head-block
 2032      }
 2033  
 2034      pub fn print_mutability(&mut self,
 2035                              mutblast::Mutability) -> IoResult<()> {
 2036          match mutbl {
 2037              ast::MutMutable => self.word_nbsp("mut"),
 2038              ast::MutImmutable => Ok(()),
 2039          }
 2040      }
 2041  
 2042      pub fn print_mt(&mut self, mt&ast::MutTy) -> IoResult<()> {
 2043          try!(self.print_mutability(mt.mutbl));
 2044          self.print_type(mt.ty)
 2045      }
 2046  
 2047      pub fn print_arg(&mut self, input&ast::Arg) -> IoResult<()> {
 2048          try!(self.ibox(indent_unit));
 2049          match input.ty.node {
 2050              ast::TyInfer => try!(self.print_pat(input.pat)),
 2051              _ => {
 2052                  match input.pat.node {
 2053                      ast::PatIdent(_, ref path, _) if
 2054                          path.segments.len() == 1 &&
 2055                          path.segments.get(0).identifier.name ==
 2056                              parse::token::special_idents::invalid.name => {
 2057                          // Do nothing.
 2058                      }
 2059                      _ => {
 2060                          try!(self.print_pat(input.pat));
 2061                          try!(word(&mut self.s, ":"));
 2062                          try!(space(&mut self.s));
 2063                      }
 2064                  }
 2065                  try!(self.print_type(input.ty));
 2066              }
 2067          }
 2068          self.end()
 2069      }
 2070  
 2071      pub fn print_ty_fn(&mut self,
 2072                         opt_abiOption<abi::Abi>,
 2073                         opt_sigilOption<char>,
 2074                         opt_region&Option<ast::Lifetime>,
 2075                         fn_styleast::FnStyle,
 2076                         oncenessast::Onceness,
 2077                         decl&ast::FnDecl,
 2078                         idOption<ast::Ident>,
 2079                         opt_bounds&Option<OwnedSlice<ast::TyParamBound>>,
 2080                         genericsOption<&ast::Generics>,
 2081                         opt_explicit_selfOption<ast::ExplicitSelf_>)
 2082          -> IoResult<()> {
 2083          try!(self.ibox(indent_unit));
 2084  
 2085          // Duplicates the logic in `print_fn_header_info()`.  This is because that
 2086          // function prints the sigil in the wrong place.  That should be fixed.
 2087          if opt_sigil == Some('~') && onceness == ast::Once {
 2088              try!(word(&mut self.s, "proc"));
 2089          } else if opt_sigil == Some('&') {
 2090              try!(self.print_extern_opt_abi(opt_abi));
 2091              try!(self.print_fn_style(fn_style));
 2092              try!(self.print_onceness(onceness));
 2093          } else {
 2094              assert!(opt_sigil.is_none());
 2095              try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
 2096              try!(self.print_fn_style(fn_style));
 2097              try!(self.print_onceness(onceness));
 2098              try!(word(&mut self.s, "fn"));
 2099          }
 2100  
 2101          match id {
 2102              Some(id) => {
 2103                  try!(word(&mut self.s, " "));
 2104                  try!(self.print_ident(id));
 2105              }
 2106              _ => ()
 2107          }
 2108  
 2109          match generics { Some(g) => try!(self.print_generics(g)), _ => () }
 2110          try!(zerobreak(&mut self.s));
 2111  
 2112          if opt_sigil == Some('&') {
 2113              try!(word(&mut self.s, "|"));
 2114          } else {
 2115              try!(self.popen());
 2116          }
 2117  
 2118          try!(self.print_fn_args(decl, opt_explicit_self));
 2119  
 2120          if opt_sigil == Some('&') {
 2121              try!(word(&mut self.s, "|"));
 2122          } else {
 2123              if decl.variadic {
 2124                  try!(word(&mut self.s, ", ..."));
 2125              }
 2126              try!(self.pclose());
 2127          }
 2128  
 2129          opt_bounds.as_ref().map(|bounds| {
 2130              self.print_bounds(opt_region, bounds, true)
 2131          });
 2132  
 2133          try!(self.maybe_print_comment(decl.output.span.lo));
 2134  
 2135          match decl.output.node {
 2136              ast::TyNil => {}
 2137              _ => {
 2138                  try!(self.space_if_not_bol());
 2139                  try!(self.ibox(indent_unit));
 2140                  try!(self.word_space("->"));
 2141                  if decl.cf == ast::NoReturn {
 2142                      try!(self.word_nbsp("!"));
 2143                  } else {
 2144                      try!(self.print_type(decl.output));
 2145                  }
 2146                  try!(self.end());
 2147              }
 2148          }
 2149  
 2150          self.end()
 2151      }
 2152  
 2153      pub fn maybe_print_trailing_comment(&mut self, spancodemap::Span,
 2154                                          next_posOption<BytePos>)
 2155          -> IoResult<()> {
 2156          let cm = match self.cm {
 2157              Some(cm) => cm,
 2158              _ => return Ok(())
 2159          };
 2160          match self.next_comment() {
 2161              Some(ref cmnt) => {
 2162                  if (*cmnt).style != comments::Trailing { return Ok(()) }
 2163                  let span_line = cm.lookup_char_pos(span.hi);
 2164                  let comment_line = cm.lookup_char_pos((*cmnt).pos);
 2165                  let mut next = (*cmnt).pos + BytePos(1);
 2166                  match next_pos { None => (), Some(p) => next = p }
 2167                  if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
 2168                      span_line.line == comment_line.line {
 2169                          try!(self.print_comment(cmnt));
 2170                          self.cur_cmnt_and_lit.cur_cmnt += 1u;
 2171                      }
 2172              }
 2173              _ => ()
 2174          }
 2175          Ok(())
 2176      }
 2177  
 2178      pub fn print_remaining_comments(&mut self) -> IoResult<()> {
 2179          // If there aren't any remaining comments, then we need to manually
 2180          // make sure there is a line break at the end.
 2181          if self.next_comment().is_none() {
 2182              try!(hardbreak(&mut self.s));
 2183          }
 2184          loop {
 2185              match self.next_comment() {
 2186                  Some(ref cmnt) => {
 2187                      try!(self.print_comment(cmnt));
 2188                      self.cur_cmnt_and_lit.cur_cmnt += 1u;
 2189                  }
 2190                  _ => break
 2191              }
 2192          }
 2193          Ok(())
 2194      }
 2195  
 2196      pub fn print_literal(&mut self, lit&ast::Lit) -> IoResult<()> {
 2197          try!(self.maybe_print_comment(lit.span.lo));
 2198          match self.next_lit(lit.span.lo) {
 2199              Some(ref ltrl) => {
 2200                  return word(&mut self.s, (*ltrl).lit.as_slice());
 2201              }
 2202              _ => ()
 2203          }
 2204          match lit.node {
 2205              ast::LitStr(ref st, style) => self.print_string(st.get(), style),
 2206              ast::LitChar(ch) => {
 2207                  let mut res = StrBuf::from_str("'");
 2208                  ch.escape_default(|c| res.push_char(c));
 2209                  res.push_char('\'');
 2210                  word(&mut self.s, res.into_owned())
 2211              }
 2212              ast::LitInt(i, t) => {
 2213                  word(&mut self.s,
 2214                       ast_util::int_ty_to_str(t, Some(i)).as_slice())
 2215              }
 2216              ast::LitUint(u, t) => {
 2217                  word(&mut self.s,
 2218                       ast_util::uint_ty_to_str(t, Some(u)).as_slice())
 2219              }
 2220              ast::LitIntUnsuffixed(i) => {
 2221                  word(&mut self.s, format!("{}", i))
 2222              }
 2223              ast::LitFloat(ref f, t) => {
 2224                  word(&mut self.s,
 2225                       f.get() + ast_util::float_ty_to_str(t).as_slice())
 2226              }
 2227              ast::LitFloatUnsuffixed(ref f) => word(&mut self.s, f.get()),
 2228              ast::LitNil => word(&mut self.s, "()"),
 2229              ast::LitBool(val) => {
 2230                  if val { word(&mut self.s, "true") } else { word(&mut self.s, "false") }
 2231              }
 2232              ast::LitBinary(ref arr) => {
 2233                  try!(self.ibox(indent_unit));
 2234                  try!(word(&mut self.s, "["));
 2235                  try!(self.commasep_cmnt(Inconsistent, arr.as_slice(),
 2236                                          |s, u| word(&mut s.s, format!("{}", *u)),
 2237                                          |_| lit.span));
 2238                  try!(word(&mut self.s, "]"));
 2239                  self.end()
 2240              }
 2241          }
 2242      }
 2243  
 2244      pub fn next_lit(&mut self, posBytePos) -> Option<comments::Literal> {
 2245          match self.literals {
 2246              Some(ref lits) => {
 2247                  while self.cur_cmnt_and_lit.cur_lit < lits.len() {
 2248                      let ltrl = (*(*lits).get(self.cur_cmnt_and_lit.cur_lit)).clone();
 2249                      if ltrl.pos > pos { return None; }
 2250                      self.cur_cmnt_and_lit.cur_lit += 1u;
 2251                      if ltrl.pos == pos { return Some(ltrl); }
 2252                  }
 2253                  None
 2254              }
 2255              _ => None
 2256          }
 2257      }
 2258  
 2259      pub fn maybe_print_comment(&mut self, posBytePos) -> IoResult<()> {
 2260          loop {
 2261              match self.next_comment() {
 2262                  Some(ref cmnt) => {
 2263                      if (*cmnt).pos < pos {
 2264                          try!(self.print_comment(cmnt));
 2265                          self.cur_cmnt_and_lit.cur_cmnt += 1u;
 2266                      } else { break; }
 2267                  }
 2268                  _ => break
 2269              }
 2270          }
 2271          Ok(())
 2272      }
 2273  
 2274      pub fn print_comment(&mut self,
 2275                           cmnt&comments::Comment) -> IoResult<()> {
 2276          match cmnt.style {
 2277              comments::Mixed => {
 2278                  assert_eq!(cmnt.lines.len(), 1u);
 2279                  try!(zerobreak(&mut self.s));
 2280                  try!(word(&mut self.s, cmnt.lines.get(0).as_slice()));
 2281                  zerobreak(&mut self.s)
 2282              }
 2283              comments::Isolated => {
 2284                  try!(self.hardbreak_if_not_bol());
 2285                  for line in cmnt.lines.iter() {
 2286                      // Don't print empty lines because they will end up as trailing
 2287                      // whitespace
 2288                      if !line.is_empty() {
 2289                          try!(word(&mut self.s, line.as_slice()));
 2290                      }
 2291                      try!(hardbreak(&mut self.s));
 2292                  }
 2293                  Ok(())
 2294              }
 2295              comments::Trailing => {
 2296                  try!(word(&mut self.s, " "));
 2297                  if cmnt.lines.len() == 1u {
 2298                      try!(word(&mut self.s, cmnt.lines.get(0).as_slice()));
 2299                      hardbreak(&mut self.s)
 2300                  } else {
 2301                      try!(self.ibox(0u));
 2302                      for line in cmnt.lines.iter() {
 2303                          if !line.is_empty() {
 2304                              try!(word(&mut self.s, line.as_slice()));
 2305                          }
 2306                          try!(hardbreak(&mut self.s));
 2307                      }
 2308                      self.end()
 2309                  }
 2310              }
 2311              comments::BlankLine => {
 2312                  // We need to do at least one, possibly two hardbreaks.
 2313                  let is_semi = match self.s.last_token() {
 2314                      pp::String(s, _) => ";" == s.as_slice(),
 2315                      _ => false
 2316                  };
 2317                  if is_semi || self.is_begin() || self.is_end() {
 2318                      try!(hardbreak(&mut self.s));
 2319                  }
 2320                  hardbreak(&mut self.s)
 2321              }
 2322          }
 2323      }
 2324  
 2325      pub fn print_string(&mut self, st&str,
 2326                          styleast::StrStyle) -> IoResult<()> {
 2327          let st = match style {
 2328              ast::CookedStr => format!("\"{}\"", st.escape_default()),
 2329              ast::RawStr(n) => format!("r{delim}\"{string}\"{delim}",
 2330                                        delim="#".repeat(n), string=st)
 2331          };
 2332          word(&mut self.s, st)
 2333      }
 2334  
 2335      pub fn next_comment(&mut self) -> Option<comments::Comment> {
 2336          match self.comments {
 2337              Some(ref cmnts) => {
 2338                  if self.cur_cmnt_and_lit.cur_cmnt < cmnts.len() {
 2339                      Some((*cmnts.get(self.cur_cmnt_and_lit.cur_cmnt)).clone())
 2340                  } else {
 2341                      None
 2342                  }
 2343              }
 2344              _ => None
 2345          }
 2346      }
 2347  
 2348      pub fn print_opt_fn_style(&mut self,
 2349                              opt_fn_styleOption<ast::FnStyle>) -> IoResult<()> {
 2350          match opt_fn_style {
 2351              Some(fn_style) => self.print_fn_style(fn_style),
 2352              None => Ok(())
 2353          }
 2354      }
 2355  
 2356      pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
 2357                                                    opt_abiOption<abi::Abi>)
 2358          -> IoResult<()> {
 2359          match opt_abi {
 2360              Some(abi::Rust) => Ok(()),
 2361              Some(abi) => {
 2362                  try!(self.word_nbsp("extern"));
 2363                  self.word_nbsp(abi.to_str())
 2364              }
 2365              None => Ok(())
 2366          }
 2367      }
 2368  
 2369      pub fn print_extern_opt_abi(&mut self,
 2370                                  opt_abiOption<abi::Abi>) -> IoResult<()> {
 2371          match opt_abi {
 2372              Some(abi) => {
 2373                  try!(self.word_nbsp("extern"));
 2374                  self.word_nbsp(abi.to_str())
 2375              }
 2376              None => Ok(())
 2377          }
 2378      }
 2379  
 2380      pub fn print_fn_header_info(&mut self,
 2381                                  _opt_explicit_selfOption<ast::ExplicitSelf_>,
 2382                                  opt_fn_styleOption<ast::FnStyle>,
 2383                                  abiabi::Abi,
 2384                                  visast::Visibility) -> IoResult<()> {
 2385          try!(word(&mut self.s, visibility_qualified(vis, "").as_slice()));
 2386          try!(self.print_opt_fn_style(opt_fn_style));
 2387  
 2388          if abi != abi::Rust {
 2389              try!(self.word_nbsp("extern"));
 2390              try!(self.word_nbsp(abi.to_str()));
 2391          }
 2392  
 2393          word(&mut self.s, "fn")
 2394      }
 2395  
 2396      pub fn print_fn_style(&mut self, sast::FnStyle) -> IoResult<()> {
 2397          match s {
 2398              ast::NormalFn => Ok(()),
 2399              ast::UnsafeFn => self.word_nbsp("unsafe"),
 2400          }
 2401      }
 2402  
 2403      pub fn print_onceness(&mut self, oast::Onceness) -> IoResult<()> {
 2404          match o {
 2405              ast::Once => self.word_nbsp("once"),
 2406              ast::Many => Ok(())
 2407          }
 2408      }
 2409  }
 2410  
 2411  #[cfg(test)]
 2412  mod test {
 2413      use super::*;
 2414  
 2415      use ast;
 2416      use ast_util;
 2417      use codemap;
 2418      use parse::token;
 2419  
 2420      #[test]
 2421      fn test_fun_to_str() {
 2422          let abba_ident = token::str_to_ident("abba");
 2423  
 2424          let decl = ast::FnDecl {
 2425              inputs: Vec::new(),
 2426              output: ast::P(ast::Ty {id: 0,
 2427                                      node: ast::TyNil,
 2428                                      span: codemap::DUMMY_SP}),
 2429              cf: ast::Return,
 2430              variadic: false
 2431          };
 2432          let generics = ast_util::empty_generics();
 2433          assert_eq!(&fun_to_str(&decl, ast::NormalFn, abba_ident,
 2434                                 None, &generics),
 2435                     &"fn abba()".to_strbuf());
 2436      }
 2437  
 2438      #[test]
 2439      fn test_variant_to_str() {
 2440          let ident = token::str_to_ident("principal_skinner");
 2441  
 2442          let var = codemap::respan(codemap::DUMMY_SP, ast::Variant_ {
 2443              name: ident,
 2444              attrs: Vec::new(),
 2445              // making this up as I go.... ?
 2446              kind: ast::TupleVariantKind(Vec::new()),
 2447              id: 0,
 2448              disr_expr: None,
 2449              vis: ast::Public,
 2450          });
 2451  
 2452          let varstr = variant_to_str(&var);
 2453          assert_eq!(&varstr,&"pub principal_skinner".to_strbuf());
 2454      }
 2455  }


libsyntax/print/pprust.rs:42:1-42:1 -trait- definition:
pub trait PpAnn {
    fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
    fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
references:- 4
73: pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>,
74:                                   ann: &'a PpAnn) -> State<'a> {
75:     State {
--
102:                        out: Box<io::Writer>,
103:                        ann: &'a PpAnn,
104:                        is_expanded: bool) -> IoResult<()> {


libsyntax/print/pprust.rs:153:1-153:1 -fn- definition:
pub fn pat_to_str(pat: &ast::Pat) -> StrBuf {
    to_str(|s| s.print_pat(pat))
}
references:- 2
libsyntax/ast_map.rs:
704:             (format!("local {} (id={})",
705:                     pprust::pat_to_str(pat), id)).to_strbuf()
706:         }


libsyntax/print/pprust.rs:35:1-35:1 -enum- definition:
pub enum AnnNode<'a> {
    NodeBlock(&'a ast::Block),
    NodeItem(&'a ast::Item),
references:- 2
44:     fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
45:     fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
46: }


libsyntax/print/pprust.rs:242:1-242:1 -fn- definition:
pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> StrBuf {
    match vis {
        ast::Public => format!("pub {}", s).to_strbuf(),
references:- 9
2384:                                 vis: ast::Visibility) -> IoResult<()> {
2385:         try!(word(&mut self.s, visibility_qualified(vis, "").as_slice()));
2386:         try!(self.print_opt_fn_style(opt_fn_style));


libsyntax/print/pprust.rs:157:1-157:1 -fn- definition:
pub fn expr_to_str(e: &ast::Expr) -> StrBuf {
    to_str(|s| s.print_expr(e))
}
references:- 3
libsyntax/ast_map.rs:
692:             (format!("expr {} (id={})",
693:                     pprust::expr_to_str(expr), id)).to_strbuf()
694:         }
libsyntax/parse/token.rs:
243:         match nt {
244:             &NtExpr(e) => ::print::pprust::expr_to_str(e),
245:             &NtMeta(e) => ::print::pprust::meta_item_to_str(e),
libsyntax/ext/quote.rs:
118:         fn to_source(&self) -> StrBuf {
119:             pprust::expr_to_str(*self)
120:         }


libsyntax/print/pprust.rs:165:1-165:1 -fn- definition:
pub fn tt_to_str(tt: &ast::TokenTree) -> StrBuf {
    to_str(|s| s.print_tt(tt))
}
references:- 2
libsyntax/ext/log_syntax.rs:
23:     cx.print_backtrace();
24:     println!("{}", print::pprust::tt_to_str(&ast::TTDelim(
25:                 Rc::new(tt.iter().map(|x| (*x).clone()).collect()))));
libsyntax/ext/tt/macro_rules.rs:
127:                  token::get_ident(name),
128:                  print::pprust::tt_to_str(&TTDelim(Rc::new(arg.iter()
129:                                                               .map(|x| (*x).clone())


libsyntax/print/pprust.rs:56:1-56:1 -struct- definition:
pub struct State<'a> {
    pub s: pp::Printer,
    cm: Option<&'a CodeMap>,
references:- 10
109:     );
110:     let mut s = State {
111:         s: pp::mk_printer(out, default_columns),
--
377:     pub fn commasep<T>(&mut self, b: Breaks, elts: &[T],
378:                        op: |&mut State, &T| -> IoResult<()>)
379:         -> IoResult<()> {
--
393:                          elts: &[T],
394:                          op: |&mut State, &T| -> IoResult<()>,
395:                          get_span: |&T| -> codemap::Span) -> IoResult<()> {


libsyntax/print/pprust.rs:51:1-51:1 -struct- definition:
pub struct CurrentCommentAndLiteral {
    cur_cmnt: uint,
    cur_lit: uint,
references:- 3
122:         },
123:         cur_cmnt_and_lit: CurrentCommentAndLiteral {
124:             cur_cmnt: 0,


libsyntax/print/pprust.rs:212:1-212:1 -fn- definition:
pub fn block_to_str(blk: &ast::Block) -> StrBuf {
    to_str(|s| {
        // containing cbox, will be closed by print-block at }
references:- 2
libsyntax/ext/quote.rs:
124:         fn to_source(&self) -> StrBuf {
125:             pprust::block_to_str(self)
126:         }
libsyntax/ast_map.rs:
708:             (format!("block {} (id={})",
709:                     pprust::block_to_str(block), id)).to_strbuf()
710:         }


libsyntax/print/pprust.rs:149:1-149:1 -fn- definition:
pub fn ty_to_str(ty: &ast::Ty) -> StrBuf {
    to_str(|s| s.print_type(ty))
}
references:- 2
libsyntax/ast_util.rs:
258: pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: &Ty) -> Ident {
259:     let mut pretty = pprust::ty_to_str(ty);
260:     match *trait_ref {
libsyntax/ext/quote.rs:
96:         fn to_source(&self) -> StrBuf {
97:             pprust::ty_to_str(self)
98:         }


libsyntax/print/pprust.rs:47:1-47:1 -struct- definition:
pub struct NoAnn;
impl PpAnn for NoAnn {}
pub struct CurrentCommentAndLiteral {
references:- 2
68: pub fn rust_printer(writer: Box<io::Writer>) -> State<'static> {
69:     static NO_ANN: NoAnn = NoAnn;
70:     rust_printer_annotated(writer, &NO_ANN)


libsyntax/print/pprust.rs:230:1-230:1 -fn- definition:
pub fn lit_to_str(l: &ast::Lit) -> StrBuf {
    to_str(|s| s.print_literal(l))
}
references:- 13
libsyntax/ext/quote.rs:
188:             let lit = dummy_spanned(ast::LitInt(*self as i64, ast::TyI64));
189:             pprust::lit_to_str(&lit)
190:         }
--
195:             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU));
196:             pprust::lit_to_str(&lit)
197:         }
--
216:             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU32));
217:             pprust::lit_to_str(&lit)
218:         }
--
223:             let lit = dummy_spanned(ast::LitUint(*self as u64, ast::TyU64));
224:             pprust::lit_to_str(&lit)
225:         }


libsyntax/print/pprust.rs:134:1-134:1 -fn- definition:
pub fn to_str(f: |&mut State| -> IoResult<()>) -> StrBuf {
    let mut s = rust_printer(box MemWriter::new());
    f(&mut s).unwrap();
references:- 20
204:                   generics: &ast::Generics) -> StrBuf {
205:     to_str(|s| {
206:         try!(s.print_fn(decl, Some(fn_style), abi::Rust,
--
223: pub fn meta_item_to_str(mi: &ast::MetaItem) -> StrBuf {
224:     to_str(|s| s.print_meta_item(mi))
225: }
--
227: pub fn attribute_to_str(attr: &ast::Attribute) -> StrBuf {
228:     to_str(|s| s.print_attribute(attr))
229: }
--
231: pub fn lit_to_str(l: &ast::Lit) -> StrBuf {
232:     to_str(|s| s.print_literal(l))
233: }
--
235: pub fn explicit_self_to_str(explicit_self: ast::ExplicitSelf_) -> StrBuf {
236:     to_str(|s| s.print_explicit_self(explicit_self, ast::MutImmutable).map(|_| {}))
237: }
--
239: pub fn variant_to_str(var: &ast::Variant) -> StrBuf {
240:     to_str(|s| s.print_variant(var))
241: }