about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-02-04 14:02:01 -0800
committerPatrick Walton <pcwalton@mimiga.net>2013-02-07 16:17:39 -0800
commit472797b04a3fac95e14368e5f1b149573d3d676c (patch)
treef20d5b197e8eb9d86302fb631a4fe18b2634324a /src/libsyntax
parent2bc9655bc1a5486a2fa4cbcd7543fe094cfc4616 (diff)
downloadrust-472797b04a3fac95e14368e5f1b149573d3d676c.tar.gz
rust-472797b04a3fac95e14368e5f1b149573d3d676c.zip
librustc: Lots of de-muting. rs=demuting
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast_map.rs56
-rw-r--r--src/libsyntax/diagnostic.rs140
-rw-r--r--src/libsyntax/ext/base.rs112
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs151
-rw-r--r--src/libsyntax/parse/comments.rs31
-rw-r--r--src/libsyntax/parse/lexer.rs157
-rw-r--r--src/libsyntax/parse/mod.rs18
-rw-r--r--src/libsyntax/print/pp.rs173
-rw-r--r--src/libsyntax/print/pprust.rs325
9 files changed, 596 insertions, 567 deletions
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index fe41cee919f..8be4b219ded 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -107,15 +107,17 @@ pub enum ast_node {
 }
 
 pub type map = std::oldmap::HashMap<node_id, ast_node>;
-pub struct ctx {
-    map: map,
-    mut path: path,
-    mut local_id: uint,
+
+pub struct Ctx {
+    map: @map,
+    path: path,
+    local_id: uint,
     diag: span_handler,
 }
-pub type vt = visit::vt<ctx>;
 
-pub fn extend(cx: ctx, +elt: ident) -> @path {
+pub type vt = visit::vt<@mut Ctx>;
+
+pub fn extend(cx: @mut Ctx, +elt: ident) -> @path {
     @(vec::append(cx.path, ~[path_name(elt)]))
 }
 
@@ -133,31 +135,33 @@ pub fn mk_ast_map_visitor() -> vt {
 }
 
 pub fn map_crate(diag: span_handler, c: crate) -> map {
-    let cx = ctx {
-        map: std::oldmap::HashMap(),
-        mut path: ~[],
-        mut local_id: 0u,
+    let cx = @mut Ctx {
+        map: @std::oldmap::HashMap(),
+        path: ~[],
+        local_id: 0u,
         diag: diag,
     };
     visit::visit_crate(c, cx, mk_ast_map_visitor());
-    cx.map
+    *cx.map
 }
 
 // Used for items loaded from external crate that are being inlined into this
 // crate.  The `path` should be the path to the item but should not include
 // the item itself.
 pub fn map_decoded_item(diag: span_handler,
-                        map: map, path: path, ii: inlined_item) {
+                        map: map,
+                        path: path,
+                        ii: inlined_item) {
     // I believe it is ok for the local IDs of inlined items from other crates
     // to overlap with the local ids from this crate, so just generate the ids
     // starting from 0.  (In particular, I think these ids are only used in
     // alias analysis, which we will not be running on the inlined items, and
     // even if we did I think it only needs an ordering between local
     // variables that are simultaneously in scope).
-    let cx = ctx {
-        map: map,
-        mut path: path,
-        mut local_id: 0,
+    let cx = @mut Ctx {
+        map: @map,
+        path: path,
+        local_id: 0,
         diag: diag,
     };
     let v = mk_ast_map_visitor();
@@ -181,7 +185,7 @@ pub fn map_decoded_item(diag: span_handler,
 }
 
 pub fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
-              sp: codemap::span, id: node_id, cx: ctx, v: vt) {
+              sp: codemap::span, id: node_id, &&cx: @mut Ctx, v: vt) {
     for decl.inputs.each |a| {
         cx.map.insert(a.id,
                       node_arg(/* FIXME (#2543) */
@@ -208,12 +212,12 @@ pub fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
     visit::visit_fn(fk, decl, body, sp, id, cx, v);
 }
 
-pub fn map_block(b: blk, cx: ctx, v: vt) {
+pub fn map_block(b: blk, &&cx: @mut Ctx, v: vt) {
     cx.map.insert(b.node.id, node_block(/* FIXME (#2543) */ copy b));
     visit::visit_block(b, cx, v);
 }
 
-pub fn number_pat(cx: ctx, pat: @pat) {
+pub fn number_pat(cx: @mut Ctx, pat: @pat) {
     do ast_util::walk_pat(pat) |p| {
         match p.node {
           pat_ident(*) => {
@@ -225,24 +229,24 @@ pub fn number_pat(cx: ctx, pat: @pat) {
     };
 }
 
-pub fn map_local(loc: @local, cx: ctx, v: vt) {
+pub fn map_local(loc: @local, &&cx: @mut Ctx, v: vt) {
     number_pat(cx, loc.node.pat);
     visit::visit_local(loc, cx, v);
 }
 
-pub fn map_arm(arm: arm, cx: ctx, v: vt) {
+pub fn map_arm(arm: arm, &&cx: @mut Ctx, v: vt) {
     number_pat(cx, arm.pats[0]);
     visit::visit_arm(arm, cx, v);
 }
 
 pub fn map_method(impl_did: def_id, impl_path: @path,
-                  m: @method, cx: ctx) {
+                  m: @method, &&cx: @mut Ctx) {
     cx.map.insert(m.id, node_method(m, impl_did, impl_path));
     cx.map.insert(m.self_id, node_local(cx.local_id));
     cx.local_id += 1u;
 }
 
-pub fn map_item(i: @item, cx: ctx, v: vt) {
+pub fn map_item(i: @item, &&cx: @mut Ctx, v: vt) {
     let item_path = @/* FIXME (#2543) */ copy cx.path;
     cx.map.insert(i.id, node_item(i, item_path));
     match i.node {
@@ -305,7 +309,7 @@ pub fn map_item(i: @item, cx: ctx, v: vt) {
 }
 
 pub fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node,
-                      ident: ast::ident, cx: ctx, _v: vt) {
+                      ident: ast::ident, cx: @mut Ctx, _v: vt) {
     let p = extend(cx, ident);
     // If this is a tuple-like struct, register the constructor.
     match struct_def.ctor_id {
@@ -322,12 +326,12 @@ pub fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node,
     }
 }
 
-pub fn map_expr(ex: @expr, cx: ctx, v: vt) {
+pub fn map_expr(ex: @expr, &&cx: @mut Ctx, v: vt) {
     cx.map.insert(ex.id, node_expr(ex));
     visit::visit_expr(ex, cx, v);
 }
 
-pub fn map_stmt(stmt: @stmt, cx: ctx, v: vt) {
+pub fn map_stmt(stmt: @stmt, &&cx: @mut Ctx, v: vt) {
     cx.map.insert(stmt_id(*stmt), node_stmt(stmt));
     visit::visit_stmt(stmt, cx, v);
 }
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index c454f5dde2b..cd42fc7a953 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -23,83 +23,86 @@ use core::dvec::DVec;
 
 use std::term;
 
-pub type emitter = fn@(cmsp: Option<(@codemap::CodeMap, span)>,
+pub type Emitter = fn@(cmsp: Option<(@codemap::CodeMap, span)>,
                    msg: &str, lvl: level);
 
 
 pub trait span_handler {
-    fn span_fatal(sp: span, msg: &str) -> !;
-    fn span_err(sp: span, msg: &str);
-    fn span_warn(sp: span, msg: &str);
-    fn span_note(sp: span, msg: &str);
-    fn span_bug(sp: span, msg: &str) -> !;
-    fn span_unimpl(sp: span, msg: &str) -> !;
-    fn handler() -> handler;
+    fn span_fatal(@mut self, sp: span, msg: &str) -> !;
+    fn span_err(@mut self, sp: span, msg: &str);
+    fn span_warn(@mut self, sp: span, msg: &str);
+    fn span_note(@mut self, sp: span, msg: &str);
+    fn span_bug(@mut self, sp: span, msg: &str) -> !;
+    fn span_unimpl(@mut self, sp: span, msg: &str) -> !;
+    fn handler(@mut self) -> handler;
 }
 
 pub trait handler {
-    fn fatal(msg: &str) -> !;
-    fn err(msg: &str);
-    fn bump_err_count();
-    fn has_errors() -> bool;
-    fn abort_if_errors();
-    fn warn(msg: &str);
-    fn note(msg: &str);
-    fn bug(msg: &str) -> !;
-    fn unimpl(msg: &str) -> !;
-    fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level);
+    fn fatal(@mut self, msg: &str) -> !;
+    fn err(@mut self, msg: &str);
+    fn bump_err_count(@mut self);
+    fn has_errors(@mut self) -> bool;
+    fn abort_if_errors(@mut self);
+    fn warn(@mut self, msg: &str);
+    fn note(@mut self, msg: &str);
+    fn bug(@mut self, msg: &str) -> !;
+    fn unimpl(@mut self, msg: &str) -> !;
+    fn emit(@mut self,
+            cmsp: Option<(@codemap::CodeMap, span)>,
+            msg: &str,
+            lvl: level);
 }
 
-struct handler_t {
-    mut err_count: uint,
-    emit: emitter,
+struct HandlerT {
+    err_count: uint,
+    emit: Emitter,
 }
 
-struct codemap_t {
+struct CodemapT {
     handler: handler,
     cm: @codemap::CodeMap,
 }
 
-impl codemap_t: span_handler {
-    fn span_fatal(sp: span, msg: &str) -> ! {
+impl CodemapT: span_handler {
+    fn span_fatal(@mut self, sp: span, msg: &str) -> ! {
         self.handler.emit(Some((self.cm, sp)), msg, fatal);
         die!();
     }
-    fn span_err(sp: span, msg: &str) {
+    fn span_err(@mut self, sp: span, msg: &str) {
         self.handler.emit(Some((self.cm, sp)), msg, error);
         self.handler.bump_err_count();
     }
-    fn span_warn(sp: span, msg: &str) {
+    fn span_warn(@mut self, sp: span, msg: &str) {
         self.handler.emit(Some((self.cm, sp)), msg, warning);
     }
-    fn span_note(sp: span, msg: &str) {
+    fn span_note(@mut self, sp: span, msg: &str) {
         self.handler.emit(Some((self.cm, sp)), msg, note);
     }
-    fn span_bug(sp: span, msg: &str) -> ! {
+    fn span_bug(@mut self, sp: span, msg: &str) -> ! {
         self.span_fatal(sp, ice_msg(msg));
     }
-    fn span_unimpl(sp: span, msg: &str) -> ! {
+    fn span_unimpl(@mut self, sp: span, msg: &str) -> ! {
         self.span_bug(sp, ~"unimplemented " + msg);
     }
-    fn handler() -> handler {
+    fn handler(@mut self) -> handler {
         self.handler
     }
 }
 
-impl handler_t: handler {
-    fn fatal(msg: &str) -> ! {
+impl HandlerT: handler {
+    fn fatal(@mut self, msg: &str) -> ! {
         (self.emit)(None, msg, fatal);
         die!();
     }
-    fn err(msg: &str) {
+    fn err(@mut self, msg: &str) {
         (self.emit)(None, msg, error);
         self.bump_err_count();
     }
-    fn bump_err_count() {
+    fn bump_err_count(@mut self) {
         self.err_count += 1u;
     }
-    fn has_errors() -> bool { self.err_count > 0u }
-    fn abort_if_errors() {
+    fn has_errors(@mut self) -> bool { self.err_count > 0u }
+    fn abort_if_errors(@mut self) {
         let s;
         match self.err_count {
           0u => return,
@@ -111,17 +114,22 @@ impl handler_t: handler {
         }
         self.fatal(s);
     }
-    fn warn(msg: &str) {
+    fn warn(@mut self, msg: &str) {
         (self.emit)(None, msg, warning);
     }
-    fn note(msg: &str) {
+    fn note(@mut self, msg: &str) {
         (self.emit)(None, msg, note);
     }
-    fn bug(msg: &str) -> ! {
+    fn bug(@mut self, msg: &str) -> ! {
         self.fatal(ice_msg(msg));
     }
-    fn unimpl(msg: &str) -> ! { self.bug(~"unimplemented " + msg); }
-    fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) {
+    fn unimpl(@mut self, msg: &str) -> ! {
+        self.bug(~"unimplemented " + msg);
+    }
+    fn emit(@mut self,
+            cmsp: Option<(@codemap::CodeMap, span)>,
+            msg: &str,
+            lvl: level) {
         (self.emit)(cmsp, msg, lvl);
     }
 }
@@ -132,25 +140,22 @@ pub fn ice_msg(msg: &str) -> ~str {
 
 pub fn mk_span_handler(handler: handler, cm: @codemap::CodeMap)
                     -> span_handler {
-    @codemap_t { handler: handler, cm: cm } as span_handler
+    @mut CodemapT { handler: handler, cm: cm } as @span_handler
 }
 
-pub fn mk_handler(emitter: Option<emitter>) -> handler {
-
-    let emit = match emitter {
-      Some(e) => e,
-      None => {
-        let f = fn@(cmsp: Option<(@codemap::CodeMap, span)>,
-                    msg: &str, t: level) {
-            emit(cmsp, msg, t);
-        };
-        f
-      }
+pub fn mk_handler(emitter: Option<Emitter>) -> @handler {
+    let emit: Emitter = match emitter {
+        Some(e) => e,
+        None => {
+            let emit: Emitter = |cmsp, msg, t| emit(cmsp, msg, t);
+            emit
+        }
     };
 
-    @handler_t { mut err_count: 0, emit: emit } as handler
+    @mut HandlerT { mut err_count: 0, emit: emit } as @handler
 }
 
+#[deriving_eq]
 pub enum level {
     fatal,
     error,
@@ -158,28 +163,21 @@ pub enum level {
     note,
 }
 
-impl level : cmp::Eq {
-    pure fn eq(&self, other: &level) -> bool {
-        ((*self) as uint) == ((*other) as uint)
-    }
-    pure fn ne(&self, other: &level) -> bool { !(*self).eq(other) }
-}
-
 fn diagnosticstr(lvl: level) -> ~str {
     match lvl {
-      fatal => ~"error",
-      error => ~"error",
-      warning => ~"warning",
-      note => ~"note"
+        fatal => ~"error",
+        error => ~"error",
+        warning => ~"warning",
+        note => ~"note"
     }
 }
 
 fn diagnosticcolor(lvl: level) -> u8 {
     match lvl {
-      fatal => term::color_bright_red,
-      error => term::color_bright_red,
-      warning => term::color_bright_yellow,
-      note => term::color_bright_green
+        fatal => term::color_bright_red,
+        error => term::color_bright_red,
+        warning => term::color_bright_yellow,
+        note => term::color_bright_green
     }
 }
 
@@ -223,9 +221,9 @@ pub fn emit(cmsp: Option<(@codemap::CodeMap, span)>, msg: &str, lvl: level) {
     }
 }
 
-fn highlight_lines(cm: @codemap::CodeMap, sp: span,
+fn highlight_lines(cm: @codemap::CodeMap,
+                   sp: span,
                    lines: @codemap::FileLines) {
-
     let fm = lines.file;
 
     // arbitrarily only print up to six lines of the error
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 3efae955965..8c3db21f4ea 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -161,54 +161,56 @@ pub fn syntax_expander_table() -> HashMap<~str, SyntaxExtension> {
 // when a macro expansion occurs, the resulting nodes have the backtrace()
 // -> expn_info of their expansion context stored into their span.
 pub trait ext_ctxt {
-    fn codemap() -> @CodeMap;
-    fn parse_sess() -> parse::parse_sess;
-    fn cfg() -> ast::crate_cfg;
-    fn call_site() -> span;
-    fn print_backtrace();
-    fn backtrace() -> Option<@ExpnInfo>;
-    fn mod_push(mod_name: ast::ident);
-    fn mod_pop();
-    fn mod_path() -> ~[ast::ident];
-    fn bt_push(ei: codemap::ExpnInfo);
-    fn bt_pop();
-    fn span_fatal(sp: span, msg: &str) -> !;
-    fn span_err(sp: span, msg: &str);
-    fn span_warn(sp: span, msg: &str);
-    fn span_unimpl(sp: span, msg: &str) -> !;
-    fn span_bug(sp: span, msg: &str) -> !;
-    fn bug(msg: &str) -> !;
-    fn next_id() -> ast::node_id;
-    pure fn trace_macros() -> bool;
-    fn set_trace_macros(x: bool);
+    fn codemap(@mut self) -> @CodeMap;
+    fn parse_sess(@mut self) -> parse::parse_sess;
+    fn cfg(@mut self) -> ast::crate_cfg;
+    fn call_site(@mut self) -> span;
+    fn print_backtrace(@mut self);
+    fn backtrace(@mut self) -> Option<@ExpnInfo>;
+    fn mod_push(@mut self, mod_name: ast::ident);
+    fn mod_pop(@mut self);
+    fn mod_path(@mut self) -> ~[ast::ident];
+    fn bt_push(@mut self, ei: codemap::ExpnInfo);
+    fn bt_pop(@mut self);
+    fn span_fatal(@mut self, sp: span, msg: &str) -> !;
+    fn span_err(@mut self, sp: span, msg: &str);
+    fn span_warn(@mut self, sp: span, msg: &str);
+    fn span_unimpl(@mut self, sp: span, msg: &str) -> !;
+    fn span_bug(@mut self, sp: span, msg: &str) -> !;
+    fn bug(@mut self, msg: &str) -> !;
+    fn next_id(@mut self) -> ast::node_id;
+    pure fn trace_macros(@mut self) -> bool;
+    fn set_trace_macros(@mut self, x: bool);
     /* for unhygienic identifier transformation */
-    fn str_of(id: ast::ident) -> ~str;
-    fn ident_of(st: ~str) -> ast::ident;
+    fn str_of(@mut self, id: ast::ident) -> ~str;
+    fn ident_of(@mut self, st: ~str) -> ast::ident;
 }
 
 pub fn mk_ctxt(parse_sess: parse::parse_sess,
                cfg: ast::crate_cfg) -> ext_ctxt {
-    type ctxt_repr = {parse_sess: parse::parse_sess,
-                      cfg: ast::crate_cfg,
-                      mut backtrace: Option<@ExpnInfo>,
-                      mut mod_path: ~[ast::ident],
-                      mut trace_mac: bool};
-    impl ctxt_repr: ext_ctxt {
-        fn codemap() -> @CodeMap { self.parse_sess.cm }
-        fn parse_sess() -> parse::parse_sess { self.parse_sess }
-        fn cfg() -> ast::crate_cfg { self.cfg }
-        fn call_site() -> span {
+    struct CtxtRepr {
+        parse_sess: parse::parse_sess,
+        cfg: ast::crate_cfg,
+        backtrace: Option<@ExpnInfo>,
+        mod_path: ~[ast::ident],
+        trace_mac: bool
+    }
+    impl CtxtRepr: ext_ctxt {
+        fn codemap(@mut self) -> @CodeMap { self.parse_sess.cm }
+        fn parse_sess(@mut self) -> parse::parse_sess { self.parse_sess }
+        fn cfg(@mut self) -> ast::crate_cfg { self.cfg }
+        fn call_site(@mut self) -> span {
             match self.backtrace {
                 Some(@ExpandedFrom({call_site: cs, _})) => cs,
                 None => self.bug(~"missing top span")
             }
         }
-        fn print_backtrace() { }
-        fn backtrace() -> Option<@ExpnInfo> { self.backtrace }
-        fn mod_push(i: ast::ident) { self.mod_path.push(i); }
-        fn mod_pop() { self.mod_path.pop(); }
-        fn mod_path() -> ~[ast::ident] { return self.mod_path; }
-        fn bt_push(ei: codemap::ExpnInfo) {
+        fn print_backtrace(@mut self) { }
+        fn backtrace(@mut self) -> Option<@ExpnInfo> { self.backtrace }
+        fn mod_push(@mut self, i: ast::ident) { self.mod_path.push(i); }
+        fn mod_pop(@mut self) { self.mod_path.pop(); }
+        fn mod_path(@mut self) -> ~[ast::ident] { return self.mod_path; }
+        fn bt_push(@mut self, ei: codemap::ExpnInfo) {
             match ei {
               ExpandedFrom({call_site: cs, callie: ref callie}) => {
                 self.backtrace =
@@ -219,7 +221,7 @@ pub fn mk_ctxt(parse_sess: parse::parse_sess,
               }
             }
         }
-        fn bt_pop() {
+        fn bt_pop(@mut self) {
             match self.backtrace {
               Some(@ExpandedFrom({
                   call_site: span {expn_info: prev, _}, _
@@ -229,55 +231,55 @@ pub fn mk_ctxt(parse_sess: parse::parse_sess,
               _ => self.bug(~"tried to pop without a push")
             }
         }
-        fn span_fatal(sp: span, msg: &str) -> ! {
+        fn span_fatal(@mut self, sp: span, msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_fatal(sp, msg);
         }
-        fn span_err(sp: span, msg: &str) {
+        fn span_err(@mut self, sp: span, msg: &str) {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_err(sp, msg);
         }
-        fn span_warn(sp: span, msg: &str) {
+        fn span_warn(@mut self, sp: span, msg: &str) {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_warn(sp, msg);
         }
-        fn span_unimpl(sp: span, msg: &str) -> ! {
+        fn span_unimpl(@mut self, sp: span, msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
         }
-        fn span_bug(sp: span, msg: &str) -> ! {
+        fn span_bug(@mut self, sp: span, msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.span_bug(sp, msg);
         }
-        fn bug(msg: &str) -> ! {
+        fn bug(@mut self, msg: &str) -> ! {
             self.print_backtrace();
             self.parse_sess.span_diagnostic.handler().bug(msg);
         }
-        fn next_id() -> ast::node_id {
+        fn next_id(@mut self) -> ast::node_id {
             return parse::next_node_id(self.parse_sess);
         }
-        pure fn trace_macros() -> bool {
+        pure fn trace_macros(@mut self) -> bool {
             self.trace_mac
         }
-        fn set_trace_macros(x: bool) {
+        fn set_trace_macros(@mut self, x: bool) {
             self.trace_mac = x
         }
 
-        fn str_of(id: ast::ident) -> ~str {
+        fn str_of(@mut self, id: ast::ident) -> ~str {
             *self.parse_sess.interner.get(id)
         }
-        fn ident_of(st: ~str) -> ast::ident {
+        fn ident_of(@mut self, st: ~str) -> ast::ident {
             self.parse_sess.interner.intern(@st)
         }
     }
-    let imp: ctxt_repr = {
+    let imp: @mut CtxtRepr = @mut CtxtRepr {
         parse_sess: parse_sess,
         cfg: cfg,
-        mut backtrace: None,
-        mut mod_path: ~[],
-        mut trace_mac: false
+        backtrace: None,
+        mod_path: ~[],
+        trace_mac: false
     };
-    move ((move imp) as ext_ctxt)
+    move ((move imp) as @ext_ctxt)
 }
 
 pub fn expr_to_str(cx: ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index ba42c3744e5..aa9036d295e 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -24,80 +24,90 @@ use core::vec;
 use std;
 use std::oldmap::HashMap;
 
-enum tt_frame_up { /* to break a circularity */
-    tt_frame_up(Option<tt_frame>)
-}
-
 /* FIXME #2811: figure out how to have a uniquely linked stack, and change to
    `~` */
 ///an unzipping of `token_tree`s
-type tt_frame = @{
+struct TtFrame {
     readme: ~[ast::token_tree],
-    mut idx: uint,
+    idx: uint,
     dotdotdoted: bool,
     sep: Option<Token>,
-    up: tt_frame_up,
-};
+    up: Option<@mut TtFrame>,
+}
 
-pub type tt_reader = @tt_reader_;
-pub type tt_reader_ = {
+pub struct TtReader {
     sp_diag: span_handler,
     interner: @ident_interner,
-    mut cur: tt_frame,
+    cur: @mut TtFrame,
     /* for MBE-style macro transcription */
     interpolations: std::oldmap::HashMap<ident, @named_match>,
-    mut repeat_idx: ~[uint],
-    mut repeat_len: ~[uint],
+    repeat_idx: ~[uint],
+    repeat_len: ~[uint],
     /* cached: */
-    mut cur_tok: Token,
-    mut cur_span: span
-};
+    cur_tok: Token,
+    cur_span: span
+}
 
 /** This can do Macro-By-Example transcription. On the other hand, if
  *  `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
  *  should) be none. */
-pub fn new_tt_reader(sp_diag: span_handler, itr: @ident_interner,
+pub fn new_tt_reader(sp_diag: span_handler,
+                     itr: @ident_interner,
                      interp: Option<std::oldmap::HashMap<ident,@named_match>>,
                      src: ~[ast::token_tree])
-                  -> tt_reader {
-    let r = @{sp_diag: sp_diag, interner: itr,
-              mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false,
-                         sep: None, up: tt_frame_up(option::None)},
-              interpolations: match interp { /* just a convienience */
-                None => std::oldmap::HashMap(),
-                Some(x) => x
-              },
-              mut repeat_idx: ~[],
-              mut repeat_len: ~[],
-              /* dummy values, never read: */
-              mut cur_tok: EOF,
-              mut cur_span: dummy_sp()
-             };
+                  -> @mut TtReader {
+    let r = @mut TtReader {
+        sp_diag: sp_diag,
+        interner: itr,
+        mut cur: @mut TtFrame {
+            readme: src,
+            idx: 0u,
+            dotdotdoted: false,
+            sep: None,
+            up: option::None
+        },
+        interpolations: match interp { /* just a convienience */
+            None => std::oldmap::HashMap(),
+            Some(x) => x
+        },
+        repeat_idx: ~[],
+        repeat_len: ~[],
+        /* dummy values, never read: */
+        cur_tok: EOF,
+        cur_span: dummy_sp()
+    };
     tt_next_token(r); /* get cur_tok and cur_span set up */
     return r;
 }
 
-pure fn dup_tt_frame(&&f: tt_frame) -> tt_frame {
-    @{readme: f.readme, mut idx: f.idx, dotdotdoted: f.dotdotdoted,
-      sep: f.sep, up: match f.up {
-        tt_frame_up(Some(up_frame)) => {
-          tt_frame_up(Some(dup_tt_frame(up_frame)))
+pure fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame {
+    @mut TtFrame {
+        readme: f.readme,
+        idx: f.idx,
+        dotdotdoted: f.dotdotdoted,
+        sep: f.sep,
+        up: match f.up {
+            Some(up_frame) => Some(dup_tt_frame(up_frame)),
+            None => None
         }
-        tt_frame_up(none) => tt_frame_up(none)
-      }
-     }
+    }
 }
 
-pub pure fn dup_tt_reader(r: &tt_reader_) -> tt_reader {
-    @{sp_diag: r.sp_diag, interner: r.interner,
-      mut cur: dup_tt_frame(r.cur),
-      interpolations: r.interpolations,
-      mut repeat_idx: copy r.repeat_idx, mut repeat_len: copy r.repeat_len,
-      mut cur_tok: r.cur_tok, mut cur_span: r.cur_span}
+pub pure fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader {
+    @mut TtReader {
+        sp_diag: r.sp_diag,
+        interner: r.interner,
+        cur: dup_tt_frame(r.cur),
+        interpolations: r.interpolations,
+        repeat_idx: copy r.repeat_idx,
+        repeat_len: copy r.repeat_len,
+        cur_tok: r.cur_tok,
+        cur_span: r.cur_span
+    }
 }
 
 
-pure fn lookup_cur_matched_by_matched(r: &tt_reader_,
+pure fn lookup_cur_matched_by_matched(r: @mut TtReader,
                                       start: @named_match) -> @named_match {
     pure fn red(+ad: @named_match, idx: &uint) -> @named_match {
         match *ad {
@@ -111,15 +121,15 @@ pure fn lookup_cur_matched_by_matched(r: &tt_reader_,
     vec::foldl(start, r.repeat_idx, red)
 }
 
-fn lookup_cur_matched(r: &tt_reader_, name: ident) -> @named_match {
+fn lookup_cur_matched(r: @mut TtReader, name: ident) -> @named_match {
     lookup_cur_matched_by_matched(r, r.interpolations.get(&name))
 }
 enum lis {
     lis_unconstrained, lis_constraint(uint, ident), lis_contradiction(~str)
 }
 
-fn lockstep_iter_size(t: token_tree, r: &tt_reader_) -> lis {
-    fn lis_merge(lhs: lis, rhs: lis, r: &tt_reader_) -> lis {
+fn lockstep_iter_size(t: token_tree, r: @mut TtReader) -> lis {
+    fn lis_merge(lhs: lis, rhs: lis, r: @mut TtReader) -> lis {
         match lhs {
           lis_unconstrained => rhs,
           lis_contradiction(_) => lhs,
@@ -151,7 +161,7 @@ fn lockstep_iter_size(t: token_tree, r: &tt_reader_) -> lis {
 }
 
 
-pub fn tt_next_token(r: &tt_reader_) -> TokenAndSpan {
+pub fn tt_next_token(r: @mut TtReader) -> TokenAndSpan {
     let ret_val = TokenAndSpan { tok: r.cur_tok, sp: r.cur_span };
     while r.cur.idx >= r.cur.readme.len() {
         /* done with this set; pop or repeat? */
@@ -159,11 +169,11 @@ pub fn tt_next_token(r: &tt_reader_) -> TokenAndSpan {
             || r.repeat_idx.last() == r.repeat_len.last() - 1 {
 
             match r.cur.up {
-              tt_frame_up(None) => {
+              None => {
                 r.cur_tok = EOF;
                 return ret_val;
               }
-              tt_frame_up(Some(tt_f)) => {
+              Some(tt_f) => {
                 if r.cur.dotdotdoted {
                     r.repeat_idx.pop();
                     r.repeat_len.pop();
@@ -178,8 +188,8 @@ pub fn tt_next_token(r: &tt_reader_) -> TokenAndSpan {
             r.cur.idx = 0u;
             r.repeat_idx[r.repeat_idx.len() - 1u] += 1u;
             match r.cur.sep {
-              Some(ref tk) => {
-                r.cur_tok = (*tk); /* repeat same span, I guess */
+              Some(tk) => {
+                r.cur_tok = tk; /* repeat same span, I guess */
                 return ret_val;
               }
               None => ()
@@ -189,20 +199,25 @@ pub fn tt_next_token(r: &tt_reader_) -> TokenAndSpan {
     loop { /* because it's easiest, this handles `tt_delim` not starting
     with a `tt_tok`, even though it won't happen */
         match r.cur.readme[r.cur.idx] {
-          tt_delim(ref tts) => {
-            r.cur = @{readme: (*tts), mut idx: 0u, dotdotdoted: false,
-                      sep: None, up: tt_frame_up(option::Some(r.cur)) };
+          tt_delim(copy tts) => {
+            r.cur = @mut TtFrame {
+                readme: tts,
+                idx: 0u,
+                dotdotdoted: false,
+                sep: None,
+                up: option::Some(r.cur)
+            };
             // if this could be 0-length, we'd need to potentially recur here
           }
-          tt_tok(sp, ref tok) => {
-            r.cur_span = sp; r.cur_tok = (*tok);
+          tt_tok(sp, copy tok) => {
+            r.cur_span = sp; r.cur_tok = tok;
             r.cur.idx += 1u;
             return ret_val;
           }
-          tt_seq(sp, ref tts, ref sep, zerok) => {
-              match lockstep_iter_size(tt_seq(sp, (*tts), (*sep), zerok), r) {
-                lis_unconstrained => {
-                  r.sp_diag.span_fatal(
+          tt_seq(sp, copy tts, copy sep, zerok) => {
+            match lockstep_iter_size(tt_seq(sp, tts, sep, zerok), r) {
+              lis_unconstrained => {
+                r.sp_diag.span_fatal(
                     sp, /* blame macro writer */
                       ~"attempted to repeat an expression \
                         containing no syntax \
@@ -226,12 +241,12 @@ pub fn tt_next_token(r: &tt_reader_) -> TokenAndSpan {
                 } else {
                     r.repeat_len.push(len);
                     r.repeat_idx.push(0u);
-                    r.cur = @{
-                        readme: (*tts),
-                        mut idx: 0u,
+                    r.cur = @mut TtFrame {
+                        readme: tts,
+                        idx: 0u,
                         dotdotdoted: true,
-                        sep: (*sep),
-                        up: tt_frame_up(option::Some(r.cur))
+                        sep: sep,
+                        up: option::Some(r.cur)
                     };
                 }
               }
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index d7640ce3a23..a8db06fe085 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -14,7 +14,7 @@ use ast;
 use codemap::{BytePos, CharPos, CodeMap, FileMap, Pos};
 use diagnostic;
 use parse::lexer::{is_whitespace, get_str_from, reader};
-use parse::lexer::{string_reader, bump, is_eof, nextch, TokenAndSpan};
+use parse::lexer::{StringReader, bump, is_eof, nextch, TokenAndSpan};
 use parse::lexer;
 use parse::token;
 use parse;
@@ -120,7 +120,7 @@ pub fn strip_doc_comment_decoration(comment: ~str) -> ~str {
     die!(~"not a doc-comment: " + comment);
 }
 
-fn read_to_eol(rdr: string_reader) -> ~str {
+fn read_to_eol(rdr: @mut StringReader) -> ~str {
     let mut val = ~"";
     while rdr.curr != '\n' && !is_eof(rdr) {
         str::push_char(&mut val, rdr.curr);
@@ -130,26 +130,26 @@ fn read_to_eol(rdr: string_reader) -> ~str {
     return val;
 }
 
-fn read_one_line_comment(rdr: string_reader) -> ~str {
+fn read_one_line_comment(rdr: @mut StringReader) -> ~str {
     let val = read_to_eol(rdr);
     assert ((val[0] == '/' as u8 && val[1] == '/' as u8) ||
             (val[0] == '#' as u8 && val[1] == '!' as u8));
     return val;
 }
 
-fn consume_non_eol_whitespace(rdr: string_reader) {
+fn consume_non_eol_whitespace(rdr: @mut StringReader) {
     while is_whitespace(rdr.curr) && rdr.curr != '\n' && !is_eof(rdr) {
         bump(rdr);
     }
 }
 
-fn push_blank_line_comment(rdr: string_reader, comments: &mut ~[cmnt]) {
+fn push_blank_line_comment(rdr: @mut StringReader, comments: &mut ~[cmnt]) {
     debug!(">>> blank-line comment");
     let v: ~[~str] = ~[];
     comments.push({style: blank_line, lines: v, pos: rdr.last_pos});
 }
 
-fn consume_whitespace_counting_blank_lines(rdr: string_reader,
+fn consume_whitespace_counting_blank_lines(rdr: @mut StringReader,
                                            comments: &mut ~[cmnt]) {
     while is_whitespace(rdr.curr) && !is_eof(rdr) {
         if rdr.col == CharPos(0u) && rdr.curr == '\n' {
@@ -160,7 +160,7 @@ fn consume_whitespace_counting_blank_lines(rdr: string_reader,
 }
 
 
-fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
+fn read_shebang_comment(rdr: @mut StringReader, code_to_the_left: bool,
                                             comments: &mut ~[cmnt]) {
     debug!(">>> shebang comment");
     let p = rdr.last_pos;
@@ -172,7 +172,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
     });
 }
 
-fn read_line_comments(rdr: string_reader, code_to_the_left: bool,
+fn read_line_comments(rdr: @mut StringReader, code_to_the_left: bool,
                                           comments: &mut ~[cmnt]) {
     debug!(">>> line comments");
     let p = rdr.last_pos;
@@ -221,8 +221,9 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
     lines.push(s1);
 }
 
-fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
-                                          comments: &mut ~[cmnt]) {
+fn read_block_comment(rdr: @mut StringReader,
+                      code_to_the_left: bool,
+                      comments: &mut ~[cmnt]) {
     debug!(">>> block comment");
     let p = rdr.last_pos;
     let mut lines: ~[~str] = ~[];
@@ -280,13 +281,14 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
     comments.push({style: style, lines: lines, pos: p});
 }
 
-fn peeking_at_comment(rdr: string_reader) -> bool {
+fn peeking_at_comment(rdr: @mut StringReader) -> bool {
     return ((rdr.curr == '/' && nextch(rdr) == '/') ||
          (rdr.curr == '/' && nextch(rdr) == '*')) ||
          (rdr.curr == '#' && nextch(rdr) == '!');
 }
 
-fn consume_comment(rdr: string_reader, code_to_the_left: bool,
+fn consume_comment(rdr: @mut StringReader,
+                   code_to_the_left: bool,
                    comments: &mut ~[cmnt]) {
     debug!(">>> consume comment");
     if rdr.curr == '/' && nextch(rdr) == '/' {
@@ -309,8 +311,9 @@ pub fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
     let itr = parse::token::mk_fake_ident_interner();
     let cm = CodeMap::new();
     let filemap = cm.new_filemap(path, src);
-    let rdr = lexer::new_low_level_string_reader(
-        span_diagnostic, filemap, itr);
+    let rdr = lexer::new_low_level_string_reader(span_diagnostic,
+                                                 filemap,
+                                                 itr);
 
     let mut comments: ~[cmnt] = ~[];
     let mut literals: ~[lit] = ~[];
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 07c2a9f5e7e..9ac0093eda6 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -24,45 +24,45 @@ use core::either;
 use core::str;
 use core::u64;
 
-pub use ext::tt::transcribe::{tt_reader, tt_reader_, new_tt_reader};
+pub use ext::tt::transcribe::{TtReader, new_tt_reader};
 
 //use std;
 
 pub trait reader {
-    fn is_eof(&self) -> bool;
-    fn next_token(&self) -> TokenAndSpan;
-    fn fatal(&self,~str) -> !;
-    fn span_diag(&self) -> span_handler;
-    pure fn interner(&self) -> @token::ident_interner;
-    fn peek(&self) -> TokenAndSpan;
-    fn dup(&self) -> reader;
+    fn is_eof(@mut self) -> bool;
+    fn next_token(@mut self) -> TokenAndSpan;
+    fn fatal(@mut self, ~str) -> !;
+    fn span_diag(@mut self) -> span_handler;
+    pure fn interner(@mut self) -> @token::ident_interner;
+    fn peek(@mut self) -> TokenAndSpan;
+    fn dup(@mut self) -> reader;
 }
 
 #[deriving_eq]
 pub struct TokenAndSpan {tok: token::Token, sp: span}
 
-pub type string_reader = @string_reader_;
-pub type string_reader_ = {
+pub struct StringReader {
     span_diagnostic: span_handler,
     src: @~str,
     // The absolute offset within the codemap of the next character to read
-    mut pos: BytePos,
+    pos: BytePos,
     // The absolute offset within the codemap of the last character read(curr)
-    mut last_pos: BytePos,
+    last_pos: BytePos,
     // The column of the next character to read
-    mut col: CharPos,
+    col: CharPos,
     // The last character to be read
-    mut curr: char,
+    curr: char,
     filemap: @codemap::FileMap,
     interner: @token::ident_interner,
     /* cached: */
-    mut peek_tok: token::Token,
-    mut peek_span: span
-};
+    peek_tok: token::Token,
+    peek_span: span
+}
 
 pub fn new_string_reader(span_diagnostic: span_handler,
                          filemap: @codemap::FileMap,
-                         itr: @token::ident_interner) -> string_reader {
+                         itr: @token::ident_interner)
+                      -> @mut StringReader {
     let r = new_low_level_string_reader(span_diagnostic, filemap, itr);
     string_advance_token(r); /* fill in peek_* */
     return r;
@@ -72,18 +72,20 @@ pub fn new_string_reader(span_diagnostic: span_handler,
 pub fn new_low_level_string_reader(span_diagnostic: span_handler,
                                    filemap: @codemap::FileMap,
                                    itr: @token::ident_interner)
-    -> string_reader {
+                                -> @mut StringReader {
     // Force the initial reader bump to start on a fresh line
     let initial_char = '\n';
-    let r = @{span_diagnostic: span_diagnostic, src: filemap.src,
-              mut pos: filemap.start_pos,
-              mut last_pos: filemap.start_pos,
-              mut col: CharPos(0),
-              mut curr: initial_char,
-              filemap: filemap, interner: itr,
-              /* dummy values; not read */
-              mut peek_tok: token::EOF,
-              mut peek_span: codemap::dummy_sp()};
+    let r = @mut StringReader {
+        span_diagnostic: span_diagnostic, src: filemap.src,
+        pos: filemap.start_pos,
+        last_pos: filemap.start_pos,
+        col: CharPos(0),
+        curr: initial_char,
+        filemap: filemap, interner: itr,
+        /* dummy values; not read */
+        peek_tok: token::EOF,
+        peek_span: codemap::dummy_sp()
+    };
     bump(r);
     return r;
 }
@@ -91,58 +93,56 @@ pub fn new_low_level_string_reader(span_diagnostic: span_handler,
 // duplicating the string reader is probably a bad idea, in
 // that using them will cause interleaved pushes of line
 // offsets to the underlying filemap...
-fn dup_string_reader(r: &string_reader_) -> string_reader {
-    @{span_diagnostic: r.span_diagnostic, src: r.src,
-      mut pos: r.pos,
-      mut last_pos: r.last_pos,
-      mut col: r.col, mut curr: r.curr,
-      filemap: r.filemap, interner: r.interner,
-      mut peek_tok: r.peek_tok, mut peek_span: r.peek_span}
+fn dup_string_reader(r: @mut StringReader) -> @mut StringReader {
+    @mut StringReader {
+        span_diagnostic: r.span_diagnostic,
+        src: r.src,
+        pos: r.pos,
+        last_pos: r.last_pos,
+        col: r.col,
+        curr: r.curr,
+        filemap: r.filemap,
+        interner: r.interner,
+        peek_tok: r.peek_tok,
+        peek_span: r.peek_span
+    }
 }
 
-impl string_reader_: reader {
-    fn is_eof(&self) -> bool { is_eof(self) }
+impl StringReader: reader {
+    fn is_eof(@mut self) -> bool { is_eof(self) }
     // return the next token. EFFECT: advances the string_reader.
-    fn next_token(&self) -> TokenAndSpan {
+    fn next_token(@mut self) -> TokenAndSpan {
         let ret_val = TokenAndSpan {tok: self.peek_tok, sp: self.peek_span};
         string_advance_token(self);
         return ret_val;
     }
-    fn fatal(&self, m: ~str) -> ! {
+    fn fatal(@mut self, m: ~str) -> ! {
         self.span_diagnostic.span_fatal(copy self.peek_span, m)
     }
-    fn span_diag(&self) -> span_handler { self.span_diagnostic }
-    pure fn interner(&self) -> @token::ident_interner { self.interner }
-    fn peek(&self) -> TokenAndSpan {
+    fn span_diag(@mut self) -> span_handler { self.span_diagnostic }
+    pure fn interner(@mut self) -> @token::ident_interner { self.interner }
+    fn peek(@mut self) -> TokenAndSpan {
         TokenAndSpan {tok: self.peek_tok, sp: self.peek_span}
     }
-    fn dup(&self) -> reader { dup_string_reader(self) as reader }
+    fn dup(@mut self) -> reader { dup_string_reader(self) as reader }
 }
 
-pub impl tt_reader_: reader {
-    fn is_eof(&self) -> bool { self.cur_tok == token::EOF }
-    fn next_token(&self) -> TokenAndSpan {
-        /* weird resolve bug: if the following `if`, or any of its
-        statements are removed, we get resolution errors */
-        if false {
-            let _ignore_me = 0;
-            let _me_too = self.cur.readme[self.cur.idx];
-        }
-        tt_next_token(self)
-    }
-    fn fatal(&self, m: ~str) -> ! {
+pub impl TtReader: reader {
+    fn is_eof(@mut self) -> bool { self.cur_tok == token::EOF }
+    fn next_token(@mut self) -> TokenAndSpan { tt_next_token(self) }
+    fn fatal(@mut self, m: ~str) -> ! {
         self.sp_diag.span_fatal(copy self.cur_span, m);
     }
-    fn span_diag(&self) -> span_handler { self.sp_diag }
-    pure fn interner(&self) -> @token::ident_interner { self.interner }
-    fn peek(&self) -> TokenAndSpan {
+    fn span_diag(@mut self) -> span_handler { self.sp_diag }
+    pure fn interner(@mut self) -> @token::ident_interner { self.interner }
+    fn peek(@mut self) -> TokenAndSpan {
         TokenAndSpan { tok: self.cur_tok, sp: self.cur_span }
     }
-    fn dup(&self) -> reader { dup_tt_reader(self) as reader }
+    fn dup(@mut self) -> reader { dup_tt_reader(self) as reader }
 }
 
 // EFFECT: advance peek_tok and peek_span to refer to the next token.
-fn string_advance_token(r: &string_reader_) {
+fn string_advance_token(r: @mut StringReader) {
     match (consume_whitespace_and_comments(r)) {
         Some(comment) => {
             r.peek_tok = comment.tok;
@@ -160,11 +160,11 @@ fn string_advance_token(r: &string_reader_) {
     }
 }
 
-fn byte_offset(rdr: &string_reader_) -> BytePos {
+fn byte_offset(rdr: @mut StringReader) -> BytePos {
     (rdr.pos - rdr.filemap.start_pos)
 }
 
-pub fn get_str_from(rdr: &string_reader_, start: BytePos) -> ~str {
+pub fn get_str_from(rdr: @mut StringReader, start: BytePos) -> ~str {
     unsafe {
         // I'm pretty skeptical about this subtraction. What if there's a
         // multi-byte character before the mark?
@@ -175,7 +175,7 @@ pub fn get_str_from(rdr: &string_reader_, start: BytePos) -> ~str {
 
 // EFFECT: advance the StringReader by one character. If a newline is
 // discovered, add it to the FileMap's list of line start offsets.
-pub fn bump(rdr: &string_reader_) {
+pub fn bump(rdr: @mut StringReader) {
     rdr.last_pos = rdr.pos;
     let current_byte_offset = byte_offset(rdr).to_uint();;
     if current_byte_offset < (*rdr.src).len() {
@@ -199,10 +199,10 @@ pub fn bump(rdr: &string_reader_) {
         rdr.curr = -1 as char;
     }
 }
-pub fn is_eof(rdr: &string_reader_) -> bool {
+pub fn is_eof(rdr: @mut StringReader) -> bool {
     rdr.curr == -1 as char
 }
-pub fn nextch(rdr: &string_reader_) -> char {
+pub fn nextch(rdr: @mut StringReader) -> char {
     let offset = byte_offset(rdr).to_uint();
     if offset < (*rdr.src).len() {
         return str::char_at(*rdr.src, offset);
@@ -247,8 +247,8 @@ fn is_bin_digit(c: char) -> bool { return c == '0' || c == '1'; }
 
 // EFFECT: eats whitespace and comments.
 // returns a Some(sugared-doc-attr) if one exists, None otherwise.
-fn consume_whitespace_and_comments(rdr: &string_reader_)
-    -> Option<TokenAndSpan> {
+fn consume_whitespace_and_comments(rdr: @mut StringReader)
+                                -> Option<TokenAndSpan> {
     while is_whitespace(rdr.curr) { bump(rdr); }
     return consume_any_line_comment(rdr);
 }
@@ -256,8 +256,8 @@ fn consume_whitespace_and_comments(rdr: &string_reader_)
 // PRECONDITION: rdr.curr is not whitespace
 // EFFECT: eats any kind of comment.
 // returns a Some(sugared-doc-attr) if one exists, None otherwise
-fn consume_any_line_comment(rdr: &string_reader_)
-                                -> Option<TokenAndSpan> {
+fn consume_any_line_comment(rdr: @mut StringReader)
+                         -> Option<TokenAndSpan> {
     if rdr.curr == '/' {
         match nextch(rdr) {
           '/' => {
@@ -299,9 +299,8 @@ fn consume_any_line_comment(rdr: &string_reader_)
 }
 
 // might return a sugared-doc-attr
-fn consume_block_comment(rdr: &string_reader_)
-                                -> Option<TokenAndSpan> {
-
+fn consume_block_comment(rdr: @mut StringReader)
+                      -> Option<TokenAndSpan> {
     // block comments starting with "/**" or "/*!" are doc-comments
     if rdr.curr == '*' || rdr.curr == '!' {
         let start_bpos = rdr.pos - BytePos(2u);
@@ -338,7 +337,7 @@ fn consume_block_comment(rdr: &string_reader_)
     return consume_whitespace_and_comments(rdr);
 }
 
-fn scan_exponent(rdr: &string_reader_) -> Option<~str> {
+fn scan_exponent(rdr: @mut StringReader) -> Option<~str> {
     let mut c = rdr.curr;
     let mut rslt = ~"";
     if c == 'e' || c == 'E' {
@@ -356,7 +355,7 @@ fn scan_exponent(rdr: &string_reader_) -> Option<~str> {
     } else { return None::<~str>; }
 }
 
-fn scan_digits(rdr: &string_reader_, radix: uint) -> ~str {
+fn scan_digits(rdr: @mut StringReader, radix: uint) -> ~str {
     let mut rslt = ~"";
     loop {
         let c = rdr.curr;
@@ -371,7 +370,7 @@ fn scan_digits(rdr: &string_reader_, radix: uint) -> ~str {
     };
 }
 
-fn scan_number(c: char, rdr: &string_reader_) -> token::Token {
+fn scan_number(c: char, rdr: @mut StringReader) -> token::Token {
     let mut num_str, base = 10u, c = c, n = nextch(rdr);
     if c == '0' && n == 'x' {
         bump(rdr);
@@ -487,7 +486,7 @@ fn scan_number(c: char, rdr: &string_reader_) -> token::Token {
     }
 }
 
-fn scan_numeric_escape(rdr: &string_reader_, n_hex_digits: uint) -> char {
+fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char {
     let mut accum_int = 0, i = n_hex_digits;
     while i != 0u {
         let n = rdr.curr;
@@ -502,7 +501,7 @@ fn scan_numeric_escape(rdr: &string_reader_, n_hex_digits: uint) -> char {
     return accum_int as char;
 }
 
-fn next_token_inner(rdr: &string_reader_) -> token::Token {
+fn next_token_inner(rdr: @mut StringReader) -> token::Token {
     let mut accum_str = ~"";
     let mut c = rdr.curr;
     if (c >= 'a' && c <= 'z')
@@ -527,7 +526,7 @@ fn next_token_inner(rdr: &string_reader_) -> token::Token {
     if is_dec_digit(c) {
         return scan_number(c, rdr);
     }
-    fn binop(rdr: &string_reader_, op: token::binop) -> token::Token {
+    fn binop(rdr: @mut StringReader, op: token::binop) -> token::Token {
         bump(rdr);
         if rdr.curr == '=' {
             bump(rdr);
@@ -720,7 +719,7 @@ fn next_token_inner(rdr: &string_reader_) -> token::Token {
     }
 }
 
-fn consume_whitespace(rdr: &string_reader_) {
+fn consume_whitespace(rdr: @mut StringReader) {
     while is_whitespace(rdr.curr) && !is_eof(rdr) { bump(rdr); }
 }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 6169233c1b7..b8e671b3265 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -15,9 +15,9 @@ use ast::node_id;
 use ast;
 use codemap::{span, CodeMap, FileMap, CharPos, BytePos};
 use codemap;
-use diagnostic::{span_handler, mk_span_handler, mk_handler, emitter};
+use diagnostic::{span_handler, mk_span_handler, mk_handler, Emitter};
 use parse::attr::parser_attr;
-use parse::lexer::{reader, string_reader};
+use parse::lexer::{reader, StringReader};
 use parse::parser::Parser;
 use parse::token::{ident_interner, mk_ident_interner};
 use util::interner;
@@ -54,7 +54,7 @@ pub type parse_sess = @{
     interner: @ident_interner,
 };
 
-pub fn new_parse_sess(demitter: Option<emitter>) -> parse_sess {
+pub fn new_parse_sess(demitter: Option<Emitter>) -> parse_sess {
     let cm = @CodeMap::new();
     return @{cm: cm,
              mut next_id: 1,
@@ -166,18 +166,22 @@ pub fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
                               +name: ~str, +ss: codemap::FileSubstr,
                               source: @~str) -> Parser {
     let filemap = sess.cm.new_filemap_w_substr(name, ss, source);
-    let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
+    let srdr = lexer::new_string_reader(sess.span_diagnostic,
+                                        filemap,
                                         sess.interner);
     return Parser(sess, cfg, srdr as reader);
 }
 
-pub fn new_parser_from_file(sess: parse_sess, cfg: ast::crate_cfg,
-                        path: &Path) -> Result<Parser, ~str> {
+pub fn new_parser_from_file(sess: parse_sess,
+                            cfg: ast::crate_cfg,
+                            path: &Path)
+                         -> Result<Parser, ~str> {
     match io::read_whole_file_str(path) {
       result::Ok(move src) => {
 
           let filemap = sess.cm.new_filemap(path.to_str(), @move src);
-          let srdr = lexer::new_string_reader(sess.span_diagnostic, filemap,
+          let srdr = lexer::new_string_reader(sess.span_diagnostic,
+                                              filemap,
                                               sess.interner);
 
           Ok(Parser(sess, cfg, srdr as reader))
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 34ba4526c47..4b9767ca6c8 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -32,7 +32,7 @@ use core::vec;
  * I am implementing this algorithm because it comes with 20 pages of
  * documentation explaining its theory, and because it addresses the set of
  * concerns I've seen other pretty-printers fall down on. Weirdly. Even though
- * it's 32 years old and not written in Haskell. What can I say?
+ * it's 32 years old. What can I say?
  *
  * Despite some redundancies and quirks in the way it's implemented in that
  * paper, I've opted to keep the implementation here as similar as I can,
@@ -69,20 +69,9 @@ use core::vec;
  * line (which it can't) and so naturally place the content on its own line to
  * avoid combining it with other lines and making matters even worse.
  */
+#[deriving_eq]
 pub enum breaks { consistent, inconsistent, }
 
-pub impl breaks : cmp::Eq {
-    pure fn eq(&self, other: &breaks) -> bool {
-        match ((*self), (*other)) {
-            (consistent, consistent) => true,
-            (inconsistent, inconsistent) => true,
-            (consistent, _) => false,
-            (inconsistent, _) => false,
-        }
-    }
-    pure fn ne(&self, other: &breaks) -> bool { !(*self).eq(other) }
-}
-
 pub type break_t = {offset: int, blank_space: int};
 
 pub type begin_t = {offset: int, breaks: breaks};
@@ -96,11 +85,11 @@ pub enum token {
 }
 
 pub impl token {
-    fn is_eof() -> bool {
-        match self { EOF => true, _ => false }
+    fn is_eof(&self) -> bool {
+        match *self { EOF => true, _ => false }
     }
-    fn is_hardbreak_tok() -> bool {
-        match self {
+    fn is_hardbreak_tok(&self) -> bool {
+        match *self {
             BREAK({offset: 0, blank_space: bs }) if bs == size_infinity =>
                 true,
             _ =>
@@ -111,11 +100,11 @@ pub impl token {
 
 pub fn tok_str(++t: token) -> ~str {
     match t {
-      STRING(s, len) => return fmt!("STR(%s,%d)", *s, len),
-      BREAK(_) => return ~"BREAK",
-      BEGIN(_) => return ~"BEGIN",
-      END => return ~"END",
-      EOF => return ~"EOF"
+        STRING(s, len) => return fmt!("STR(%s,%d)", *s, len),
+        BREAK(_) => return ~"BREAK",
+        BEGIN(_) => return ~"BEGIN",
+        END => return ~"END",
+        EOF => return ~"EOF"
     }
 }
 
@@ -143,7 +132,7 @@ pub type print_stack_elt = {offset: int, pbreak: print_stack_break};
 
 pub const size_infinity: int = 0xffff;
 
-pub fn mk_printer(out: io::Writer, linewidth: uint) -> printer {
+pub fn mk_printer(out: @io::Writer, linewidth: uint) -> @mut Printer {
     // Yes 3, it makes the ring buffers big enough to never
     // fall behind.
     let n: uint = 3 * linewidth;
@@ -151,22 +140,24 @@ pub fn mk_printer(out: io::Writer, linewidth: uint) -> printer {
     let mut token: ~[token] = vec::from_elem(n, EOF);
     let mut size: ~[int] = vec::from_elem(n, 0);
     let mut scan_stack: ~[uint] = vec::from_elem(n, 0u);
-    printer_(@{out: out,
-               buf_len: n,
-               mut margin: linewidth as int,
-               mut space: linewidth as int,
-               mut left: 0,
-               mut right: 0,
-               mut token: move token,
-               mut size: move size,
-               mut left_total: 0,
-               mut right_total: 0,
-               mut scan_stack: move scan_stack,
-               mut scan_stack_empty: true,
-               mut top: 0,
-               mut bottom: 0,
-               print_stack: DVec(),
-               mut pending_indentation: 0 })
+    @mut Printer {
+        out: @out,
+        buf_len: n,
+        margin: linewidth as int,
+        space: linewidth as int,
+        left: 0,
+        right: 0,
+        token: move token,
+        size: move size,
+        left_total: 0,
+        right_total: 0,
+        scan_stack: move scan_stack,
+        scan_stack_empty: true,
+        top: 0,
+        bottom: 0,
+        print_stack: @mut ~[],
+        pending_indentation: 0
+    }
 }
 
 
@@ -247,42 +238,38 @@ pub fn mk_printer(out: io::Writer, linewidth: uint) -> printer {
  * the method called 'pretty_print', and the 'PRINT' process is the method
  * called 'print'.
  */
-pub type printer_ = {
-    out: io::Writer,
+pub struct Printer {
+    out: @@io::Writer,
     buf_len: uint,
-    mut margin: int, // width of lines we're constrained to
-    mut space: int, // number of spaces left on line
-    mut left: uint, // index of left side of input stream
-    mut right: uint, // index of right side of input stream
-    mut token: ~[token], // ring-buffr stream goes through
-    mut size: ~[int], // ring-buffer of calculated sizes
-    mut left_total: int, // running size of stream "...left"
-    mut right_total: int, // running size of stream "...right"
+    margin: int, // width of lines we're constrained to
+    space: int, // number of spaces left on line
+    left: uint, // index of left side of input stream
+    right: uint, // index of right side of input stream
+    token: ~[token], // ring-buffr stream goes through
+    size: ~[int], // ring-buffer of calculated sizes
+    left_total: int, // running size of stream "...left"
+    right_total: int, // running size of stream "...right"
     // pseudo-stack, really a ring too. Holds the
     // primary-ring-buffers index of the BEGIN that started the
     // current block, possibly with the most recent BREAK after that
     // BEGIN (if there is any) on top of it. Stuff is flushed off the
     // bottom as it becomes irrelevant due to the primary ring-buffer
     // advancing.
-    mut scan_stack: ~[uint],
-    mut scan_stack_empty: bool, // top==bottom disambiguator
-    mut top: uint, // index of top of scan_stack
-    mut bottom: uint, // index of bottom of scan_stack
+    scan_stack: ~[uint],
+    scan_stack_empty: bool, // top==bottom disambiguator
+    top: uint, // index of top of scan_stack
+    bottom: uint, // index of bottom of scan_stack
     // stack of blocks-in-progress being flushed by print
-    print_stack: DVec<print_stack_elt>,
+    print_stack: @mut ~[print_stack_elt],
     // buffered indentation to avoid writing trailing whitespace
-    mut pending_indentation: int,
-};
-
-pub enum printer {
-    printer_(@printer_)
+    pending_indentation: int,
 }
 
-pub impl printer {
-    fn last_token() -> token { self.token[self.right] }
+pub impl Printer {
+    fn last_token(&mut self) -> token { self.token[self.right] }
     // be very careful with this!
-    fn replace_last_token(t: token) { self.token[self.right] = t; }
-    fn pretty_print(t: token) {
+    fn replace_last_token(&mut self, t: token) { self.token[self.right] = t; }
+    fn pretty_print(&mut self, t: token) {
         debug!("pp ~[%u,%u]", self.left, self.right);
         match t {
           EOF => {
@@ -350,7 +337,7 @@ pub impl printer {
           }
         }
     }
-    fn check_stream() {
+    fn check_stream(&mut self) {
         debug!("check_stream ~[%u, %u] with left_total=%d, right_total=%d",
                self.left, self.right, self.left_total, self.right_total);
         if self.right_total - self.left_total > self.space {
@@ -366,7 +353,7 @@ pub impl printer {
             if self.left != self.right { self.check_stream(); }
         }
     }
-    fn scan_push(x: uint) {
+    fn scan_push(&mut self, x: uint) {
         debug!("scan_push %u", x);
         if self.scan_stack_empty {
             self.scan_stack_empty = false;
@@ -377,7 +364,7 @@ pub impl printer {
         }
         self.scan_stack[self.top] = x;
     }
-    fn scan_pop() -> uint {
+    fn scan_pop(&mut self) -> uint {
         assert (!self.scan_stack_empty);
         let x = self.scan_stack[self.top];
         if self.top == self.bottom {
@@ -385,11 +372,11 @@ pub impl printer {
         } else { self.top += self.buf_len - 1u; self.top %= self.buf_len; }
         return x;
     }
-    fn scan_top() -> uint {
+    fn scan_top(&mut self) -> uint {
         assert (!self.scan_stack_empty);
         return self.scan_stack[self.top];
     }
-    fn scan_pop_bottom() -> uint {
+    fn scan_pop_bottom(&mut self) -> uint {
         assert (!self.scan_stack_empty);
         let x = self.scan_stack[self.bottom];
         if self.top == self.bottom {
@@ -397,12 +384,12 @@ pub impl printer {
         } else { self.bottom += 1u; self.bottom %= self.buf_len; }
         return x;
     }
-    fn advance_right() {
+    fn advance_right(&mut self) {
         self.right += 1u;
         self.right %= self.buf_len;
         assert (self.right != self.left);
     }
-    fn advance_left(++x: token, L: int) {
+    fn advance_left(&mut self, ++x: token, L: int) {
         debug!("advnce_left ~[%u,%u], sizeof(%u)=%d", self.left, self.right,
                self.left, L);
         if L >= 0 {
@@ -420,7 +407,7 @@ pub impl printer {
             }
         }
     }
-    fn check_stack(k: int) {
+    fn check_stack(&mut self, k: int) {
         if !self.scan_stack_empty {
             let x = self.scan_top();
             match copy self.token[x] {
@@ -443,17 +430,17 @@ pub impl printer {
             }
         }
     }
-    fn print_newline(amount: int) {
+    fn print_newline(&mut self, amount: int) {
         debug!("NEWLINE %d", amount);
-        self.out.write_str(~"\n");
+        (*self.out).write_str(~"\n");
         self.pending_indentation = 0;
         self.indent(amount);
     }
-    fn indent(amount: int) {
+    fn indent(&mut self, amount: int) {
         debug!("INDENT %d", amount);
         self.pending_indentation += amount;
     }
-    fn get_top() -> print_stack_elt {
+    fn get_top(&mut self) -> print_stack_elt {
         let n = self.print_stack.len();
         if n != 0u {
             self.print_stack[n - 1u]
@@ -461,14 +448,14 @@ pub impl printer {
             {offset: 0, pbreak: broken(inconsistent)}
         }
     }
-    fn print_str(s: ~str) {
+    fn print_str(&mut self, s: ~str) {
         while self.pending_indentation > 0 {
-            self.out.write_str(~" ");
+            (*self.out).write_str(~" ");
             self.pending_indentation -= 1;
         }
-        self.out.write_str(s);
+        (*self.out).write_str(s);
     }
-    fn print(x: token, L: int) {
+    fn print(&mut self, x: token, L: int) {
         debug!("print %s %d (remaining line space=%d)", tok_str(x), L,
                self.space);
         log(debug, buf_str(copy self.token,
@@ -539,39 +526,41 @@ pub impl printer {
 }
 
 // Convenience functions to talk to the printer.
-pub fn box(p: printer, indent: uint, b: breaks) {
+pub fn box(p: @mut Printer, indent: uint, b: breaks) {
     p.pretty_print(BEGIN({offset: indent as int, breaks: b}));
 }
 
-pub fn ibox(p: printer, indent: uint) { box(p, indent, inconsistent); }
+pub fn ibox(p: @mut Printer, indent: uint) { box(p, indent, inconsistent); }
 
-pub fn cbox(p: printer, indent: uint) { box(p, indent, consistent); }
+pub fn cbox(p: @mut Printer, indent: uint) { box(p, indent, consistent); }
 
-pub fn break_offset(p: printer, n: uint, off: int) {
+pub fn break_offset(p: @mut Printer, n: uint, off: int) {
     p.pretty_print(BREAK({offset: off, blank_space: n as int}));
 }
 
-pub fn end(p: printer) { p.pretty_print(END); }
+pub fn end(p: @mut Printer) { p.pretty_print(END); }
 
-pub fn eof(p: printer) { p.pretty_print(EOF); }
+pub fn eof(p: @mut Printer) { p.pretty_print(EOF); }
 
-pub fn word(p: printer, wrd: ~str) {
+pub fn word(p: @mut Printer, wrd: ~str) {
     p.pretty_print(STRING(@wrd, str::len(wrd) as int));
 }
 
-pub fn huge_word(p: printer, wrd: ~str) {
+pub fn huge_word(p: @mut Printer, wrd: ~str) {
     p.pretty_print(STRING(@wrd, size_infinity));
 }
 
-pub fn zero_word(p: printer, wrd: ~str) { p.pretty_print(STRING(@wrd, 0)); }
+pub fn zero_word(p: @mut Printer, wrd: ~str) {
+    p.pretty_print(STRING(@wrd, 0));
+}
 
-pub fn spaces(p: printer, n: uint) { break_offset(p, n, 0); }
+pub fn spaces(p: @mut Printer, n: uint) { break_offset(p, n, 0); }
 
-pub fn zerobreak(p: printer) { spaces(p, 0u); }
+pub fn zerobreak(p: @mut Printer) { spaces(p, 0u); }
 
-pub fn space(p: printer) { spaces(p, 1u); }
+pub fn space(p: @mut Printer) { spaces(p, 1u); }
 
-pub fn hardbreak(p: printer) { spaces(p, size_infinity as uint); }
+pub fn hardbreak(p: @mut Printer) { spaces(p, size_infinity as uint); }
 
 pub fn hardbreak_tok_offset(off: int) -> token {
     return BREAK({offset: off, blank_space: size_infinity});
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index bcbee7b2f24..dec9f5abd6a 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -23,7 +23,7 @@ use parse::classify::{stmt_ends_with_semi};
 use parse::token::ident_interner;
 use parse::{comments, lexer, token};
 use parse;
-use print::pp::{break_offset, word, printer, space, zerobreak, hardbreak};
+use print::pp::{break_offset, word, Printer, space, zerobreak, hardbreak};
 use print::pp::{breaks, consistent, inconsistent, eof};
 use print::pp;
 use print::pprust;
@@ -37,12 +37,12 @@ use core::str;
 use core::u64;
 use core::vec;
 
-// The ps is stored here to prevent recursive type.
+// The @ps is stored here to prevent recursive type.
 pub enum ann_node {
-    node_block(ps, ast::blk),
-    node_item(ps, @ast::item),
-    node_expr(ps, @ast::expr),
-    node_pat(ps, @ast::pat),
+    node_block(@ps, ast::blk),
+    node_item(@ps, @ast::item),
+    node_expr(@ps, @ast::expr),
+    node_pat(@ps, @ast::pat),
 }
 pub struct pp_ann {
     pre: fn@(ann_node),
@@ -54,37 +54,46 @@ pub fn no_ann() -> pp_ann {
     return pp_ann {pre: ignore, post: ignore};
 }
 
-pub type ps =
-    @{s: pp::printer,
-      cm: Option<@CodeMap>,
-      intr: @token::ident_interner,
-      comments: Option<~[comments::cmnt]>,
-      literals: Option<~[comments::lit]>,
-      mut cur_cmnt: uint,
-      mut cur_lit: uint,
-      boxes: DVec<pp::breaks>,
-      ann: pp_ann};
+pub struct CurrentCommentAndLiteral {
+    cur_cmnt: uint,
+    cur_lit: uint,
+}
+
+pub struct ps {
+    s: @mut pp::Printer,
+    cm: Option<@CodeMap>,
+    intr: @token::ident_interner,
+    comments: Option<~[comments::cmnt]>,
+    literals: Option<~[comments::lit]>,
+    cur_cmnt_and_lit: @mut CurrentCommentAndLiteral,
+    boxes: DVec<pp::breaks>,
+    ann: pp_ann
+}
 
-pub fn ibox(s: ps, u: uint) {
+pub fn ibox(s: @ps, u: uint) {
     s.boxes.push(pp::inconsistent);
     pp::ibox(s.s, u);
 }
 
-pub fn end(s: ps) {
+pub fn end(s: @ps) {
     s.boxes.pop();
     pp::end(s.s);
 }
 
-pub fn rust_printer(writer: io::Writer, intr: @ident_interner) -> ps {
-    return @{s: pp::mk_printer(writer, default_columns),
-             cm: None::<@CodeMap>,
-             intr: intr,
-             comments: None::<~[comments::cmnt]>,
-             literals: None::<~[comments::lit]>,
-             mut cur_cmnt: 0u,
-             mut cur_lit: 0u,
-             boxes: DVec(),
-             ann: no_ann()};
+pub fn rust_printer(writer: io::Writer, intr: @ident_interner) -> @ps {
+    return @ps {
+        s: pp::mk_printer(writer, default_columns),
+        cm: None::<@CodeMap>,
+        intr: intr,
+        comments: None::<~[comments::cmnt]>,
+        literals: None::<~[comments::lit]>,
+        cur_cmnt_and_lit: @mut CurrentCommentAndLiteral {
+            cur_cmnt: 0,
+            cur_lit: 0
+        },
+        boxes: DVec(),
+        ann: no_ann()
+    };
 }
 
 pub const indent_unit: uint = 4u;
@@ -101,23 +110,26 @@ pub fn print_crate(cm: @CodeMap, intr: @ident_interner,
                    out: io::Writer, ann: pp_ann, is_expanded: bool) {
     let r = comments::gather_comments_and_literals(span_diagnostic,
                                                    filename, in);
-    let s =
-        @{s: pp::mk_printer(out, default_columns),
-          cm: Some(cm),
-          intr: intr,
-          comments: Some(r.cmnts),
-          // If the code is post expansion, don't use the table of
-          // literals, since it doesn't correspond with the literals
-          // in the AST anymore.
-          literals: if is_expanded { None } else { Some(r.lits) },
-          mut cur_cmnt: 0u,
-          mut cur_lit: 0u,
-          boxes: DVec(),
-          ann: ann};
+    let s = @ps {
+        s: pp::mk_printer(out, default_columns),
+        cm: Some(cm),
+        intr: intr,
+        comments: Some(r.cmnts),
+        // If the code is post expansion, don't use the table of
+        // literals, since it doesn't correspond with the literals
+        // in the AST anymore.
+        literals: if is_expanded { None } else { Some(r.lits) },
+        cur_cmnt_and_lit: @mut CurrentCommentAndLiteral {
+            cur_cmnt: 0,
+            cur_lit: 0
+        },
+        boxes: DVec(),
+        ann: ann
+    };
     print_crate_(s, crate);
 }
 
-pub fn print_crate_(s: ps, &&crate: @ast::crate) {
+pub fn print_crate_(s: @ps, &&crate: @ast::crate) {
     print_mod(s, crate.node.module, crate.node.attrs);
     print_remaining_comments(s);
     eof(s.s);
@@ -194,27 +206,27 @@ pub fn variant_to_str(var: ast::variant, intr: @ident_interner) -> ~str {
     to_str(var, print_variant, intr)
 }
 
-pub fn cbox(s: ps, u: uint) {
+pub fn cbox(s: @ps, u: uint) {
     s.boxes.push(pp::consistent);
     pp::cbox(s.s, u);
 }
 
-pub fn box(s: ps, u: uint, b: pp::breaks) {
+pub fn box(s: @ps, u: uint, b: pp::breaks) {
     s.boxes.push(b);
     pp::box(s.s, u, b);
 }
 
-pub fn nbsp(s: ps) { word(s.s, ~" "); }
+pub fn nbsp(s: @ps) { word(s.s, ~" "); }
 
-pub fn word_nbsp(s: ps, w: ~str) { word(s.s, w); nbsp(s); }
+pub fn word_nbsp(s: @ps, w: ~str) { word(s.s, w); nbsp(s); }
 
-pub fn word_space(s: ps, w: ~str) { word(s.s, w); space(s.s); }
+pub fn word_space(s: @ps, w: ~str) { word(s.s, w); space(s.s); }
 
-pub fn popen(s: ps) { word(s.s, ~"("); }
+pub fn popen(s: @ps) { word(s.s, ~"("); }
 
-pub fn pclose(s: ps) { word(s.s, ~")"); }
+pub fn pclose(s: @ps) { word(s.s, ~")"); }
 
-pub fn head(s: ps, w: ~str) {
+pub fn head(s: @ps, w: ~str) {
     // outer-box is consistent
     cbox(s, indent_unit);
     // head-box is inconsistent
@@ -225,15 +237,15 @@ pub fn head(s: ps, w: ~str) {
     }
 }
 
-pub fn bopen(s: ps) {
+pub fn bopen(s: @ps) {
     word(s.s, ~"{");
     end(s); // close the head-box
 }
 
-pub fn bclose_(s: ps, span: codemap::span, indented: uint) {
+pub fn bclose_(s: @ps, span: codemap::span, indented: uint) {
     bclose_maybe_open(s, span, indented, true);
 }
-pub fn bclose_maybe_open (s: ps, span: codemap::span, indented: uint,
+pub fn bclose_maybe_open (s: @ps, span: codemap::span, indented: uint,
                           close_box: bool) {
     maybe_print_comment(s, span.hi);
     break_offset_if_not_bol(s, 1u, -(indented as int));
@@ -242,29 +254,29 @@ pub fn bclose_maybe_open (s: ps, span: codemap::span, indented: uint,
         end(s); // close the outer-box
     }
 }
-pub fn bclose(s: ps, span: codemap::span) { bclose_(s, span, indent_unit); }
+pub fn bclose(s: @ps, span: codemap::span) { bclose_(s, span, indent_unit); }
 
-pub fn is_begin(s: ps) -> bool {
+pub fn is_begin(s: @ps) -> bool {
     match s.s.last_token() { pp::BEGIN(_) => true, _ => false }
 }
 
-pub fn is_end(s: ps) -> bool {
+pub fn is_end(s: @ps) -> bool {
     match s.s.last_token() { pp::END => true, _ => false }
 }
 
-pub fn is_bol(s: ps) -> bool {
+pub fn is_bol(s: @ps) -> bool {
     return s.s.last_token().is_eof() || s.s.last_token().is_hardbreak_tok();
 }
 
-pub fn in_cbox(s: ps) -> bool {
+pub fn in_cbox(s: @ps) -> bool {
     let len = s.boxes.len();
     if len == 0u { return false; }
     return s.boxes[len - 1u] == pp::consistent;
 }
 
-pub fn hardbreak_if_not_bol(s: ps) { if !is_bol(s) { hardbreak(s.s); } }
-pub fn space_if_not_bol(s: ps) { if !is_bol(s) { space(s.s); } }
-pub fn break_offset_if_not_bol(s: ps, n: uint, off: int) {
+pub fn hardbreak_if_not_bol(s: @ps) { if !is_bol(s) { hardbreak(s.s); } }
+pub fn space_if_not_bol(s: @ps) { if !is_bol(s) { space(s.s); } }
+pub fn break_offset_if_not_bol(s: @ps, n: uint, off: int) {
     if !is_bol(s) {
         break_offset(s.s, n, off);
     } else {
@@ -279,7 +291,7 @@ pub fn break_offset_if_not_bol(s: ps, n: uint, off: int) {
 
 // Synthesizes a comment that was not textually present in the original source
 // file.
-pub fn synth_comment(s: ps, text: ~str) {
+pub fn synth_comment(s: @ps, text: ~str) {
     word(s.s, ~"/*");
     space(s.s);
     word(s.s, text);
@@ -287,7 +299,7 @@ pub fn synth_comment(s: ps, text: ~str) {
     word(s.s, ~"*/");
 }
 
-pub fn commasep<IN>(s: ps, b: breaks, elts: ~[IN], op: fn(ps, IN)) {
+pub fn commasep<IN>(s: @ps, b: breaks, elts: ~[IN], op: fn(@ps, IN)) {
     box(s, 0u, b);
     let mut first = true;
     for elts.each |elt| {
@@ -298,7 +310,7 @@ pub fn commasep<IN>(s: ps, b: breaks, elts: ~[IN], op: fn(ps, IN)) {
 }
 
 
-pub fn commasep_cmnt<IN>(s: ps, b: breaks, elts: ~[IN], op: fn(ps, IN),
+pub fn commasep_cmnt<IN>(s: @ps, b: breaks, elts: ~[IN], op: fn(@ps, IN),
                          get_span: fn(IN) -> codemap::span) {
     box(s, 0u, b);
     let len = vec::len::<IN>(elts);
@@ -317,12 +329,12 @@ pub fn commasep_cmnt<IN>(s: ps, b: breaks, elts: ~[IN], op: fn(ps, IN),
     end(s);
 }
 
-pub fn commasep_exprs(s: ps, b: breaks, exprs: ~[@ast::expr]) {
+pub fn commasep_exprs(s: @ps, b: breaks, exprs: ~[@ast::expr]) {
     fn expr_span(&&expr: @ast::expr) -> codemap::span { return expr.span; }
     commasep_cmnt(s, b, exprs, print_expr, expr_span);
 }
 
-pub fn print_mod(s: ps, _mod: ast::_mod, attrs: ~[ast::attribute]) {
+pub fn print_mod(s: @ps, _mod: ast::_mod, attrs: ~[ast::attribute]) {
     print_inner_attributes(s, attrs);
     for _mod.view_items.each |vitem| {
         print_view_item(s, *vitem);
@@ -330,7 +342,7 @@ pub fn print_mod(s: ps, _mod: ast::_mod, attrs: ~[ast::attribute]) {
     for _mod.items.each |item| { print_item(s, *item); }
 }
 
-pub fn print_foreign_mod(s: ps, nmod: ast::foreign_mod,
+pub fn print_foreign_mod(s: @ps, nmod: ast::foreign_mod,
                          attrs: ~[ast::attribute]) {
     print_inner_attributes(s, attrs);
     for nmod.view_items.each |vitem| {
@@ -339,7 +351,7 @@ pub fn print_foreign_mod(s: ps, nmod: ast::foreign_mod,
     for nmod.items.each |item| { print_foreign_item(s, *item); }
 }
 
-pub fn print_region(s: ps, prefix: ~str, region: @ast::region, sep: ~str) {
+pub fn print_region(s: @ps, prefix: ~str, region: @ast::region, sep: ~str) {
     word(s.s, prefix);
     match region.node {
         ast::re_anon => {
@@ -358,11 +370,11 @@ pub fn print_region(s: ps, prefix: ~str, region: @ast::region, sep: ~str) {
     word(s.s, sep);
 }
 
-pub fn print_type(s: ps, &&ty: @ast::Ty) {
+pub fn print_type(s: @ps, &&ty: @ast::Ty) {
     print_type_ex(s, ty, false);
 }
 
-pub fn print_type_ex(s: ps, &&ty: @ast::Ty, print_colons: bool) {
+pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) {
     maybe_print_comment(s, ty.span.lo);
     ibox(s, 0u);
     match ty.node {
@@ -387,7 +399,7 @@ pub fn print_type_ex(s: ps, &&ty: @ast::Ty, print_colons: bool) {
       }
       ast::ty_rec(ref fields) => {
         word(s.s, ~"{");
-        fn print_field(s: ps, f: ast::ty_field) {
+        fn print_field(s: @ps, f: ast::ty_field) {
             cbox(s, indent_unit);
             print_mutability(s, f.node.mt.mutbl);
             print_ident(s, f.node.ident);
@@ -438,7 +450,7 @@ pub fn print_type_ex(s: ps, &&ty: @ast::Ty, print_colons: bool) {
     end(s);
 }
 
-pub fn print_foreign_item(s: ps, item: @ast::foreign_item) {
+pub fn print_foreign_item(s: @ps, item: @ast::foreign_item) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, item.span.lo);
     print_outer_attributes(s, item.attrs);
@@ -462,7 +474,7 @@ pub fn print_foreign_item(s: ps, item: @ast::foreign_item) {
     }
 }
 
-pub fn print_item(s: ps, &&item: @ast::item) {
+pub fn print_item(s: @ps, &&item: @ast::item) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, item.span.lo);
     print_outer_attributes(s, item.attrs);
@@ -597,7 +609,7 @@ pub fn print_item(s: ps, &&item: @ast::item) {
     (s.ann.post)(ann_node);
 }
 
-pub fn print_enum_def(s: ps, enum_definition: ast::enum_def,
+pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def,
                       params: ~[ast::ty_param], ident: ast::ident,
                       span: codemap::span, visibility: ast::visibility) {
     let mut newtype =
@@ -632,7 +644,7 @@ pub fn print_enum_def(s: ps, enum_definition: ast::enum_def,
     }
 }
 
-pub fn print_variants(s: ps,
+pub fn print_variants(s: @ps,
                       variants: ~[ast::variant],
                       span: codemap::span) {
     bopen(s);
@@ -665,7 +677,7 @@ pub fn visibility_qualified(vis: ast::visibility, s: ~str) -> ~str {
     }
 }
 
-pub fn print_visibility(s: ps, vis: ast::visibility) {
+pub fn print_visibility(s: @ps, vis: ast::visibility) {
     match vis {
         ast::private | ast::public =>
         word_nbsp(s, visibility_to_str(vis)),
@@ -673,7 +685,7 @@ pub fn print_visibility(s: ps, vis: ast::visibility) {
     }
 }
 
-pub fn print_struct(s: ps,
+pub fn print_struct(s: @ps,
                     struct_def: @ast::struct_def,
                     tps: ~[ast::ty_param],
                     ident: ast::ident,
@@ -742,7 +754,7 @@ pub fn print_struct(s: ps,
 /// appropriate macro, transcribe back into the grammar we just parsed from,
 /// and then pretty-print the resulting AST nodes (so, e.g., we print
 /// expression arguments as expressions). It can be done! I think.
-pub fn print_tt(s: ps, tt: ast::token_tree) {
+pub fn print_tt(s: @ps, tt: ast::token_tree) {
     match tt {
       ast::tt_delim(ref tts) => print_tts(s, *tts),
       ast::tt_tok(_, ref tk) => {
@@ -765,7 +777,7 @@ pub fn print_tt(s: ps, tt: ast::token_tree) {
     }
 }
 
-pub fn print_tts(s: ps, &&tts: &[ast::token_tree]) {
+pub fn print_tts(s: @ps, &&tts: &[ast::token_tree]) {
     ibox(s, 0);
     for tts.eachi |i, tt| {
         if i != 0 {
@@ -776,14 +788,14 @@ pub fn print_tts(s: ps, &&tts: &[ast::token_tree]) {
     end(s);
 }
 
-pub fn print_variant(s: ps, v: ast::variant) {
+pub fn print_variant(s: @ps, v: ast::variant) {
     print_visibility(s, v.node.vis);
     match v.node.kind {
         ast::tuple_variant_kind(args) => {
             print_ident(s, v.node.name);
             if !args.is_empty() {
                 popen(s);
-                fn print_variant_arg(s: ps, arg: ast::variant_arg) {
+                fn print_variant_arg(s: @ps, arg: ast::variant_arg) {
                     print_type(s, arg.ty);
                 }
                 commasep(s, consistent, args, print_variant_arg);
@@ -808,7 +820,7 @@ pub fn print_variant(s: ps, v: ast::variant) {
     }
 }
 
-pub fn print_ty_method(s: ps, m: ast::ty_method) {
+pub fn print_ty_method(s: @ps, m: ast::ty_method) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, m.span.lo);
     print_outer_attributes(s, m.attrs);
@@ -818,14 +830,14 @@ pub fn print_ty_method(s: ps, m: ast::ty_method) {
     word(s.s, ~";");
 }
 
-pub fn print_trait_method(s: ps, m: ast::trait_method) {
+pub fn print_trait_method(s: @ps, m: ast::trait_method) {
     match m {
       required(ref ty_m) => print_ty_method(s, (*ty_m)),
       provided(m)    => print_method(s, m)
     }
 }
 
-pub fn print_method(s: ps, meth: @ast::method) {
+pub fn print_method(s: @ps, meth: @ast::method) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, meth.span.lo);
     print_outer_attributes(s, meth.attrs);
@@ -836,7 +848,7 @@ pub fn print_method(s: ps, meth: @ast::method) {
     print_block_with_attrs(s, meth.body, meth.attrs);
 }
 
-pub fn print_outer_attributes(s: ps, attrs: ~[ast::attribute]) {
+pub fn print_outer_attributes(s: @ps, attrs: ~[ast::attribute]) {
     let mut count = 0;
     for attrs.each |attr| {
         match attr.node.style {
@@ -847,7 +859,7 @@ pub fn print_outer_attributes(s: ps, attrs: ~[ast::attribute]) {
     if count > 0 { hardbreak_if_not_bol(s); }
 }
 
-pub fn print_inner_attributes(s: ps, attrs: ~[ast::attribute]) {
+pub fn print_inner_attributes(s: @ps, attrs: ~[ast::attribute]) {
     let mut count = 0;
     for attrs.each |attr| {
         match attr.node.style {
@@ -864,7 +876,7 @@ pub fn print_inner_attributes(s: ps, attrs: ~[ast::attribute]) {
     if count > 0 { hardbreak_if_not_bol(s); }
 }
 
-pub fn print_attribute(s: ps, attr: ast::attribute) {
+pub fn print_attribute(s: @ps, attr: ast::attribute) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, attr.span.lo);
     if attr.node.is_sugared_doc {
@@ -879,7 +891,7 @@ pub fn print_attribute(s: ps, attr: ast::attribute) {
 }
 
 
-pub fn print_stmt(s: ps, st: ast::stmt) {
+pub fn print_stmt(s: @ps, st: ast::stmt) {
     maybe_print_comment(s, st.span.lo);
     match st.node {
       ast::stmt_decl(decl, _) => {
@@ -904,21 +916,21 @@ pub fn print_stmt(s: ps, st: ast::stmt) {
     maybe_print_trailing_comment(s, st.span, None);
 }
 
-pub fn print_block(s: ps, blk: ast::blk) {
+pub fn print_block(s: @ps, blk: ast::blk) {
     print_possibly_embedded_block(s, blk, block_normal, indent_unit);
 }
 
-pub fn print_block_unclosed(s: ps, blk: ast::blk) {
+pub fn print_block_unclosed(s: @ps, blk: ast::blk) {
     print_possibly_embedded_block_(s, blk, block_normal, indent_unit, ~[],
                                  false);
 }
 
-pub fn print_block_unclosed_indent(s: ps, blk: ast::blk, indented: uint) {
+pub fn print_block_unclosed_indent(s: @ps, blk: ast::blk, indented: uint) {
     print_possibly_embedded_block_(s, blk, block_normal, indented, ~[],
                                    false);
 }
 
-pub fn print_block_with_attrs(s: ps,
+pub fn print_block_with_attrs(s: @ps,
                               blk: ast::blk,
                               attrs: ~[ast::attribute]) {
     print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs,
@@ -927,7 +939,7 @@ pub fn print_block_with_attrs(s: ps,
 
 pub enum embed_type { block_block_fn, block_normal, }
 
-pub fn print_possibly_embedded_block(s: ps,
+pub fn print_possibly_embedded_block(s: @ps,
                                      blk: ast::blk,
                                      embedded: embed_type,
                                      indented: uint) {
@@ -935,7 +947,7 @@ pub fn print_possibly_embedded_block(s: ps,
         s, blk, embedded, indented, ~[], true);
 }
 
-pub fn print_possibly_embedded_block_(s: ps,
+pub fn print_possibly_embedded_block_(s: @ps,
                                       blk: ast::blk,
                                       embedded: embed_type,
                                       indented: uint,
@@ -971,14 +983,14 @@ pub fn print_possibly_embedded_block_(s: ps,
     (s.ann.post)(ann_node);
 }
 
-pub fn print_if(s: ps, test: @ast::expr, blk: ast::blk,
+pub fn print_if(s: @ps, test: @ast::expr, blk: ast::blk,
                 elseopt: Option<@ast::expr>, chk: bool) {
     head(s, ~"if");
     if chk { word_nbsp(s, ~"check"); }
     print_expr(s, test);
     space(s.s);
     print_block(s, blk);
-    fn do_else(s: ps, els: Option<@ast::expr>) {
+    fn do_else(s: @ps, els: Option<@ast::expr>) {
         match els {
           Some(_else) => {
             match _else.node {
@@ -1011,7 +1023,7 @@ pub fn print_if(s: ps, test: @ast::expr, blk: ast::blk,
     do_else(s, elseopt);
 }
 
-pub fn print_mac(s: ps, m: ast::mac) {
+pub fn print_mac(s: @ps, m: ast::mac) {
     match m.node {
       ast::mac_invoc_tt(pth, ref tts) => {
         print_path(s, pth, false);
@@ -1023,7 +1035,7 @@ pub fn print_mac(s: ps, m: ast::mac) {
     }
 }
 
-pub fn print_vstore(s: ps, t: ast::vstore) {
+pub fn print_vstore(s: @ps, t: ast::vstore) {
     match t {
         ast::vstore_fixed(Some(i)) => word(s.s, fmt!("%u", i)),
         ast::vstore_fixed(None) => word(s.s, ~"_"),
@@ -1033,7 +1045,7 @@ pub fn print_vstore(s: ps, t: ast::vstore) {
     }
 }
 
-pub fn print_expr_vstore(s: ps, t: ast::expr_vstore) {
+pub fn print_expr_vstore(s: @ps, t: ast::expr_vstore) {
     match t {
       ast::expr_vstore_fixed(Some(i)) => word(s.s, fmt!("%u", i)),
       ast::expr_vstore_fixed(None) => word(s.s, ~"_"),
@@ -1051,7 +1063,7 @@ pub fn print_expr_vstore(s: ps, t: ast::expr_vstore) {
     }
 }
 
-pub fn print_call_pre(s: ps,
+pub fn print_call_pre(s: @ps,
                       sugar: ast::CallSugar,
                       base_args: &mut ~[@ast::expr])
                    -> Option<@ast::expr> {
@@ -1068,7 +1080,7 @@ pub fn print_call_pre(s: ps,
     }
 }
 
-pub fn print_call_post(s: ps,
+pub fn print_call_post(s: @ps,
                        sugar: ast::CallSugar,
                        blk: &Option<@ast::expr>,
                        base_args: &mut ~[@ast::expr]) {
@@ -1095,8 +1107,8 @@ pub fn print_call_post(s: ps,
     }
 }
 
-pub fn print_expr(s: ps, &&expr: @ast::expr) {
-    fn print_field(s: ps, field: ast::field) {
+pub fn print_expr(s: @ps, &&expr: @ast::expr) {
+    fn print_field(s: @ps, field: ast::field) {
         ibox(s, indent_unit);
         if field.node.mutbl == ast::m_mutbl { word_nbsp(s, ~"mut"); }
         print_ident(s, field.node.ident);
@@ -1446,7 +1458,7 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) {
     end(s);
 }
 
-pub fn print_local_decl(s: ps, loc: @ast::local) {
+pub fn print_local_decl(s: @ps, loc: @ast::local) {
     print_irrefutable_pat(s, loc.node.pat);
     match loc.node.ty.node {
       ast::ty_infer => (),
@@ -1454,7 +1466,7 @@ pub fn print_local_decl(s: ps, loc: @ast::local) {
     }
 }
 
-pub fn print_decl(s: ps, decl: @ast::decl) {
+pub fn print_decl(s: @ps, decl: @ast::decl) {
     maybe_print_comment(s, decl.span.lo);
     match decl.node {
       ast::decl_local(locs) => {
@@ -1468,7 +1480,7 @@ pub fn print_decl(s: ps, decl: @ast::decl) {
             word_nbsp(s, ~"mut");
         }
 
-        fn print_local(s: ps, &&loc: @ast::local) {
+        fn print_local(s: @ps, &&loc: @ast::local) {
             ibox(s, indent_unit);
             print_local_decl(s, loc);
             end(s);
@@ -1488,18 +1500,18 @@ pub fn print_decl(s: ps, decl: @ast::decl) {
     }
 }
 
-pub fn print_ident(s: ps, ident: ast::ident) {
+pub fn print_ident(s: @ps, ident: ast::ident) {
     word(s.s, *s.intr.get(ident));
 }
 
-pub fn print_for_decl(s: ps, loc: @ast::local, coll: @ast::expr) {
+pub fn print_for_decl(s: @ps, loc: @ast::local, coll: @ast::expr) {
     print_local_decl(s, loc);
     space(s.s);
     word_space(s, ~"in");
     print_expr(s, coll);
 }
 
-pub fn print_path(s: ps, &&path: @ast::path, colons_before_params: bool) {
+pub fn print_path(s: @ps, &&path: @ast::path, colons_before_params: bool) {
     maybe_print_comment(s, path.span.lo);
     if path.global { word(s.s, ~"::"); }
     let mut first = true;
@@ -1526,15 +1538,15 @@ pub fn print_path(s: ps, &&path: @ast::path, colons_before_params: bool) {
     }
 }
 
-pub fn print_irrefutable_pat(s: ps, &&pat: @ast::pat) {
+pub fn print_irrefutable_pat(s: @ps, &&pat: @ast::pat) {
     print_pat(s, pat, false)
 }
 
-pub fn print_refutable_pat(s: ps, &&pat: @ast::pat) {
+pub fn print_refutable_pat(s: @ps, &&pat: @ast::pat) {
     print_pat(s, pat, true)
 }
 
-pub fn print_pat(s: ps, &&pat: @ast::pat, refutable: bool) {
+pub fn print_pat(s: @ps, &&pat: @ast::pat, refutable: bool) {
     maybe_print_comment(s, pat.span.lo);
     let ann_node = node_pat(s, pat);
     (s.ann.pre)(ann_node);
@@ -1580,7 +1592,7 @@ pub fn print_pat(s: ps, &&pat: @ast::pat, refutable: bool) {
       }
       ast::pat_rec(fields, etc) => {
         word(s.s, ~"{");
-        fn print_field(s: ps, f: ast::field_pat, refutable: bool) {
+        fn print_field(s: @ps, f: ast::field_pat, refutable: bool) {
             cbox(s, indent_unit);
             print_ident(s, f.ident);
             word_space(s, ~":");
@@ -1600,7 +1612,7 @@ pub fn print_pat(s: ps, &&pat: @ast::pat, refutable: bool) {
       ast::pat_struct(path, fields, etc) => {
         print_path(s, path, true);
         word(s.s, ~"{");
-        fn print_field(s: ps, f: ast::field_pat, refutable: bool) {
+        fn print_field(s: @ps, f: ast::field_pat, refutable: bool) {
             cbox(s, indent_unit);
             print_ident(s, f.ident);
             word_space(s, ~":");
@@ -1656,7 +1668,7 @@ pub fn print_pat(s: ps, &&pat: @ast::pat, refutable: bool) {
 }
 
 // Returns whether it printed anything
-pub fn print_self_ty(s: ps, self_ty: ast::self_ty_) -> bool {
+pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool {
     match self_ty {
       ast::sty_static | ast::sty_by_ref => { return false; }
       ast::sty_value => { word(s.s, ~"self"); }
@@ -1673,7 +1685,7 @@ pub fn print_self_ty(s: ps, self_ty: ast::self_ty_) -> bool {
     return true;
 }
 
-pub fn print_fn(s: ps,
+pub fn print_fn(s: @ps,
                 decl: ast::fn_decl,
                 purity: Option<ast::purity>,
                 name: ast::ident,
@@ -1688,7 +1700,7 @@ pub fn print_fn(s: ps,
     print_fn_args_and_ret(s, decl, opt_self_ty);
 }
 
-pub fn print_fn_args(s: ps, decl: ast::fn_decl,
+pub fn print_fn_args(s: @ps, decl: ast::fn_decl,
                  opt_self_ty: Option<ast::self_ty_>) {
     // It is unfortunate to duplicate the commasep logic, but we we want the
     // self type and the args all in the same box.
@@ -1706,7 +1718,7 @@ pub fn print_fn_args(s: ps, decl: ast::fn_decl,
     end(s);
 }
 
-pub fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl,
+pub fn print_fn_args_and_ret(s: @ps, decl: ast::fn_decl,
                              opt_self_ty: Option<ast::self_ty_>) {
     popen(s);
     print_fn_args(s, decl, opt_self_ty);
@@ -1723,7 +1735,7 @@ pub fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl,
     }
 }
 
-pub fn print_fn_block_args(s: ps, decl: ast::fn_decl) {
+pub fn print_fn_block_args(s: @ps, decl: ast::fn_decl) {
     word(s.s, ~"|");
     print_fn_args(s, decl, None);
     word(s.s, ~"|");
@@ -1749,12 +1761,12 @@ pub fn mode_to_str(m: ast::mode) -> ~str {
     }
 }
 
-pub fn print_arg_mode(s: ps, m: ast::mode) {
+pub fn print_arg_mode(s: @ps, m: ast::mode) {
     let ms = mode_to_str(m);
     if ms != ~"" { word(s.s, ms); }
 }
 
-pub fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) {
+pub fn print_bounds(s: @ps, bounds: @~[ast::ty_param_bound]) {
     if !bounds.is_empty() {
         word(s.s, ~":");
         let mut first = true;
@@ -1774,10 +1786,10 @@ pub fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) {
     }
 }
 
-pub fn print_type_params(s: ps, &&params: ~[ast::ty_param]) {
+pub fn print_type_params(s: @ps, &&params: ~[ast::ty_param]) {
     if vec::len(params) > 0u {
         word(s.s, ~"<");
-        fn printParam(s: ps, param: ast::ty_param) {
+        fn printParam(s: @ps, param: ast::ty_param) {
             print_ident(s, param.ident);
             print_bounds(s, param.bounds);
         }
@@ -1786,7 +1798,7 @@ pub fn print_type_params(s: ps, &&params: ~[ast::ty_param]) {
     }
 }
 
-pub fn print_meta_item(s: ps, &&item: @ast::meta_item) {
+pub fn print_meta_item(s: @ps, &&item: @ast::meta_item) {
     ibox(s, indent_unit);
     match item.node {
       ast::meta_word(ref name) => word(s.s, (*name)),
@@ -1805,7 +1817,7 @@ pub fn print_meta_item(s: ps, &&item: @ast::meta_item) {
     end(s);
 }
 
-pub fn print_view_path(s: ps, &&vp: @ast::view_path) {
+pub fn print_view_path(s: @ps, &&vp: @ast::view_path) {
     match vp.node {
       ast::view_path_simple(ident, path, namespace, _) => {
         if namespace == ast::module_ns {
@@ -1835,11 +1847,11 @@ pub fn print_view_path(s: ps, &&vp: @ast::view_path) {
     }
 }
 
-pub fn print_view_paths(s: ps, vps: ~[@ast::view_path]) {
+pub fn print_view_paths(s: @ps, vps: ~[@ast::view_path]) {
     commasep(s, inconsistent, vps, print_view_path);
 }
 
-pub fn print_view_item(s: ps, item: @ast::view_item) {
+pub fn print_view_item(s: @ps, item: @ast::view_item) {
     hardbreak_if_not_bol(s);
     maybe_print_comment(s, item.span.lo);
     print_outer_attributes(s, item.attrs);
@@ -1865,7 +1877,7 @@ pub fn print_view_item(s: ps, item: @ast::view_item) {
     end(s); // end outer head-block
 }
 
-pub fn print_mutability(s: ps, mutbl: ast::mutability) {
+pub fn print_mutability(s: @ps, mutbl: ast::mutability) {
     match mutbl {
       ast::m_mutbl => word_nbsp(s, ~"mut"),
       ast::m_const => word_nbsp(s, ~"const"),
@@ -1873,12 +1885,12 @@ pub fn print_mutability(s: ps, mutbl: ast::mutability) {
     }
 }
 
-pub fn print_mt(s: ps, mt: ast::mt) {
+pub fn print_mt(s: @ps, mt: ast::mt) {
     print_mutability(s, mt.mutbl);
     print_type(s, mt.ty);
 }
 
-pub fn print_arg(s: ps, input: ast::arg) {
+pub fn print_arg(s: @ps, input: ast::arg) {
     ibox(s, indent_unit);
     print_arg_mode(s, input.mode);
     if input.is_mutbl {
@@ -1905,7 +1917,7 @@ pub fn print_arg(s: ps, input: ast::arg) {
     end(s);
 }
 
-pub fn print_ty_fn(s: ps,
+pub fn print_ty_fn(s: @ps,
                    opt_abi: Option<ast::Abi>,
                    opt_sigil: Option<ast::Sigil>,
                    opt_region: Option<@ast::region>,
@@ -1961,7 +1973,7 @@ pub fn print_ty_fn(s: ps,
     end(s);
 }
 
-pub fn maybe_print_trailing_comment(s: ps, span: codemap::span,
+pub fn maybe_print_trailing_comment(s: @ps, span: codemap::span,
                                     next_pos: Option<BytePos>) {
     let mut cm;
     match s.cm { Some(ccm) => cm = ccm, _ => return }
@@ -1975,26 +1987,29 @@ pub fn maybe_print_trailing_comment(s: ps, span: codemap::span,
         if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
                span_line.line == comment_line.line {
             print_comment(s, (*cmnt));
-            s.cur_cmnt += 1u;
+            s.cur_cmnt_and_lit.cur_cmnt += 1u;
         }
       }
       _ => ()
     }
 }
 
-pub fn print_remaining_comments(s: ps) {
+pub fn print_remaining_comments(s: @ps) {
     // If there aren't any remaining comments, then we need to manually
     // make sure there is a line break at the end.
     if next_comment(s).is_none() { hardbreak(s.s); }
     loop {
         match next_comment(s) {
-          Some(ref cmnt) => { print_comment(s, (*cmnt)); s.cur_cmnt += 1u; }
+          Some(ref cmnt) => {
+            print_comment(s, (*cmnt));
+            s.cur_cmnt_and_lit.cur_cmnt += 1u;
+          }
           _ => break
         }
     }
 }
 
-pub fn print_literal(s: ps, &&lit: @ast::lit) {
+pub fn print_literal(s: @ps, &&lit: @ast::lit) {
     maybe_print_comment(s, lit.span.lo);
     match next_lit(s, lit.span.lo) {
       Some(ref ltrl) => {
@@ -2046,13 +2061,13 @@ pub fn lit_to_str(l: @ast::lit) -> ~str {
     return to_str(l, print_literal, parse::token::mk_fake_ident_interner());
 }
 
-pub fn next_lit(s: ps, pos: BytePos) -> Option<comments::lit> {
+pub fn next_lit(s: @ps, pos: BytePos) -> Option<comments::lit> {
     match s.literals {
       Some(ref lits) => {
-        while s.cur_lit < vec::len((*lits)) {
-            let ltrl = (*lits)[s.cur_lit];
+        while s.cur_cmnt_and_lit.cur_lit < vec::len((*lits)) {
+            let ltrl = (*lits)[s.cur_cmnt_and_lit.cur_lit];
             if ltrl.pos > pos { return None; }
-            s.cur_lit += 1u;
+            s.cur_cmnt_and_lit.cur_lit += 1u;
             if ltrl.pos == pos { return Some(ltrl); }
         }
         return None;
@@ -2061,13 +2076,13 @@ pub fn next_lit(s: ps, pos: BytePos) -> Option<comments::lit> {
     }
 }
 
-pub fn maybe_print_comment(s: ps, pos: BytePos) {
+pub fn maybe_print_comment(s: @ps, pos: BytePos) {
     loop {
         match next_comment(s) {
           Some(ref cmnt) => {
             if (*cmnt).pos < pos {
                 print_comment(s, (*cmnt));
-                s.cur_cmnt += 1u;
+                s.cur_cmnt_and_lit.cur_cmnt += 1u;
             } else { break; }
           }
           _ => break
@@ -2075,7 +2090,7 @@ pub fn maybe_print_comment(s: ps, pos: BytePos) {
     }
 }
 
-pub fn print_comment(s: ps, cmnt: comments::cmnt) {
+pub fn print_comment(s: @ps, cmnt: comments::cmnt) {
     match cmnt.style {
       comments::mixed => {
         assert (vec::len(cmnt.lines) == 1u);
@@ -2119,13 +2134,13 @@ pub fn print_comment(s: ps, cmnt: comments::cmnt) {
     }
 }
 
-pub fn print_string(s: ps, st: ~str) {
+pub fn print_string(s: @ps, st: ~str) {
     word(s.s, ~"\"");
     word(s.s, str::escape_default(st));
     word(s.s, ~"\"");
 }
 
-pub fn to_str<T>(t: T, f: fn@(ps, T), intr: @ident_interner) -> ~str {
+pub fn to_str<T>(t: T, f: fn@(@ps, T), intr: @ident_interner) -> ~str {
     do io::with_str_writer |wr| {
         let s = rust_printer(wr, intr);
         f(s, t);
@@ -2133,18 +2148,18 @@ pub fn to_str<T>(t: T, f: fn@(ps, T), intr: @ident_interner) -> ~str {
     }
 }
 
-pub fn next_comment(s: ps) -> Option<comments::cmnt> {
+pub fn next_comment(s: @ps) -> Option<comments::cmnt> {
     match s.comments {
       Some(ref cmnts) => {
-        if s.cur_cmnt < vec::len((*cmnts)) {
-            return Some((*cmnts)[s.cur_cmnt]);
+        if s.cur_cmnt_and_lit.cur_cmnt < vec::len((*cmnts)) {
+            return Some((*cmnts)[s.cur_cmnt_and_lit.cur_cmnt]);
         } else { return None::<comments::cmnt>; }
       }
       _ => return None::<comments::cmnt>
     }
 }
 
-pub fn print_self_ty_if_static(s: ps,
+pub fn print_self_ty_if_static(s: @ps,
                                opt_self_ty: Option<ast::self_ty_>) {
     match opt_self_ty {
         Some(ast::sty_static) => { word(s.s, ~"static "); }
@@ -2152,7 +2167,7 @@ pub fn print_self_ty_if_static(s: ps,
     }
 }
 
-pub fn print_opt_purity(s: ps, opt_purity: Option<ast::purity>) {
+pub fn print_opt_purity(s: @ps, opt_purity: Option<ast::purity>) {
     match opt_purity {
         Some(ast::impure_fn) => { }
         Some(purity) => {
@@ -2162,14 +2177,14 @@ pub fn print_opt_purity(s: ps, opt_purity: Option<ast::purity>) {
     }
 }
 
-pub fn print_opt_abi(s: ps, opt_abi: Option<ast::Abi>) {
+pub fn print_opt_abi(s: @ps, opt_abi: Option<ast::Abi>) {
     match opt_abi {
         Some(ast::RustAbi) => { word_nbsp(s, ~"extern"); }
         None => {}
     };
 }
 
-pub fn print_opt_sigil(s: ps, opt_sigil: Option<ast::Sigil>) {
+pub fn print_opt_sigil(s: @ps, opt_sigil: Option<ast::Sigil>) {
     match opt_sigil {
         Some(ast::BorrowedSigil) => { word(s.s, ~"&"); }
         Some(ast::OwnedSigil) => { word(s.s, ~"~"); }
@@ -2178,7 +2193,7 @@ pub fn print_opt_sigil(s: ps, opt_sigil: Option<ast::Sigil>) {
     };
 }
 
-pub fn print_fn_header_info(s: ps,
+pub fn print_fn_header_info(s: @ps,
                             opt_sty: Option<ast::self_ty_>,
                             opt_purity: Option<ast::purity>,
                             onceness: ast::Onceness,
@@ -2215,14 +2230,14 @@ pub pure fn onceness_to_str(o: ast::Onceness) -> ~str {
     }
 }
 
-pub fn print_purity(s: ps, p: ast::purity) {
+pub fn print_purity(s: @ps, p: ast::purity) {
     match p {
       ast::impure_fn => (),
       _ => word_nbsp(s, purity_to_str(p))
     }
 }
 
-pub fn print_onceness(s: ps, o: ast::Onceness) {
+pub fn print_onceness(s: @ps, o: ast::Onceness) {
     match o {
         ast::Once => { word_nbsp(s, ~"once"); }
         ast::Many => {}