about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-21 10:43:17 -0700
committerbors <bors@rust-lang.org>2013-05-21 10:43:17 -0700
commit64963d6cbaea86e0d2a58f507e57a76da7512e3e (patch)
tree96dfdb86aaa32e4131710cb71507ddd3b9aa752f /src/libsyntax
parent808aada1fb95133f9e9e78be70ad805c0fee4b9c (diff)
parenta59bec43e34715880f471db7d7c9d57939649d92 (diff)
downloadrust-64963d6cbaea86e0d2a58f507e57a76da7512e3e.tar.gz
rust-64963d6cbaea86e0d2a58f507e57a76da7512e3e.zip
auto merge of #6611 : huonw/rust/syntax-ext-no-dup, r=jbclements
Fixes https://github.com/mozilla/rust/issues/6578 by merging the 3 different ways to build an AST into a single `AstBuilder` trait, creating a more uniform and briefer interface.

Also, converts the `ext_ctxt` trait-object to be a plain struct, as well as renaming it to `ExtCtxt`.

Seems to make expansion slightly faster for the normal case (e.g. `libcore` and `libstd`), but slower for `librustc` (slightly) and `libsyntax` (0.3s -> 0.8s! I'm investigating this, but I'd prefer this patch to land relatively quickly.).

`git blame` suggests maybe @graydon or @erickt are familiar with this area of the code. r?
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/asm.rs2
-rw-r--r--src/libsyntax/ext/auto_encode.rs4
-rw-r--r--src/libsyntax/ext/base.rs213
-rw-r--r--src/libsyntax/ext/build.rs1462
-rw-r--r--src/libsyntax/ext/bytes.rs14
-rw-r--r--src/libsyntax/ext/concat_idents.rs2
-rw-r--r--src/libsyntax/ext/deriving/clone.rs34
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs22
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs51
-rw-r--r--src/libsyntax/ext/deriving/cmp/totaleq.rs16
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs35
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs252
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs200
-rw-r--r--src/libsyntax/ext/deriving/generic.rs122
-rw-r--r--src/libsyntax/ext/deriving/iter_bytes.rs24
-rw-r--r--src/libsyntax/ext/deriving/mod.rs132
-rw-r--r--src/libsyntax/ext/deriving/rand.rs73
-rw-r--r--src/libsyntax/ext/deriving/to_str.rs26
-rw-r--r--src/libsyntax/ext/deriving/ty.rs127
-rw-r--r--src/libsyntax/ext/env.rs8
-rw-r--r--src/libsyntax/ext/expand.rs16
-rw-r--r--src/libsyntax/ext/fmt.rs91
-rw-r--r--src/libsyntax/ext/log_syntax.rs2
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs384
-rw-r--r--src/libsyntax/ext/pipes/check.rs4
-rw-r--r--src/libsyntax/ext/pipes/liveness.rs4
-rw-r--r--src/libsyntax/ext/pipes/mod.rs4
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs168
-rw-r--r--src/libsyntax/ext/pipes/proto.rs9
-rw-r--r--src/libsyntax/ext/quote.rs352
-rw-r--r--src/libsyntax/ext/source_util.rs36
-rw-r--r--src/libsyntax/ext/trace_macros.rs4
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs8
33 files changed, 1659 insertions, 2242 deletions
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs
index 97c5797cf57..162eced1124 100644
--- a/src/libsyntax/ext/asm.rs
+++ b/src/libsyntax/ext/asm.rs
@@ -37,7 +37,7 @@ fn next_state(s: State) -> Option<State> {
     }
 }
 
-pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_asm(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
                -> base::MacResult {
     let p = parse::new_parser_from_tts(cx.parse_sess(),
                                        cx.cfg(),
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 6bb3ac5eba4..64d2644b383 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -15,7 +15,7 @@ use codemap::span;
 use ext::base::*;
 
 pub fn expand_auto_encode(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     _mitem: @ast::meta_item,
     in_items: ~[@ast::item]
@@ -25,7 +25,7 @@ pub fn expand_auto_encode(
 }
 
 pub fn expand_auto_decode(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     _mitem: @ast::meta_item,
     in_items: ~[@ast::item]
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 2a7f8c8865b..9b71fb9647c 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -33,7 +33,7 @@ pub struct MacroDef {
     ext: SyntaxExtension
 }
 
-pub type ItemDecorator = @fn(@ext_ctxt,
+pub type ItemDecorator = @fn(@ExtCtxt,
                              span,
                              @ast::meta_item,
                              ~[@ast::item])
@@ -44,7 +44,7 @@ pub struct SyntaxExpanderTT {
     span: Option<span>
 }
 
-pub type SyntaxExpanderTTFun = @fn(@ext_ctxt,
+pub type SyntaxExpanderTTFun = @fn(@ExtCtxt,
                                    span,
                                    &[ast::token_tree])
                                 -> MacResult;
@@ -54,7 +54,7 @@ pub struct SyntaxExpanderTTItem {
     span: Option<span>
 }
 
-pub type SyntaxExpanderTTItemFun = @fn(@ext_ctxt,
+pub type SyntaxExpanderTTItemFun = @fn(@ExtCtxt,
                                        span,
                                        ast::ident,
                                        ~[ast::token_tree])
@@ -202,134 +202,109 @@ pub fn syntax_expander_table() -> SyntaxEnv {
 // One of these is made during expansion and incrementally updated as we go;
 // 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(&self) -> @CodeMap;
-    fn parse_sess(&self) -> @mut parse::ParseSess;
-    fn cfg(&self) -> ast::crate_cfg;
-    fn call_site(&self) -> span;
-    fn print_backtrace(&self);
-    fn backtrace(&self) -> Option<@ExpnInfo>;
-    fn mod_push(&self, mod_name: ast::ident);
-    fn mod_pop(&self);
-    fn mod_path(&self) -> ~[ast::ident];
-    fn bt_push(&self, ei: codemap::ExpnInfo);
-    fn bt_pop(&self);
-    fn span_fatal(&self, sp: span, msg: &str) -> !;
-    fn span_err(&self, sp: span, msg: &str);
-    fn span_warn(&self, sp: span, msg: &str);
-    fn span_unimpl(&self, sp: span, msg: &str) -> !;
-    fn span_bug(&self, sp: span, msg: &str) -> !;
-    fn bug(&self, msg: &str) -> !;
-    fn next_id(&self) -> ast::node_id;
-    fn trace_macros(&self) -> bool;
-    fn set_trace_macros(&self, x: bool);
-    /* for unhygienic identifier transformation */
-    fn str_of(&self, id: ast::ident) -> ~str;
-    fn ident_of(&self, st: &str) -> ast::ident;
+pub struct ExtCtxt {
+    parse_sess: @mut parse::ParseSess,
+    cfg: ast::crate_cfg,
+    backtrace: @mut Option<@ExpnInfo>,
+
+    // These two @mut's should really not be here,
+    // but the self types for CtxtRepr are all wrong
+    // and there are bugs in the code for object
+    // types that make this hard to get right at the
+    // moment. - nmatsakis
+    mod_path: @mut ~[ast::ident],
+    trace_mac: @mut bool
 }
 
-pub fn mk_ctxt(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg)
-            -> @ext_ctxt {
-    struct CtxtRepr {
-        parse_sess: @mut parse::ParseSess,
-        cfg: ast::crate_cfg,
-        backtrace: @mut Option<@ExpnInfo>,
-
-        // These two @mut's should really not be here,
-        // but the self types for CtxtRepr are all wrong
-        // and there are bugs in the code for object
-        // types that make this hard to get right at the
-        // moment. - nmatsakis
-        mod_path: @mut ~[ast::ident],
-        trace_mac: @mut bool
-    }
-    impl ext_ctxt for CtxtRepr {
-        fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
-        fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
-        fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
-        fn call_site(&self) -> span {
-            match *self.backtrace {
-                Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
-                None => self.bug("missing top span")
-            }
+pub impl ExtCtxt {
+    fn new(parse_sess: @mut parse::ParseSess, cfg: ast::crate_cfg) -> @ExtCtxt {
+        @ExtCtxt {
+            parse_sess: parse_sess,
+            cfg: cfg,
+            backtrace: @mut None,
+            mod_path: @mut ~[],
+            trace_mac: @mut false
+        }
+    }
+
+    fn codemap(&self) -> @CodeMap { self.parse_sess.cm }
+    fn parse_sess(&self) -> @mut parse::ParseSess { self.parse_sess }
+    fn cfg(&self) -> ast::crate_cfg { copy self.cfg }
+    fn call_site(&self) -> span {
+        match *self.backtrace {
+            Some(@ExpandedFrom(CallInfo {call_site: cs, _})) => cs,
+            None => self.bug("missing top span")
         }
-        fn print_backtrace(&self) { }
-        fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
-        fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
-        fn mod_pop(&self) { self.mod_path.pop(); }
-        fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
-        fn bt_push(&self, ei: codemap::ExpnInfo) {
-            match ei {
-              ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
+    }
+    fn print_backtrace(&self) { }
+    fn backtrace(&self) -> Option<@ExpnInfo> { *self.backtrace }
+    fn mod_push(&self, i: ast::ident) { self.mod_path.push(i); }
+    fn mod_pop(&self) { self.mod_path.pop(); }
+    fn mod_path(&self) -> ~[ast::ident] { copy *self.mod_path }
+    fn bt_push(&self, ei: codemap::ExpnInfo) {
+        match ei {
+            ExpandedFrom(CallInfo {call_site: cs, callee: ref callee}) => {
                 *self.backtrace =
                     Some(@ExpandedFrom(CallInfo {
                         call_site: span {lo: cs.lo, hi: cs.hi,
                                          expn_info: *self.backtrace},
                         callee: copy *callee}));
-              }
             }
         }
-        fn bt_pop(&self) {
-            match *self.backtrace {
-              Some(@ExpandedFrom(CallInfo {
-                  call_site: span {expn_info: prev, _}, _
-              })) => {
+    }
+    fn bt_pop(&self) {
+        match *self.backtrace {
+            Some(@ExpandedFrom(
+                CallInfo {
+                    call_site: span {expn_info: prev, _}, _
+                })) => {
                 *self.backtrace = prev
-              }
-              _ => self.bug("tried to pop without a push")
             }
+            _ => self.bug("tried to pop without a push")
         }
-        fn span_fatal(&self, sp: span, msg: &str) -> ! {
-            self.print_backtrace();
-            self.parse_sess.span_diagnostic.span_fatal(sp, msg);
-        }
-        fn span_err(&self, sp: span, msg: &str) {
-            self.print_backtrace();
-            self.parse_sess.span_diagnostic.span_err(sp, msg);
-        }
-        fn span_warn(&self, sp: span, msg: &str) {
-            self.print_backtrace();
-            self.parse_sess.span_diagnostic.span_warn(sp, msg);
-        }
-        fn span_unimpl(&self, sp: span, msg: &str) -> ! {
-            self.print_backtrace();
-            self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
-        }
-        fn span_bug(&self, sp: span, msg: &str) -> ! {
-            self.print_backtrace();
-            self.parse_sess.span_diagnostic.span_bug(sp, msg);
-        }
-        fn bug(&self, msg: &str) -> ! {
-            self.print_backtrace();
-            self.parse_sess.span_diagnostic.handler().bug(msg);
-        }
-        fn next_id(&self) -> ast::node_id {
-            return parse::next_node_id(self.parse_sess);
-        }
-        fn trace_macros(&self) -> bool {
-            *self.trace_mac
-        }
-        fn set_trace_macros(&self, x: bool) {
-            *self.trace_mac = x
-        }
-        fn str_of(&self, id: ast::ident) -> ~str {
-            copy *self.parse_sess.interner.get(id)
-        }
-        fn ident_of(&self, st: &str) -> ast::ident {
-            self.parse_sess.interner.intern(st)
-        }
     }
-    let imp: @CtxtRepr = @CtxtRepr {
-        parse_sess: parse_sess,
-        cfg: cfg,
-        backtrace: @mut None,
-        mod_path: @mut ~[],
-        trace_mac: @mut false
-    };
-    ((imp) as @ext_ctxt)
+    fn span_fatal(&self, sp: span, msg: &str) -> ! {
+        self.print_backtrace();
+        self.parse_sess.span_diagnostic.span_fatal(sp, msg);
+    }
+    fn span_err(&self, sp: span, msg: &str) {
+        self.print_backtrace();
+        self.parse_sess.span_diagnostic.span_err(sp, msg);
+    }
+    fn span_warn(&self, sp: span, msg: &str) {
+        self.print_backtrace();
+        self.parse_sess.span_diagnostic.span_warn(sp, msg);
+    }
+    fn span_unimpl(&self, sp: span, msg: &str) -> ! {
+        self.print_backtrace();
+        self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
+    }
+    fn span_bug(&self, sp: span, msg: &str) -> ! {
+        self.print_backtrace();
+        self.parse_sess.span_diagnostic.span_bug(sp, msg);
+    }
+    fn bug(&self, msg: &str) -> ! {
+        self.print_backtrace();
+        self.parse_sess.span_diagnostic.handler().bug(msg);
+    }
+    fn next_id(&self) -> ast::node_id {
+        parse::next_node_id(self.parse_sess)
+    }
+    fn trace_macros(&self) -> bool {
+        *self.trace_mac
+    }
+    fn set_trace_macros(&self, x: bool) {
+        *self.trace_mac = x
+    }
+    fn str_of(&self, id: ast::ident) -> ~str {
+        copy *self.parse_sess.interner.get(id)
+    }
+    fn ident_of(&self, st: &str) -> ast::ident {
+        self.parse_sess.interner.intern(st)
+    }
 }
 
-pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
+pub fn expr_to_str(cx: @ExtCtxt, expr: @ast::expr, err_msg: ~str) -> ~str {
     match expr.node {
       ast::expr_lit(l) => match l.node {
         ast::lit_str(s) => copy *s,
@@ -339,7 +314,7 @@ pub fn expr_to_str(cx: @ext_ctxt, expr: @ast::expr, err_msg: ~str) -> ~str {
     }
 }
 
-pub fn expr_to_ident(cx: @ext_ctxt,
+pub fn expr_to_ident(cx: @ExtCtxt,
                      expr: @ast::expr,
                      err_msg: &str) -> ast::ident {
     match expr.node {
@@ -353,14 +328,14 @@ pub fn expr_to_ident(cx: @ext_ctxt,
     }
 }
 
-pub fn check_zero_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree],
+pub fn check_zero_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree],
                       name: &str) {
     if tts.len() != 0 {
         cx.span_fatal(sp, fmt!("%s takes no arguments", name));
     }
 }
 
-pub fn get_single_str_from_tts(cx: @ext_ctxt,
+pub fn get_single_str_from_tts(cx: @ExtCtxt,
                                sp: span,
                                tts: &[ast::token_tree],
                                name: &str) -> ~str {
@@ -375,7 +350,7 @@ pub fn get_single_str_from_tts(cx: @ext_ctxt,
     }
 }
 
-pub fn get_exprs_from_tts(cx: @ext_ctxt, tts: &[ast::token_tree])
+pub fn get_exprs_from_tts(cx: @ExtCtxt, tts: &[ast::token_tree])
                        -> ~[@ast::expr] {
     let p = parse::new_parser_from_tts(cx.parse_sess(),
                                        cx.cfg(),
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 624e0495e59..01a504101b9 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -8,13 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use abi::AbiSet;
+use ast::ident;
 use ast;
-use codemap;
-use codemap::span;
+use ast_util;
+use codemap::{span, respan, dummy_sp};
 use fold;
-use ext::base::ext_ctxt;
-use ext::build;
-
+use ext::base::ExtCtxt;
+use ext::quote::rt::*;
+use opt_vec;
 use opt_vec::OptVec;
 
 pub struct Field {
@@ -22,601 +24,389 @@ pub struct Field {
     ex: @ast::expr
 }
 
-pub fn mk_expr(cx: @ext_ctxt,
-               sp: codemap::span,
-               expr: ast::expr_)
-            -> @ast::expr {
-    @ast::expr {
-        id: cx.next_id(),
-        callee_id: cx.next_id(),
-        node: expr,
-        span: sp,
-    }
+// Transitional reexports so qquote can find the paths it is looking for
+mod syntax {
+    pub use ext;
+    pub use parse;
 }
 
-pub fn mk_lit(cx: @ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
-    let sp_lit = @codemap::spanned { node: lit, span: sp };
-    mk_expr(cx, sp, ast::expr_lit(sp_lit))
-}
-pub fn mk_int(cx: @ext_ctxt, sp: span, i: int) -> @ast::expr {
-    let lit = ast::lit_int(i as i64, ast::ty_i);
-    return mk_lit(cx, sp, lit);
-}
-pub fn mk_uint(cx: @ext_ctxt, sp: span, u: uint) -> @ast::expr {
-    let lit = ast::lit_uint(u as u64, ast::ty_u);
-    return mk_lit(cx, sp, lit);
-}
-pub fn mk_u8(cx: @ext_ctxt, sp: span, u: u8) -> @ast::expr {
-    let lit = ast::lit_uint(u as u64, ast::ty_u8);
-    return mk_lit(cx, sp, lit);
-}
-pub fn mk_binary(cx: @ext_ctxt, sp: span, op: ast::binop,
-                 lhs: @ast::expr, rhs: @ast::expr) -> @ast::expr {
-    cx.next_id(); // see ast_util::op_expr_callee_id
-    mk_expr(cx, sp, ast::expr_binary(op, lhs, rhs))
-}
+pub trait AstBuilder {
+    // paths
+    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
+    fn path_ident(&self, span: span, id: ast::ident) -> @ast::Path;
+    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
+    fn path_all(&self, sp: span,
+                global: bool,
+                idents: ~[ast::ident],
+                rp: Option<@ast::Lifetime>,
+                types: ~[@ast::Ty])
+        -> @ast::Path;
+
+    // types
+    fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt;
+
+    fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty;
+    fn ty_path(&self, @ast::Path) -> @ast::Ty;
+    fn ty_ident(&self, span: span, idents: ast::ident) -> @ast::Ty;
+
+    fn ty_rptr(&self, span: span,
+               ty: @ast::Ty,
+               lifetime: Option<@ast::Lifetime>,
+               mutbl: ast::mutability)
+        -> @ast::Ty;
+    fn ty_uniq(&self, span: span, ty: @ast::Ty) -> @ast::Ty;
+    fn ty_box(&self, span: span, ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty;
+
+    fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty;
+    fn ty_infer(&self, sp: span) -> @ast::Ty;
+    fn ty_nil(&self) -> @ast::Ty;
+
+    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
+    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
+    fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field;
+    fn strip_bounds(&self, bounds: &Generics) -> Generics;
+
+    fn typaram(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>) -> ast::TyParam;
+
+    fn trait_ref(&self, path: @ast::Path) -> @ast::trait_ref;
+    fn typarambound(&self, path: @ast::Path) -> ast::TyParamBound;
+    fn lifetime(&self, span: span, ident: ast::ident) -> ast::Lifetime;
+
+    // statements
+    fn stmt_expr(&self, expr: @ast::expr) -> @ast::stmt;
+    fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt;
+
+    // blocks
+    fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk;
+    fn blk_expr(&self, expr: @ast::expr) -> ast::blk;
+    fn blk_all(&self, span: span,
+               view_items: ~[@ast::view_item],
+               stmts: ~[@ast::stmt],
+               expr: Option<@ast::expr>) -> ast::blk;
+
+    // expressions
+    fn expr(&self, span: span, node: ast::expr_) -> @ast::expr;
+    fn expr_path(&self, path: @ast::Path) -> @ast::expr;
+    fn expr_ident(&self, span: span, id: ast::ident) -> @ast::expr;
 
-pub fn mk_deref(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
-    mk_unary(cx, sp, ast::deref, e)
-}
-pub fn mk_unary(cx: @ext_ctxt, sp: span, op: ast::unop, e: @ast::expr)
-             -> @ast::expr {
-    cx.next_id(); // see ast_util::op_expr_callee_id
-    mk_expr(cx, sp, ast::expr_unary(op, e))
-}
-pub fn mk_raw_path(sp: span, idents: ~[ast::ident]) -> @ast::Path {
-    mk_raw_path_(sp, idents, None, ~[])
-}
-pub fn mk_raw_path_(sp: span,
-                    idents: ~[ast::ident],
-                    rp: Option<@ast::Lifetime>,
-                    types: ~[@ast::Ty])
-                 -> @ast::Path {
-    @ast::Path { span: sp,
-                 global: false,
-                 idents: idents,
-                 rp: rp,
-                 types: types }
-}
-pub fn mk_raw_path_global(sp: span, idents: ~[ast::ident]) -> @ast::Path {
-    mk_raw_path_global_(sp, idents, None, ~[])
-}
-pub fn mk_raw_path_global_(sp: span,
-                           idents: ~[ast::ident],
-                           rp: Option<@ast::Lifetime>,
-                           types: ~[@ast::Ty]) -> @ast::Path {
-    @ast::Path { span: sp,
-                 global: true,
-                 idents: idents,
-                 rp: rp,
-                 types: types }
-}
-pub fn mk_path_raw(cx: @ext_ctxt, sp: span, path: @ast::Path)-> @ast::expr {
-    mk_expr(cx, sp, ast::expr_path(path))
-}
-pub fn mk_path(cx: @ext_ctxt, sp: span, idents: ~[ast::ident])
-            -> @ast::expr {
-    mk_path_raw(cx, sp, mk_raw_path(sp, idents))
-}
-pub fn mk_path_global(cx: @ext_ctxt, sp: span, idents: ~[ast::ident])
-                   -> @ast::expr {
-    mk_path_raw(cx, sp, mk_raw_path_global(sp, idents))
-}
-pub fn mk_access_(cx: @ext_ctxt, sp: span, p: @ast::expr, m: ast::ident)
-               -> @ast::expr {
-    mk_expr(cx, sp, ast::expr_field(p, m, ~[]))
-}
-pub fn mk_access(cx: @ext_ctxt, sp: span, p: ~[ast::ident], m: ast::ident)
-              -> @ast::expr {
-    let pathexpr = mk_path(cx, sp, p);
-    return mk_access_(cx, sp, pathexpr, m);
-}
-pub fn mk_addr_of(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
-    return mk_expr(cx, sp, ast::expr_addr_of(ast::m_imm, e));
-}
-pub fn mk_mut_addr_of(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
-    return mk_expr(cx, sp, ast::expr_addr_of(ast::m_mutbl, e));
-}
-pub fn mk_method_call(cx: @ext_ctxt,
-                      sp: span,
-                      rcvr_expr: @ast::expr,
-                      method_ident: ast::ident,
-                      args: ~[@ast::expr]) -> @ast::expr {
-    mk_expr(cx, sp, ast::expr_method_call(rcvr_expr, method_ident, ~[], args, ast::NoSugar))
-}
-pub fn mk_call_(cx: @ext_ctxt, sp: span, fn_expr: @ast::expr,
-                args: ~[@ast::expr]) -> @ast::expr {
-    mk_expr(cx, sp, ast::expr_call(fn_expr, args, ast::NoSugar))
-}
-pub fn mk_call(cx: @ext_ctxt, sp: span, fn_path: ~[ast::ident],
-               args: ~[@ast::expr]) -> @ast::expr {
-    let pathexpr = mk_path(cx, sp, fn_path);
-    return mk_call_(cx, sp, pathexpr, args);
-}
-pub fn mk_call_global(cx: @ext_ctxt, sp: span, fn_path: ~[ast::ident],
-                      args: ~[@ast::expr]) -> @ast::expr {
-    let pathexpr = mk_path_global(cx, sp, fn_path);
-    return mk_call_(cx, sp, pathexpr, args);
-}
-// e = expr, t = type
-pub fn mk_base_vec_e(cx: @ext_ctxt, sp: span, exprs: ~[@ast::expr])
-                  -> @ast::expr {
-    let vecexpr = ast::expr_vec(exprs, ast::m_imm);
-    mk_expr(cx, sp, vecexpr)
-}
-pub fn mk_vstore_e(cx: @ext_ctxt, sp: span, expr: @ast::expr,
-                   vst: ast::expr_vstore) ->
-   @ast::expr {
-    mk_expr(cx, sp, ast::expr_vstore(expr, vst))
-}
-pub fn mk_uniq_vec_e(cx: @ext_ctxt, sp: span, exprs: ~[@ast::expr])
-                  -> @ast::expr {
-    mk_vstore_e(cx, sp, mk_base_vec_e(cx, sp, exprs), ast::expr_vstore_uniq)
-}
-pub fn mk_slice_vec_e(cx: @ext_ctxt, sp: span, exprs: ~[@ast::expr])
-                   -> @ast::expr {
-    mk_vstore_e(cx, sp, mk_base_vec_e(cx, sp, exprs),
-                ast::expr_vstore_slice)
-}
-pub fn mk_base_str(cx: @ext_ctxt, sp: span, s: ~str) -> @ast::expr {
-    let lit = ast::lit_str(@s);
-    return mk_lit(cx, sp, lit);
-}
-pub fn mk_uniq_str(cx: @ext_ctxt, sp: span, s: ~str) -> @ast::expr {
-    mk_vstore_e(cx, sp, mk_base_str(cx, sp, s), ast::expr_vstore_uniq)
+    fn expr_self(&self, span: span) -> @ast::expr;
+    fn expr_binary(&self, sp: span, op: ast::binop,
+                   lhs: @ast::expr, rhs: @ast::expr) -> @ast::expr;
+    fn expr_deref(&self, sp: span, e: @ast::expr) -> @ast::expr;
+    fn expr_unary(&self, sp: span, op: ast::unop, e: @ast::expr) -> @ast::expr;
+
+    fn expr_copy(&self, sp: span, e: @ast::expr) -> @ast::expr;
+    fn expr_managed(&self, sp: span, e: @ast::expr) -> @ast::expr;
+    fn expr_addr_of(&self, sp: span, e: @ast::expr) -> @ast::expr;
+    fn expr_mut_addr_of(&self, sp: span, e: @ast::expr) -> @ast::expr;
+    fn expr_field_access(&self, span: span, expr: @ast::expr, ident: ast::ident) -> @ast::expr;
+    fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr]) -> @ast::expr;
+    fn expr_call_ident(&self, span: span, id: ast::ident, args: ~[@ast::expr]) -> @ast::expr;
+    fn expr_call_global(&self, sp: span, fn_path: ~[ast::ident],
+                        args: ~[@ast::expr]) -> @ast::expr;
+    fn expr_method_call(&self, span: span,
+                        expr: @ast::expr, ident: ast::ident,
+                        args: ~[@ast::expr]) -> @ast::expr;
+    fn expr_blk(&self, b: ast::blk) -> @ast::expr;
+
+    fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field;
+    fn expr_struct(&self, span: span, path: @ast::Path, fields: ~[ast::field]) -> @ast::expr;
+    fn expr_struct_ident(&self, span: span, id: ast::ident, fields: ~[ast::field]) -> @ast::expr;
+
+    fn expr_lit(&self, sp: span, lit: ast::lit_) -> @ast::expr;
+
+    fn expr_uint(&self, span: span, i: uint) -> @ast::expr;
+    fn expr_int(&self, sp: span, i: int) -> @ast::expr;
+    fn expr_u8(&self, sp: span, u: u8) -> @ast::expr;
+    fn expr_bool(&self, sp: span, value: bool) -> @ast::expr;
+
+    fn expr_vstore(&self, sp: span, expr: @ast::expr, vst: ast::expr_vstore) -> @ast::expr;
+    fn expr_vec(&self, sp: span, exprs: ~[@ast::expr]) -> @ast::expr;
+    fn expr_vec_uniq(&self, sp: span, exprs: ~[@ast::expr]) -> @ast::expr;
+    fn expr_vec_slice(&self, sp: span, exprs: ~[@ast::expr]) -> @ast::expr;
+    fn expr_str(&self, sp: span, s: ~str) -> @ast::expr;
+    fn expr_str_uniq(&self, sp: span, s: ~str) -> @ast::expr;
+
+    fn expr_unreachable(&self, span: span) -> @ast::expr;
+
+    fn pat(&self, span: span, pat: ast::pat_) -> @ast::pat;
+    fn pat_wild(&self, span: span) -> @ast::pat;
+    fn pat_lit(&self, span: span, expr: @ast::expr) -> @ast::pat;
+    fn pat_ident(&self, span: span, ident: ast::ident) -> @ast::pat;
+
+    fn pat_ident_binding_mode(&self,
+                              span: span,
+                              ident: ast::ident,
+                              bm: ast::binding_mode) -> @ast::pat;
+    fn pat_enum(&self, span: span, path: @ast::Path, subpats: ~[@ast::pat]) -> @ast::pat;
+    fn pat_struct(&self, span: span,
+                  path: @ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat;
+
+    fn arm(&self, span: span, pats: ~[@ast::pat], expr: @ast::expr) -> ast::arm;
+    fn arm_unreachable(&self, span: span) -> ast::arm;
+
+    fn expr_match(&self, span: span, arg: @ast::expr, arms: ~[ast::arm]) -> @ast::expr;
+    fn expr_if(&self, span: span,
+               cond: @ast::expr, then: @ast::expr, els: Option<@ast::expr>) -> @ast::expr;
+
+    fn lambda_fn_decl(&self, span: span, fn_decl: ast::fn_decl, blk: ast::blk) -> @ast::expr;
+
+    fn lambda(&self, span: span, ids: ~[ast::ident], blk: ast::blk) -> @ast::expr;
+    fn lambda0(&self, span: span, blk: ast::blk) -> @ast::expr;
+    fn lambda1(&self, span: span, blk: ast::blk, ident: ast::ident) -> @ast::expr;
+
+    fn lambda_expr(&self, span: span, ids: ~[ast::ident], blk: @ast::expr) -> @ast::expr;
+    fn lambda_expr_0(&self, span: span, expr: @ast::expr) -> @ast::expr;
+    fn lambda_expr_1(&self, span: span, expr: @ast::expr, ident: ast::ident) -> @ast::expr;
+
+    fn lambda_stmts(&self, span: span, ids: ~[ast::ident], blk: ~[@ast::stmt]) -> @ast::expr;
+    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr;
+    fn lambda_stmts_1(&self, span: span, stmts: ~[@ast::stmt], ident: ast::ident) -> @ast::expr;
+
+    // items
+    fn item(&self, span: span,
+            name: ident, attrs: ~[ast::attribute], node: ast::item_) -> @ast::item;
+
+    fn arg(&self, span: span, name: ident, ty: @ast::Ty) -> ast::arg;
+    // XXX unused self
+    fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl;
+
+    fn item_fn_poly(&self,
+                    span: span,
+                    name: ident,
+                    inputs: ~[ast::arg],
+                    output: @ast::Ty,
+                    generics: Generics,
+                    body: ast::blk) -> @ast::item;
+    fn item_fn(&self,
+               span: span,
+               name: ident,
+               inputs: ~[ast::arg],
+               output: @ast::Ty,
+               body: ast::blk) -> @ast::item;
+
+    fn variant(&self, span: span, name: ident, tys: ~[@ast::Ty]) -> ast::variant;
+    fn item_enum_poly(&self,
+                      span: span,
+                      name: ident,
+                      enum_definition: ast::enum_def,
+                      generics: Generics) -> @ast::item;
+    fn item_enum(&self, span: span, name: ident, enum_def: ast::enum_def) -> @ast::item;
+
+    fn item_struct_poly(&self,
+                        span: span,
+                        name: ident,
+                        struct_def: ast::struct_def,
+                        generics: Generics) -> @ast::item;
+    fn item_struct(&self, span: span, name: ident, struct_def: ast::struct_def) -> @ast::item;
+
+    fn item_mod(&self, span: span,
+                name: ident, attrs: ~[ast::attribute],
+                vi: ~[@ast::view_item], items: ~[@ast::item]) -> @ast::item;
+
+    fn item_ty_poly(&self,
+                    span: span,
+                    name: ident,
+                    ty: @ast::Ty,
+                    generics: Generics) -> @ast::item;
+    fn item_ty(&self, span: span, name: ident, ty: @ast::Ty) -> @ast::item;
+
+    fn attribute(&self, sp: span, mi: @ast::meta_item) -> ast::attribute;
+
+    fn meta_word(&self, sp: span, w: ~str) -> @ast::meta_item;
+    fn meta_list(&self, sp: span, name: ~str, mis: ~[@ast::meta_item]) -> @ast::meta_item;
+    fn meta_name_value(&self, sp: span, name: ~str, value: ast::lit_) -> @ast::meta_item;
+
+    fn view_use(&self, sp: span,
+                vis: ast::visibility, vp: ~[@ast::view_path]) -> @ast::view_item;
+    fn view_use_list(&self, sp: span, vis: ast::visibility,
+                     path: ~[ast::ident], imports: &[ast::ident]) -> @ast::view_item;
+    fn view_use_glob(&self, sp: span,
+                     vis: ast::visibility, path: ~[ast::ident]) -> @ast::view_item;
 }
-pub fn mk_field(sp: span, f: &Field) -> ast::field {
-    codemap::spanned {
-        node: ast::field_ { mutbl: ast::m_imm, ident: f.ident, expr: f.ex },
-        span: sp,
+
+impl AstBuilder for @ExtCtxt {
+    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
+        self.path_all(span, false, strs, None, ~[])
     }
-}
-pub fn mk_fields(sp: span, fields: ~[Field]) -> ~[ast::field] {
-    fields.map(|f| mk_field(sp, f))
-}
-pub fn mk_struct_e(cx: @ext_ctxt,
-                   sp: span,
-                   ctor_path: ~[ast::ident],
-                   fields: ~[Field])
-                -> @ast::expr {
-    mk_expr(cx, sp,
-            ast::expr_struct(mk_raw_path(sp, ctor_path),
-                             mk_fields(sp, fields),
-                                    option::None::<@ast::expr>))
-}
-pub fn mk_global_struct_e(cx: @ext_ctxt,
-                          sp: span,
-                          ctor_path: ~[ast::ident],
-                          fields: ~[Field])
-                       -> @ast::expr {
-    mk_expr(cx, sp,
-            ast::expr_struct(mk_raw_path_global(sp, ctor_path),
-                             mk_fields(sp, fields),
-                                    option::None::<@ast::expr>))
-}
-pub fn mk_glob_use(cx: @ext_ctxt,
-                   sp: span,
-                   vis: ast::visibility,
-                   path: ~[ast::ident]) -> @ast::view_item {
-    let glob = @codemap::spanned {
-        node: ast::view_path_glob(mk_raw_path(sp, path), cx.next_id()),
-        span: sp,
-    };
-    @ast::view_item { node: ast::view_item_use(~[glob]),
-                      attrs: ~[],
-                      vis: vis,
-                      span: sp }
-}
-pub fn mk_local(cx: @ext_ctxt, sp: span, mutbl: bool,
-                ident: ast::ident, ex: @ast::expr) -> @ast::stmt {
-
-    let pat = @ast::pat {
-        id: cx.next_id(),
-        node: ast::pat_ident(
-            ast::bind_by_copy,
-            mk_raw_path(sp, ~[ident]),
-            None),
-        span: sp,
-    };
-    let ty = @ast::Ty { id: cx.next_id(), node: ast::ty_infer, span: sp };
-    let local = @codemap::spanned {
-        node: ast::local_ {
-            is_mutbl: mutbl,
-            ty: ty,
-            pat: pat,
-            init: Some(ex),
-            id: cx.next_id(),
-        },
-        span: sp,
-    };
-    let decl = codemap::spanned {node: ast::decl_local(~[local]), span: sp};
-    @codemap::spanned { node: ast::stmt_decl(@decl, cx.next_id()), span: sp }
-}
-pub fn mk_block(cx: @ext_ctxt, span: span,
-                view_items: ~[@ast::view_item],
-                stmts: ~[@ast::stmt],
-                expr: Option<@ast::expr>) -> @ast::expr {
-    let blk = codemap::spanned {
-        node: ast::blk_ {
-             view_items: view_items,
-             stmts: stmts,
-             expr: expr,
-             id: cx.next_id(),
-             rules: ast::default_blk,
-        },
-        span: span,
-    };
-    mk_expr(cx, span, ast::expr_block(blk))
-}
-pub fn mk_block_(cx: @ext_ctxt,
-                 span: span,
-                 stmts: ~[@ast::stmt])
-              -> ast::blk {
-    codemap::spanned {
-        node: ast::blk_ {
-            view_items: ~[],
-            stmts: stmts,
-            expr: None,
-            id: cx.next_id(),
-            rules: ast::default_blk,
-        },
-        span: span,
+    fn path_ident(&self, span: span, id: ast::ident) -> @ast::Path {
+        self.path(span, ~[id])
     }
-}
-pub fn mk_simple_block(cx: @ext_ctxt,
-                       span: span,
-                       expr: @ast::expr)
-                    -> ast::blk {
-    codemap::spanned {
-        node: ast::blk_ {
-            view_items: ~[],
-            stmts: ~[],
-            expr: Some(expr),
-            id: cx.next_id(),
-            rules: ast::default_blk,
-        },
-        span: span,
+    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
+        self.path_all(span, true, strs, None, ~[])
+    }
+    fn path_all(&self, sp: span,
+                global: bool,
+                idents: ~[ast::ident],
+                rp: Option<@ast::Lifetime>,
+                types: ~[@ast::Ty])
+        -> @ast::Path {
+        @ast::Path {
+            span: sp,
+            global: global,
+            idents: idents,
+            rp: rp,
+            types: types
+        }
     }
-}
-pub fn mk_lambda_(cx: @ext_ctxt,
-                 span: span,
-                 fn_decl: ast::fn_decl,
-                 blk: ast::blk)
-              -> @ast::expr {
-    mk_expr(cx, span, ast::expr_fn_block(fn_decl, blk))
-}
-pub fn mk_lambda(cx: @ext_ctxt,
-                 span: span,
-                 fn_decl: ast::fn_decl,
-                 expr: @ast::expr)
-              -> @ast::expr {
-    let blk = mk_simple_block(cx, span, expr);
-    mk_lambda_(cx, span, fn_decl, blk)
-}
-pub fn mk_lambda_stmts(cx: @ext_ctxt,
-                       span: span,
-                       fn_decl: ast::fn_decl,
-                       stmts: ~[@ast::stmt])
-                    -> @ast::expr {
-    let blk = mk_block(cx, span, ~[], stmts, None);
-    mk_lambda(cx, span, fn_decl, blk)
-}
-pub fn mk_lambda_no_args(cx: @ext_ctxt,
-                         span: span,
-                         expr: @ast::expr)
-                      -> @ast::expr {
-    let fn_decl = mk_fn_decl(~[], mk_ty_infer(cx, span));
-    mk_lambda(cx, span, fn_decl, expr)
-}
-pub fn mk_copy(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
-    mk_expr(cx, sp, ast::expr_copy(e))
-}
-pub fn mk_managed(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
-    mk_expr(cx, sp, ast::expr_unary(ast::box(ast::m_imm), e))
-}
-pub fn mk_pat(cx: @ext_ctxt, span: span, pat: ast::pat_) -> @ast::pat {
-    @ast::pat { id: cx.next_id(), node: pat, span: span }
-}
-pub fn mk_pat_wild(cx: @ext_ctxt, span: span) -> @ast::pat {
-    mk_pat(cx, span, ast::pat_wild)
-}
-pub fn mk_pat_lit(cx: @ext_ctxt,
-                  span: span,
-                  expr: @ast::expr) -> @ast::pat {
-    mk_pat(cx, span, ast::pat_lit(expr))
-}
-pub fn mk_pat_ident(cx: @ext_ctxt,
-                    span: span,
-                    ident: ast::ident) -> @ast::pat {
-    mk_pat_ident_with_binding_mode(cx, span, ident, ast::bind_by_copy)
-}
 
-pub fn mk_pat_ident_with_binding_mode(cx: @ext_ctxt,
-                                      span: span,
-                                      ident: ast::ident,
-                                      bm: ast::binding_mode) -> @ast::pat {
-    let path = mk_raw_path(span, ~[ ident ]);
-    let pat = ast::pat_ident(bm, path, None);
-    mk_pat(cx, span, pat)
-}
-pub fn mk_pat_enum(cx: @ext_ctxt,
-                   span: span,
-                   path: @ast::Path,
-                   subpats: ~[@ast::pat])
-                -> @ast::pat {
-    let pat = ast::pat_enum(path, Some(subpats));
-    mk_pat(cx, span, pat)
-}
-pub fn mk_pat_struct(cx: @ext_ctxt,
-                     span: span,
-                     path: @ast::Path,
-                     field_pats: ~[ast::field_pat])
-                  -> @ast::pat {
-    let pat = ast::pat_struct(path, field_pats, false);
-    mk_pat(cx, span, pat)
-}
-pub fn mk_bool(cx: @ext_ctxt, span: span, value: bool) -> @ast::expr {
-    let lit_expr = ast::expr_lit(@codemap::spanned {
-        node: ast::lit_bool(value),
-        span: span });
-    build::mk_expr(cx, span, lit_expr)
-}
-pub fn mk_stmt(cx: @ext_ctxt, span: span, expr: @ast::expr) -> @ast::stmt {
-    let stmt_ = ast::stmt_semi(expr, cx.next_id());
-    @codemap::spanned { node: stmt_, span: span }
-}
+    fn ty_mt(&self, ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt {
+        ast::mt {
+            ty: ty,
+            mutbl: mutbl
+        }
+    }
 
-pub fn mk_ty_mt(ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt {
-    ast::mt {
-        ty: ty,
-        mutbl: mutbl
+    fn ty(&self, span: span, ty: ast::ty_) -> @ast::Ty {
+        @ast::Ty {
+            id: self.next_id(),
+            span: span,
+            node: ty
+        }
     }
-}
 
-pub fn mk_ty(cx: @ext_ctxt,
-             span: span,
-             ty: ast::ty_) -> @ast::Ty {
-    @ast::Ty {
-        id: cx.next_id(),
-        span: span,
-        node: ty
+    fn ty_path(&self, path: @ast::Path) -> @ast::Ty {
+        self.ty(path.span,
+                ast::ty_path(path, self.next_id()))
     }
-}
 
-pub fn mk_ty_path(cx: @ext_ctxt,
-                  span: span,
-                  idents: ~[ ast::ident ])
-               -> @ast::Ty {
-    let ty = build::mk_raw_path(span, idents);
-    mk_ty_path_path(cx, span, ty)
-}
+    fn ty_ident(&self, span: span, ident: ast::ident)
+        -> @ast::Ty {
+        self.ty_path(self.path_ident(span, ident))
+    }
 
-pub fn mk_ty_path_global(cx: @ext_ctxt,
-                         span: span,
-                         idents: ~[ ast::ident ])
-                      -> @ast::Ty {
-    let ty = build::mk_raw_path_global(span, idents);
-    mk_ty_path_path(cx, span, ty)
-}
+    fn ty_rptr(&self,
+               span: span,
+               ty: @ast::Ty,
+               lifetime: Option<@ast::Lifetime>,
+               mutbl: ast::mutability)
+        -> @ast::Ty {
+        self.ty(span,
+                ast::ty_rptr(lifetime, self.ty_mt(ty, mutbl)))
+    }
+    fn ty_uniq(&self, span: span, ty: @ast::Ty) -> @ast::Ty {
+        self.ty(span, ast::ty_uniq(self.ty_mt(ty, ast::m_imm)))
+    }
+    fn ty_box(&self, span: span,
+                 ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty {
+        self.ty(span, ast::ty_box(self.ty_mt(ty, mutbl)))
+    }
 
-pub fn mk_ty_path_path(cx: @ext_ctxt,
-                       span: span,
-                       path: @ast::Path)
-                      -> @ast::Ty {
-    let ty = ast::ty_path(path, cx.next_id());
-    mk_ty(cx, span, ty)
-}
+    fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty {
+        self.ty_path(
+            self.path_all(dummy_sp(),
+                          true,
+                          ~[
+                              self.ident_of("core"),
+                              self.ident_of("option"),
+                              self.ident_of("Option")
+                          ],
+                          None,
+                          ~[ ty ]))
+    }
 
-pub fn mk_ty_rptr(cx: @ext_ctxt,
-                  span: span,
-                  ty: @ast::Ty,
-                  lifetime: Option<@ast::Lifetime>,
-                  mutbl: ast::mutability)
-               -> @ast::Ty {
-    mk_ty(cx, span,
-          ast::ty_rptr(lifetime, mk_ty_mt(ty, mutbl)))
-}
-pub fn mk_ty_uniq(cx: @ext_ctxt, span: span, ty: @ast::Ty) -> @ast::Ty {
-    mk_ty(cx, span, ast::ty_uniq(mk_ty_mt(ty, ast::m_imm)))
-}
-pub fn mk_ty_box(cx: @ext_ctxt, span: span,
-                 ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty {
-    mk_ty(cx, span, ast::ty_box(mk_ty_mt(ty, mutbl)))
-}
+    fn ty_field_imm(&self, span: span, name: ident, ty: @ast::Ty) -> ast::ty_field {
+        respan(span,
+               ast::ty_field_ {
+                   ident: name,
+                   mt: ast::mt { ty: ty, mutbl: ast::m_imm },
+               })
+    }
 
+    fn ty_infer(&self, span: span) -> @ast::Ty {
+        self.ty(span, ast::ty_infer)
+    }
 
+    fn ty_nil(&self) -> @ast::Ty {
+        @ast::Ty {
+            id: self.next_id(),
+            node: ast::ty_nil,
+            span: dummy_sp(),
+        }
+    }
 
-pub fn mk_ty_infer(cx: @ext_ctxt, span: span) -> @ast::Ty {
-    mk_ty(cx, span, ast::ty_infer)
-}
-pub fn mk_trait_ref_global(cx: @ext_ctxt,
-                           span: span,
-                           idents: ~[ ast::ident ])
-    -> @ast::trait_ref
-{
-    mk_trait_ref_(cx, build::mk_raw_path_global(span, idents))
-}
-pub fn mk_trait_ref_(cx: @ext_ctxt, path: @ast::Path) -> @ast::trait_ref {
-    @ast::trait_ref {
-        path: path,
-        ref_id: cx.next_id()
+    fn typaram(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>) -> ast::TyParam {
+        ast::TyParam { ident: id, id: self.next_id(), bounds: bounds }
     }
-}
-pub fn mk_simple_ty_path(cx: @ext_ctxt,
-                         span: span,
-                         ident: ast::ident)
-                      -> @ast::Ty {
-    mk_ty_path(cx, span, ~[ ident ])
-}
-pub fn mk_arg(cx: @ext_ctxt,
-              span: span,
-              ident: ast::ident,
-              ty: @ast::Ty)
-           -> ast::arg {
-    let arg_pat = mk_pat_ident(cx, span, ident);
-    ast::arg {
-        is_mutbl: false,
-        ty: ty,
-        pat: arg_pat,
-        id: cx.next_id()
+
+    // these are strange, and probably shouldn't be used outside of
+    // pipes. Specifically, the global version possible generates
+    // incorrect code.
+    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
+        opt_vec::take_vec(
+            ty_params.map(|p| self.ty_ident(dummy_sp(), p.ident)))
     }
-}
-pub fn mk_fn_decl(inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl {
-    ast::fn_decl { inputs: inputs, output: output, cf: ast::return_val }
-}
-pub fn mk_trait_ty_param_bound_global(cx: @ext_ctxt,
-                                      span: span,
-                                      idents: ~[ast::ident])
-                                   -> ast::TyParamBound {
-    ast::TraitTyParamBound(mk_trait_ref_global(cx, span, idents))
-}
-pub fn mk_trait_ty_param_bound_(cx: @ext_ctxt,
-                                path: @ast::Path) -> ast::TyParamBound {
-    ast::TraitTyParamBound(mk_trait_ref_(cx, path))
-}
-pub fn mk_ty_param(cx: @ext_ctxt,
-                   ident: ast::ident,
-                   bounds: @OptVec<ast::TyParamBound>)
-                -> ast::TyParam {
-    ast::TyParam { ident: ident, id: cx.next_id(), bounds: bounds }
-}
-pub fn mk_lifetime(cx: @ext_ctxt,
-                   span: span,
-                   ident: ast::ident)
-                -> ast::Lifetime {
-    ast::Lifetime { id: cx.next_id(), span: span, ident: ident }
-}
-pub fn mk_arm(cx: @ext_ctxt,
-              span: span,
-              pats: ~[@ast::pat],
-              expr: @ast::expr)
-           -> ast::arm {
-    ast::arm {
-        pats: pats,
-        guard: None,
-        body: mk_simple_block(cx, span, expr)
+
+    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
+        opt_vec::take_vec(
+            ty_params.map(|p| self.ty_path(
+                self.path_global(dummy_sp(), ~[p.ident]))))
     }
-}
-pub fn mk_unreachable(cx: @ext_ctxt, span: span) -> @ast::expr {
-    let loc = cx.codemap().lookup_char_pos(span.lo);
-    mk_call_global(
-        cx,
-        span,
-        ~[
-            cx.ident_of("core"),
-            cx.ident_of("sys"),
-            cx.ident_of("FailWithCause"),
-            cx.ident_of("fail_with"),
-        ],
-        ~[
-            mk_base_str(cx, span, ~"internal error: entered unreachable code"),
-            mk_base_str(cx, span, copy loc.file.name),
-            mk_uint(cx, span, loc.line),
-        ]
-    )
-}
-pub fn mk_unreachable_arm(cx: @ext_ctxt, span: span) -> ast::arm {
-    mk_arm(cx, span, ~[mk_pat_wild(cx, span)], mk_unreachable(cx, span))
-}
 
-pub fn make_self(cx: @ext_ctxt, span: span) -> @ast::expr {
-    build::mk_expr(cx, span, ast::expr_self)
-}
+    fn strip_bounds(&self, generics: &Generics) -> Generics {
+        let no_bounds = @opt_vec::Empty;
+        let new_params = do generics.ty_params.map |ty_param| {
+            ast::TyParam { bounds: no_bounds, ..copy *ty_param }
+        };
+        Generics {
+            ty_params: new_params,
+            .. copy *generics
+        }
+    }
 
-//
-// Duplication functions
-//
-// These functions just duplicate AST nodes.
-//
+    fn trait_ref(&self, path: @ast::Path) -> @ast::trait_ref {
+        @ast::trait_ref {
+            path: path,
+            ref_id: self.next_id()
+        }
+    }
 
-pub fn duplicate_expr(cx: @ext_ctxt, expr: @ast::expr) -> @ast::expr {
-    let folder = fold::default_ast_fold();
-    let folder = @fold::AstFoldFns {
-        new_id: |_| cx.next_id(),
-        ..*folder
-    };
-    let folder = fold::make_fold(folder);
-    folder.fold_expr(expr)
-}
+    fn typarambound(&self, path: @ast::Path) -> ast::TyParamBound {
+        ast::TraitTyParamBound(self.trait_ref(path))
+    }
 
+    fn lifetime(&self, span: span, ident: ast::ident) -> ast::Lifetime {
+        ast::Lifetime { id: self.next_id(), span: span, ident: ident }
+    }
 
+    fn stmt_expr(&self, expr: @ast::expr) -> @ast::stmt {
+        @respan(expr.span, ast::stmt_semi(expr, self.next_id()))
+    }
 
-// Transitional reexports so qquote can find the paths it is looking for
-mod syntax {
-    pub use ext;
-    pub use parse;
-}
+    fn stmt_let(&self, sp: span, mutbl: bool, ident: ast::ident, ex: @ast::expr) -> @ast::stmt {
+        let pat = self.pat_ident(sp, ident);
+        let local = @respan(sp,
+                            ast::local_ {
+                                is_mutbl: mutbl,
+                                ty: self.ty_infer(sp),
+                                pat: pat,
+                                init: Some(ex),
+                                id: self.next_id(),
+                            });
+        let decl = respan(sp, ast::decl_local(~[local]));
+        @respan(sp, ast::stmt_decl(@decl, self.next_id()))
+    }
 
-trait ExtCtxtMethods {
-    fn bind_path(&self,
-                 span: span,
-                 ident: ast::ident,
-                 path: @ast::Path,
-                 bounds: @OptVec<ast::TyParamBound>)
-                 -> ast::TyParam;
-    fn expr(&self, span: span, node: ast::expr_) -> @ast::expr;
-    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
-    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path;
-    fn path_tps(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty])
-                -> @ast::Path;
-    fn path_tps_global(&self,
-                       span: span,
-                       strs: ~[ast::ident],
-                       tps: ~[@ast::Ty])
-                       -> @ast::Path;
-    fn ty_path(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty])
-               -> @ast::Ty;
-    fn binder_pat(&self, span: span, nm: ast::ident) -> @ast::pat;
-    fn stmt(&self, expr: @ast::expr) -> @ast::stmt;
-    fn lit_str(&self, span: span, s: @~str) -> @ast::expr;
-    fn lit_uint(&self, span: span, i: uint) -> @ast::expr;
-    fn lambda0(&self, blk: ast::blk) -> @ast::expr;
-    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr;
-    fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk;
-    fn expr_blk(&self, expr: @ast::expr) -> ast::blk;
-    fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
-    fn expr_path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::expr;
-    fn expr_var(&self, span: span, var: &str) -> @ast::expr;
-    fn expr_self(&self, span: span) -> @ast::expr;
-    fn expr_field(&self, span: span, expr: @ast::expr, ident: ast::ident)
-                  -> @ast::expr;
-    fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr])
-                 -> @ast::expr;
-    fn expr_method_call(&self,
-                        span: span,
-                        expr: @ast::expr,
-                        ident: ast::ident,
-                        args: ~[@ast::expr])
-                        -> @ast::expr;
-    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr;
-    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
-                    -> @ast::expr;
-    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr;
-    fn lambda_stmts_1(&self,
-                      span: span,
-                      stmts: ~[@ast::stmt],
-                      ident: ast::ident)
-                      -> @ast::expr;
-}
+    fn blk(&self, span: span, stmts: ~[@ast::stmt], expr: Option<@expr>) -> ast::blk {
+        self.blk_all(span, ~[], stmts, expr)
+    }
 
-impl ExtCtxtMethods for @ext_ctxt {
-    fn bind_path(
-        &self,
-        _span: span,
-        ident: ast::ident,
-        path: @ast::Path,
-        bounds: @OptVec<ast::TyParamBound>
-    ) -> ast::TyParam {
-        let bound = ast::TraitTyParamBound(@ast::trait_ref {
-            ref_id: self.next_id(),
-            path: path
-        });
-
-        ast::TyParam {
-            ident: ident,
-            id: self.next_id(),
-            bounds: @bounds.prepend(bound)
-        }
+    fn blk_expr(&self, expr: @ast::expr) -> ast::blk {
+        self.blk_all(expr.span, ~[], ~[], Some(expr))
+    }
+    fn blk_all(&self,
+               span: span,
+               view_items: ~[@ast::view_item],
+               stmts: ~[@ast::stmt],
+               expr: Option<@ast::expr>) -> ast::blk {
+        respan(span,
+               ast::blk_ {
+                   view_items: view_items,
+                   stmts: stmts,
+                   expr: expr,
+                   id: self.next_id(),
+                   rules: ast::default_blk,
+               })
     }
 
     fn expr(&self, span: span, node: ast::expr_) -> @ast::expr {
@@ -628,212 +418,440 @@ impl ExtCtxtMethods for @ext_ctxt {
         }
     }
 
-    fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: false,
-            idents: strs,
-            rp: None,
-            types: ~[]
-        }
+    fn expr_path(&self, path: @ast::Path) -> @ast::expr {
+        self.expr(path.span, ast::expr_path(path))
     }
 
-    fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: true,
-            idents: strs,
-            rp: None,
-            types: ~[]
-        }
+    fn expr_ident(&self, span: span, id: ast::ident) -> @ast::expr {
+        self.expr_path(self.path_ident(span, id))
+    }
+    fn expr_self(&self, span: span) -> @ast::expr {
+        self.expr(span, ast::expr_self)
     }
 
-    fn path_tps(
-        &self,
-        span: span,
-        strs: ~[ast::ident],
-        tps: ~[@ast::Ty]
-    ) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: false,
-            idents: strs,
-            rp: None,
-            types: tps
-        }
+    fn expr_binary(&self, sp: span, op: ast::binop,
+                   lhs: @ast::expr, rhs: @ast::expr) -> @ast::expr {
+        self.next_id(); // see ast_util::op_expr_callee_id
+        self.expr(sp, ast::expr_binary(op, lhs, rhs))
     }
 
-    fn path_tps_global(
-        &self,
-        span: span,
-        strs: ~[ast::ident],
-        tps: ~[@ast::Ty]
-    ) -> @ast::Path {
-        @ast::Path {
-            span: span,
-            global: true,
-            idents: strs,
-            rp: None,
-            types: tps
-        }
+    fn expr_deref(&self, sp: span, e: @ast::expr) -> @ast::expr {
+        self.expr_unary(sp, ast::deref, e)
+    }
+    fn expr_unary(&self, sp: span, op: ast::unop, e: @ast::expr)
+        -> @ast::expr {
+        self.next_id(); // see ast_util::op_expr_callee_id
+        self.expr(sp, ast::expr_unary(op, e))
     }
 
-    fn ty_path(
-        &self,
-        span: span,
-        strs: ~[ast::ident],
-        tps: ~[@ast::Ty]
-    ) -> @ast::Ty {
-        @ast::Ty {
-            id: self.next_id(),
-            node: ast::ty_path(
-                self.path_tps(span, strs, tps),
-                self.next_id()),
-            span: span,
-        }
+    fn expr_copy(&self, sp: span, e: @ast::expr) -> @ast::expr {
+        self.expr(sp, ast::expr_copy(e))
+    }
+    fn expr_managed(&self, sp: span, e: @ast::expr) -> @ast::expr {
+        self.expr_unary(sp, ast::box(ast::m_imm), e)
     }
 
-    fn binder_pat(&self, span: span, nm: ast::ident) -> @ast::pat {
-        @ast::pat {
-            id: self.next_id(),
-            node: ast::pat_ident(
-                ast::bind_by_ref(ast::m_imm),
-                self.path(span, ~[nm]),
-                None),
-            span: span,
-        }
+    fn expr_field_access(&self, sp: span, expr: @ast::expr, ident: ast::ident) -> @ast::expr {
+        self.expr(sp, ast::expr_field(expr, ident, ~[]))
+    }
+    fn expr_addr_of(&self, sp: span, e: @ast::expr) -> @ast::expr {
+        self.expr(sp, ast::expr_addr_of(ast::m_imm, e))
+    }
+    fn expr_mut_addr_of(&self, sp: span, e: @ast::expr) -> @ast::expr {
+        self.expr(sp, ast::expr_addr_of(ast::m_mutbl, e))
+    }
+
+    fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr]) -> @ast::expr {
+        self.expr(span, ast::expr_call(expr, args, ast::NoSugar))
+    }
+    fn expr_call_ident(&self, span: span, id: ast::ident, args: ~[@ast::expr]) -> @ast::expr {
+        self.expr(span,
+                  ast::expr_call(self.expr_ident(span, id), args, ast::NoSugar))
+    }
+    fn expr_call_global(&self, sp: span, fn_path: ~[ast::ident],
+                      args: ~[@ast::expr]) -> @ast::expr {
+        let pathexpr = self.expr_path(self.path_global(sp, fn_path));
+        self.expr_call(sp, pathexpr, args)
+    }
+    fn expr_method_call(&self, span: span,
+                        expr: @ast::expr,
+                        ident: ast::ident,
+                        args: ~[@ast::expr]) -> @ast::expr {
+        self.expr(span,
+                  ast::expr_method_call(expr, ident, ~[], args, ast::NoSugar))
+    }
+    fn expr_blk(&self, b: ast::blk) -> @ast::expr {
+        self.expr(b.span, ast::expr_block(b))
+    }
+    fn field_imm(&self, span: span, name: ident, e: @ast::expr) -> ast::field {
+        respan(span, ast::field_ { mutbl: ast::m_imm, ident: name, expr: e })
+    }
+    fn expr_struct(&self, span: span, path: @ast::Path, fields: ~[ast::field]) -> @ast::expr {
+        self.expr(span, ast::expr_struct(path, fields, None))
+    }
+    fn expr_struct_ident(&self, span: span,
+                         id: ast::ident, fields: ~[ast::field]) -> @ast::expr {
+        self.expr_struct(span, self.path_ident(span, id), fields)
     }
 
-    fn stmt(&self, expr: @ast::expr) -> @ast::stmt {
-        @codemap::spanned { node: ast::stmt_semi(expr, self.next_id()),
-                       span: expr.span }
+    fn expr_lit(&self, sp: span, lit: ast::lit_) -> @ast::expr {
+        self.expr(sp, ast::expr_lit(@respan(sp, lit)))
+    }
+    fn expr_uint(&self, span: span, i: uint) -> @ast::expr {
+        self.expr_lit(span, ast::lit_uint(i as u64, ast::ty_u))
+    }
+    fn expr_int(&self, sp: span, i: int) -> @ast::expr {
+        self.expr_lit(sp, ast::lit_int(i as i64, ast::ty_i))
+    }
+    fn expr_u8(&self, sp: span, u: u8) -> @ast::expr {
+        self.expr_lit(sp, ast::lit_uint(u as u64, ast::ty_u8))
+    }
+    fn expr_bool(&self, sp: span, value: bool) -> @ast::expr {
+        self.expr_lit(sp, ast::lit_bool(value))
     }
 
-    fn lit_str(&self, span: span, s: @~str) -> @ast::expr {
-        self.expr(
-            span,
-            ast::expr_vstore(
-                self.expr(
-                    span,
-                    ast::expr_lit(
-                        @codemap::spanned { node: ast::lit_str(s),
-                                        span: span})),
-                ast::expr_vstore_uniq))
+    fn expr_vstore(&self, sp: span, expr: @ast::expr, vst: ast::expr_vstore) -> @ast::expr {
+        self.expr(sp, ast::expr_vstore(expr, vst))
+    }
+    fn expr_vec(&self, sp: span, exprs: ~[@ast::expr]) -> @ast::expr {
+        self.expr(sp, ast::expr_vec(exprs, ast::m_imm))
     }
+    fn expr_vec_uniq(&self, sp: span, exprs: ~[@ast::expr]) -> @ast::expr {
+        self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::expr_vstore_uniq)
+    }
+    fn expr_vec_slice(&self, sp: span, exprs: ~[@ast::expr]) -> @ast::expr {
+        self.expr_vstore(sp, self.expr_vec(sp, exprs), ast::expr_vstore_slice)
+    }
+    fn expr_str(&self, sp: span, s: ~str) -> @ast::expr {
+        self.expr_lit(sp, ast::lit_str(@s))
+    }
+    fn expr_str_uniq(&self, sp: span, s: ~str) -> @ast::expr {
+        self.expr_vstore(sp, self.expr_str(sp, s), ast::expr_vstore_uniq)
+    }
+
 
-    fn lit_uint(&self, span: span, i: uint) -> @ast::expr {
-        self.expr(
+    fn expr_unreachable(&self, span: span) -> @ast::expr {
+        let loc = self.codemap().lookup_char_pos(span.lo);
+        self.expr_call_global(
             span,
-            ast::expr_lit(
-                @codemap::spanned { node: ast::lit_uint(i as u64, ast::ty_u),
-                                span: span}))
+            ~[
+                self.ident_of("core"),
+                self.ident_of("sys"),
+                self.ident_of("FailWithCause"),
+                self.ident_of("fail_with"),
+            ],
+            ~[
+                self.expr_str(span, ~"internal error: entered unreachable code"),
+                self.expr_str(span, copy loc.file.name),
+                self.expr_uint(span, loc.line),
+            ])
     }
 
-    fn lambda0(&self, blk: ast::blk) -> @ast::expr {
+
+    fn pat(&self, span: span, pat: ast::pat_) -> @ast::pat {
+        @ast::pat { id: self.next_id(), node: pat, span: span }
+    }
+    fn pat_wild(&self, span: span) -> @ast::pat {
+        self.pat(span, ast::pat_wild)
+    }
+    fn pat_lit(&self, span: span, expr: @ast::expr) -> @ast::pat {
+        self.pat(span, ast::pat_lit(expr))
+    }
+    fn pat_ident(&self, span: span, ident: ast::ident) -> @ast::pat {
+        self.pat_ident_binding_mode(span, ident, ast::bind_by_copy)
+    }
+
+    fn pat_ident_binding_mode(&self,
+                              span: span,
+                              ident: ast::ident,
+                              bm: ast::binding_mode) -> @ast::pat {
+        let path = self.path_ident(span, ident);
+        let pat = ast::pat_ident(bm, path, None);
+        self.pat(span, pat)
+    }
+    fn pat_enum(&self, span: span, path: @ast::Path, subpats: ~[@ast::pat]) -> @ast::pat {
+        let pat = ast::pat_enum(path, Some(subpats));
+        self.pat(span, pat)
+    }
+    fn pat_struct(&self, span: span,
+                  path: @ast::Path, field_pats: ~[ast::field_pat]) -> @ast::pat {
+        let pat = ast::pat_struct(path, field_pats, false);
+        self.pat(span, pat)
+    }
+
+    fn arm(&self, _span: span, pats: ~[@ast::pat], expr: @ast::expr) -> ast::arm {
+        ast::arm {
+            pats: pats,
+            guard: None,
+            body: self.blk_expr(expr)
+        }
+    }
+
+    fn arm_unreachable(&self, span: span) -> ast::arm {
+        self.arm(span, ~[self.pat_wild(span)], self.expr_unreachable(span))
+    }
+
+    fn expr_match(&self, span: span, arg: @ast::expr, arms: ~[ast::arm]) -> @expr {
+        self.expr(span, ast::expr_match(arg, arms))
+    }
+
+    fn expr_if(&self, span: span,
+               cond: @ast::expr, then: @ast::expr, els: Option<@ast::expr>) -> @ast::expr {
+        let els = els.map(|x| self.expr_blk(self.blk_expr(*x)));
+        self.expr(span, ast::expr_if(cond, self.blk_expr(then), els))
+    }
+
+    fn lambda_fn_decl(&self, span: span, fn_decl: ast::fn_decl, blk: ast::blk) -> @ast::expr {
+        self.expr(span, ast::expr_fn_block(fn_decl, blk))
+    }
+    fn lambda(&self, span: span, ids: ~[ast::ident], blk: ast::blk) -> @ast::expr {
+        let fn_decl = self.fn_decl(
+            ids.map(|id| self.arg(span, *id, self.ty_infer(span))),
+            self.ty_infer(span));
+
+        self.expr(span, ast::expr_fn_block(fn_decl, blk))
+    }
+    fn lambda0(&self, _span: span, blk: ast::blk) -> @ast::expr {
         let ext_cx = *self;
         let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
-        quote_expr!( || $blk_e )
+        quote_expr!(|| $blk_e )
     }
 
-    fn lambda1(&self, blk: ast::blk, ident: ast::ident) -> @ast::expr {
+    fn lambda1(&self, _span: span, blk: ast::blk, ident: ast::ident) -> @ast::expr {
         let ext_cx = *self;
         let blk_e = self.expr(copy blk.span, ast::expr_block(copy blk));
-        quote_expr!( |$ident| $blk_e )
-    }
-
-    fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk {
-        codemap::spanned {
-            node: ast::blk_ {
-                view_items: ~[],
-                stmts: stmts,
-                expr: None,
-                id: self.next_id(),
-                rules: ast::default_blk,
-            },
-            span: span,
+        quote_expr!(|$ident| $blk_e )
+    }
+
+    fn lambda_expr(&self, span: span, ids: ~[ast::ident], expr: @ast::expr) -> @ast::expr {
+        self.lambda(span, ids, self.blk_expr(expr))
+    }
+    fn lambda_expr_0(&self, span: span, expr: @ast::expr) -> @ast::expr {
+        self.lambda0(span, self.blk_expr(expr))
+    }
+    fn lambda_expr_1(&self, span: span, expr: @ast::expr, ident: ast::ident) -> @ast::expr {
+        self.lambda1(span, self.blk_expr(expr), ident)
+    }
+
+    fn lambda_stmts(&self, span: span, ids: ~[ast::ident], stmts: ~[@ast::stmt]) -> @ast::expr {
+        self.lambda(span, ids, self.blk(span, stmts, None))
+    }
+    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
+        self.lambda0(span, self.blk(span, stmts, None))
+    }
+    fn lambda_stmts_1(&self, span: span, stmts: ~[@ast::stmt], ident: ast::ident) -> @ast::expr {
+        self.lambda1(span, self.blk(span, stmts, None), ident)
+    }
+
+    fn arg(&self, span: span, ident: ast::ident, ty: @ast::Ty) -> ast::arg {
+        let arg_pat = self.pat_ident(span, ident);
+        ast::arg {
+            is_mutbl: false,
+            ty: ty,
+            pat: arg_pat,
+            id: self.next_id()
         }
     }
 
-    fn expr_blk(&self, expr: @ast::expr) -> ast::blk {
-        codemap::spanned {
-            node: ast::blk_ {
-                view_items: ~[],
-                stmts: ~[],
-                expr: Some(expr),
-                id: self.next_id(),
-                rules: ast::default_blk,
-            },
-            span: expr.span,
+    // XXX unused self
+    fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl {
+        ast::fn_decl {
+            inputs: inputs,
+            output: output,
+            cf: ast::return_val,
         }
     }
 
-    fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr {
-        self.expr(span, ast::expr_path(self.path(span, strs)))
+    fn item(&self, span: span,
+            name: ident, attrs: ~[ast::attribute], node: ast::item_) -> @ast::item {
+        // XXX: Would be nice if our generated code didn't violate
+        // Rust coding conventions
+        @ast::item { ident: name,
+                    attrs: attrs,
+                    id: self.next_id(),
+                    node: node,
+                    vis: ast::public,
+                    span: span }
     }
 
-    fn expr_path_global(
-        &self,
-        span: span,
-        strs: ~[ast::ident]
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_path(self.path_global(span, strs)))
+    fn item_fn_poly(&self,
+                    span: span,
+                    name: ident,
+                    inputs: ~[ast::arg],
+                    output: @ast::Ty,
+                    generics: Generics,
+                    body: ast::blk) -> @ast::item {
+        self.item(span,
+                  name,
+                  ~[],
+                  ast::item_fn(self.fn_decl(inputs, output),
+                               ast::impure_fn,
+                               AbiSet::Rust(),
+                               generics,
+                               body))
+    }
+
+    fn item_fn(&self,
+               span: span,
+               name: ident,
+               inputs: ~[ast::arg],
+               output: @ast::Ty,
+               body: ast::blk
+              ) -> @ast::item {
+        self.item_fn_poly(
+            span,
+            name,
+            inputs,
+            output,
+            ast_util::empty_generics(),
+            body)
     }
 
-    fn expr_var(&self, span: span, var: &str) -> @ast::expr {
-        self.expr_path(span, ~[self.ident_of(var)])
+    fn variant(&self, span: span, name: ident, tys: ~[@ast::Ty]) -> ast::variant {
+        let args = do tys.map |ty| {
+            ast::variant_arg { ty: *ty, id: self.next_id() }
+        };
+
+        respan(span,
+               ast::variant_ {
+                   name: name,
+                   attrs: ~[],
+                   kind: ast::tuple_variant_kind(args),
+                   id: self.next_id(),
+                   disr_expr: None,
+                   vis: ast::public
+               })
     }
 
-    fn expr_self(&self, span: span) -> @ast::expr {
-        self.expr(span, ast::expr_self)
+    fn item_enum_poly(&self, span: span, name: ident,
+                      enum_definition: ast::enum_def,
+                      generics: Generics) -> @ast::item {
+        self.item(span, name, ~[], ast::item_enum(enum_definition, generics))
     }
 
-    fn expr_field(
-        &self,
-        span: span,
-        expr: @ast::expr,
-        ident: ast::ident
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_field(expr, ident, ~[]))
+    fn item_enum(&self, span: span, name: ident,
+                 enum_definition: ast::enum_def) -> @ast::item {
+        self.item_enum_poly(span, name, enum_definition,
+                            ast_util::empty_generics())
     }
 
-    fn expr_call(
+    fn item_struct(
         &self,
         span: span,
-        expr: @ast::expr,
-        args: ~[@ast::expr]
-    ) -> @ast::expr {
-        self.expr(span, ast::expr_call(expr, args, ast::NoSugar))
+        name: ident,
+        struct_def: ast::struct_def
+    ) -> @ast::item {
+        self.item_struct_poly(
+            span,
+            name,
+            struct_def,
+            ast_util::empty_generics()
+        )
     }
 
-    fn expr_method_call(
+    fn item_struct_poly(
         &self,
         span: span,
-        expr: @ast::expr,
-        ident: ast::ident,
-        args: ~[@ast::expr]
-    ) -> @ast::expr {
-        self.expr(span,
-                  ast::expr_method_call(expr, ident, ~[], args, ast::NoSugar))
+        name: ident,
+        struct_def: ast::struct_def,
+        generics: Generics
+    ) -> @ast::item {
+        self.item(span, name, ~[], ast::item_struct(@struct_def, generics))
+    }
+
+    fn item_mod(&self, span: span, name: ident,
+                attrs: ~[ast::attribute],
+                vi: ~[@ast::view_item],
+                items: ~[@ast::item]) -> @ast::item {
+        self.item(
+            span,
+            name,
+            attrs,
+            ast::item_mod(ast::_mod {
+                view_items: vi,
+                items: items,
+            })
+        )
     }
 
-    fn lambda_expr_0(&self, expr: @ast::expr) -> @ast::expr {
-        self.lambda0(self.expr_blk(expr))
+    fn item_ty_poly(&self, span: span, name: ident, ty: @ast::Ty,
+                    generics: Generics) -> @ast::item {
+        self.item(span, name, ~[], ast::item_ty(ty, generics))
     }
 
-    fn lambda_expr_1(&self, expr: @ast::expr, ident: ast::ident)
-                    -> @ast::expr {
-        self.lambda1(self.expr_blk(expr), ident)
+    fn item_ty(&self, span: span, name: ident, ty: @ast::Ty) -> @ast::item {
+        self.item_ty_poly(span, name, ty, ast_util::empty_generics())
     }
 
-    fn lambda_stmts_0(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr {
-        self.lambda0(self.blk(span, stmts))
+    fn attribute(&self, sp: span, mi: @ast::meta_item) -> ast::attribute {
+        respan(sp,
+               ast::attribute_ {
+                   style: ast::attr_outer,
+                   value: mi,
+                   is_sugared_doc: false
+               })
     }
 
-    fn lambda_stmts_1(&self,
-                      span: span,
-                      stmts: ~[@ast::stmt],
-                      ident: ast::ident)
-                      -> @ast::expr {
-        self.lambda1(self.blk(span, stmts), ident)
+    fn meta_word(&self, sp: span, w: ~str) -> @ast::meta_item {
+        @respan(sp, ast::meta_word(@w))
+    }
+    fn meta_list(&self, sp: span, name: ~str, mis: ~[@ast::meta_item]) -> @ast::meta_item {
+        @respan(sp, ast::meta_list(@name, mis))
+    }
+    fn meta_name_value(&self, sp: span, name: ~str, value: ast::lit_) -> @ast::meta_item {
+        @respan(sp, ast::meta_name_value(@name, respan(sp, value)))
+    }
+
+    fn view_use(&self, sp: span,
+                vis: ast::visibility, vp: ~[@ast::view_path]) -> @ast::view_item {
+        @ast::view_item {
+            node: ast::view_item_use(vp),
+            attrs: ~[],
+            vis: vis,
+            span: sp
+        }
+    }
+
+    fn view_use_list(&self, sp: span, vis: ast::visibility,
+                     path: ~[ast::ident], imports: &[ast::ident]) -> @ast::view_item {
+        let imports = do imports.map |id| {
+            respan(sp, ast::path_list_ident_ { name: *id, id: self.next_id() })
+        };
+
+        self.view_use(sp, vis,
+                      ~[@respan(sp,
+                                ast::view_path_list(self.path(sp, path),
+                                                    imports,
+                                                    self.next_id()))])
+    }
+
+    fn view_use_glob(&self, sp: span,
+                     vis: ast::visibility, path: ~[ast::ident]) -> @ast::view_item {
+        self.view_use(sp, vis,
+                      ~[@respan(sp,
+                                ast::view_path_glob(self.path(sp, path), self.next_id()))])
+    }
+}
+
+
+pub trait Duplicate {
+    //
+    // Duplication functions
+    //
+    // These functions just duplicate AST nodes.
+    //
+
+    fn duplicate(&self, cx: @ExtCtxt) -> Self;
+}
+
+impl Duplicate for @ast::expr {
+    fn duplicate(&self, cx: @ExtCtxt) -> @ast::expr {
+        let folder = fold::default_ast_fold();
+        let folder = @fold::AstFoldFns {
+            new_id: |_| cx.next_id(),
+            ..*folder
+        };
+        let folder = fold::make_fold(folder);
+        folder.fold_expr(*self)
     }
 }
diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs
index 7c2f27ada3b..a046395b6f5 100644
--- a/src/libsyntax/ext/bytes.rs
+++ b/src/libsyntax/ext/bytes.rs
@@ -14,9 +14,9 @@ use ast;
 use codemap::span;
 use ext::base::*;
 use ext::base;
-use ext::build::{mk_u8, mk_slice_vec_e};
+use ext::build::AstBuilder;
 
-pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult {
+pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree]) -> base::MacResult {
     // Gather all argument expressions
     let exprs = get_exprs_from_tts(cx, tts);
     let mut bytes = ~[];
@@ -28,7 +28,7 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
                 // string literal, push each byte to vector expression
                 ast::lit_str(s) => {
                     for s.each |byte| {
-                        bytes.push(mk_u8(cx, sp, byte));
+                        bytes.push(cx.expr_u8(sp, byte));
                     }
                 }
 
@@ -37,7 +37,7 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
                     if v > 0xFF {
                         cx.span_err(sp, "Too large u8 literal in bytes!")
                     } else {
-                        bytes.push(mk_u8(cx, sp, v as u8));
+                        bytes.push(cx.expr_u8(sp, v as u8));
                     }
                 }
 
@@ -48,14 +48,14 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
                     } else if v < 0 {
                         cx.span_err(sp, "Negative integer literal in bytes!")
                     } else {
-                        bytes.push(mk_u8(cx, sp, v as u8));
+                        bytes.push(cx.expr_u8(sp, v as u8));
                     }
                 }
 
                 // char literal, push to vector expression
                 ast::lit_int(v, ast::ty_char) => {
                     if (v as char).is_ascii() {
-                        bytes.push(mk_u8(cx, sp, v as u8));
+                        bytes.push(cx.expr_u8(sp, v as u8));
                     } else {
                         cx.span_err(sp, "Non-ascii char literal in bytes!")
                     }
@@ -68,6 +68,6 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) -> ba
         }
     }
 
-    let e = mk_slice_vec_e(cx, sp, bytes);
+    let e = cx.expr_vec_slice(sp, bytes);
     MRExpr(e)
 }
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index da32cc11625..e6600e198fa 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -14,7 +14,7 @@ use ext::base::*;
 use ext::base;
 use parse::token;
 
-pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     let mut res_str = ~"";
     for tts.eachi |i, e| {
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index aceb60ebbd7..007826a8416 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -10,23 +10,23 @@
 
 use ast::{meta_item, item, expr};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
 
-pub fn expand_deriving_clone(cx: @ext_ctxt,
+pub fn expand_deriving_clone(cx: @ExtCtxt,
                              span: span,
                              mitem: @meta_item,
                              in_items: ~[@item])
                           -> ~[@item] {
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"clone", ~"Clone"]),
+        path: Path::new(~["core", "clone", "Clone"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
-                name: ~"clone",
+                name: "clone",
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[],
@@ -42,18 +42,18 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
                             &trait_def)
 }
 
-pub fn expand_deriving_deep_clone(cx: @ext_ctxt,
+pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
                                  span: span,
                                  mitem: @meta_item,
                                  in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"clone", ~"DeepClone"]),
+        path: Path::new(~["core", "clone", "DeepClone"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
-                name: ~"deep_clone",
+                name: "deep_clone",
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[],
@@ -73,21 +73,21 @@ pub fn expand_deriving_deep_clone(cx: @ext_ctxt,
 
 fn cs_clone(
     name: &str,
-    cx: @ext_ctxt, span: span,
+    cx: @ExtCtxt, span: span,
     substr: &Substructure) -> @expr {
     let clone_ident = substr.method_ident;
     let ctor_ident;
     let all_fields;
     let subcall = |field|
-        build::mk_method_call(cx, span, field, clone_ident, ~[]);
+        cx.expr_method_call(span, field, clone_ident, ~[]);
 
     match *substr.fields {
         Struct(ref af) => {
-            ctor_ident = ~[ substr.type_ident ];
+            ctor_ident = substr.type_ident;
             all_fields = af;
         }
         EnumMatching(_, variant, ref af) => {
-            ctor_ident = ~[ variant.node.name ];
+            ctor_ident = variant.node.name;
             all_fields = af;
         },
         EnumNonMatching(*) => cx.span_bug(span,
@@ -102,7 +102,7 @@ fn cs_clone(
         [(None, _, _), .. _] => {
             // enum-like
             let subcalls = all_fields.map(|&(_, self_f, _)| subcall(self_f));
-            build::mk_call(cx, span, ctor_ident, subcalls)
+            cx.expr_call_ident(span, ctor_ident, subcalls)
         },
         _ => {
             // struct-like
@@ -113,16 +113,14 @@ fn cs_clone(
                                         fmt!("unnamed field in normal struct in `deriving(%s)`",
                                              name))
                 };
-                build::Field { ident: ident, ex: subcall(self_f) }
+                cx.field_imm(span, ident, subcall(self_f))
             };
 
             if fields.is_empty() {
                 // no fields, so construct like `None`
-                build::mk_path(cx, span, ctor_ident)
+                cx.expr_ident(span, ctor_ident)
             } else {
-                build::mk_struct_e(cx, span,
-                                   ctor_ident,
-                                   fields)
+                cx.expr_struct_ident(span, ctor_ident, fields)
             }
         }
     }
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index 3d93f844ea3..11c0a597ceb 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -10,22 +10,22 @@
 
 use ast::{meta_item, item, expr};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-pub fn expand_deriving_eq(cx: @ext_ctxt,
+pub fn expand_deriving_eq(cx: @ExtCtxt,
                           span: span,
                           mitem: @meta_item,
                           in_items: ~[@item]) -> ~[@item] {
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
-    fn cs_eq(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
-        cs_and(|cx, span, _, _| build::mk_bool(cx, span, false),
+    fn cs_eq(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
+        cs_and(|cx, span, _, _| cx.expr_bool(span, false),
                                  cx, span, substr)
     }
-    fn cs_ne(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
-        cs_or(|cx, span, _, _| build::mk_bool(cx, span, true),
+    fn cs_ne(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
+        cs_or(|cx, span, _, _| cx.expr_bool(span, true),
               cx, span, substr)
     }
 
@@ -36,7 +36,7 @@ pub fn expand_deriving_eq(cx: @ext_ctxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[borrowed_self()],
-                ret_ty: Literal(Path::new(~[~"bool"])),
+                ret_ty: Literal(Path::new(~["bool"])),
                 const_nonmatching: true,
                 combine_substructure: $f
             },
@@ -44,12 +44,12 @@ pub fn expand_deriving_eq(cx: @ext_ctxt,
     );
 
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"cmp", ~"Eq"]),
+        path: Path::new(~["core", "cmp", "Eq"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
-            md!(~"eq", cs_eq),
-            md!(~"ne", cs_ne)
+            md!("eq", cs_eq),
+            md!("ne", cs_ne)
         ]
     };
 
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 5445aef4491..9438e1b0f85 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -9,13 +9,13 @@
 // except according to those terms.
 
 
-use ast::{meta_item, item, expr_if, expr};
+use ast::{meta_item, item, expr};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-pub fn expand_deriving_ord(cx: @ext_ctxt,
+pub fn expand_deriving_ord(cx: @ExtCtxt,
                            span: span,
                            mitem: @meta_item,
                            in_items: ~[@item]) -> ~[@item] {
@@ -26,7 +26,7 @@ pub fn expand_deriving_ord(cx: @ext_ctxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[borrowed_self()],
-                ret_ty: Literal(Path::new(~[~"bool"])),
+                ret_ty: Literal(Path::new(~["bool"])),
                 const_nonmatching: false,
                 combine_substructure: |cx, span, substr|
                     cs_ord($less, $equal, cx, span, substr)
@@ -37,15 +37,15 @@ pub fn expand_deriving_ord(cx: @ext_ctxt,
 
 
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"cmp", ~"Ord"]),
+        path: Path::new(~["core", "cmp", "Ord"]),
         // XXX: Ord doesn't imply Eq yet
-        additional_bounds: ~[Literal(Path::new(~[~"core", ~"cmp", ~"Eq"]))],
+        additional_bounds: ~[Literal(Path::new(~["core", "cmp", "Eq"]))],
         generics: LifetimeBounds::empty(),
         methods: ~[
-            md!(~"lt", true,  false),
-            md!(~"le", true,  true),
-            md!(~"gt", false, false),
-            md!(~"ge", false, true)
+            md!("lt", true,  false),
+            md!("le", true,  true),
+            md!("gt", false, false),
+            md!("ge", false, true)
         ]
     };
 
@@ -55,17 +55,14 @@ pub fn expand_deriving_ord(cx: @ext_ctxt,
 
 /// `less`: is this `lt` or `le`? `equal`: is this `le` or `ge`?
 fn cs_ord(less: bool, equal: bool,
-          cx: @ext_ctxt, span: span,
+          cx: @ExtCtxt, span: span,
           substr: &Substructure) -> @expr {
     let binop = if less {
         cx.ident_of("lt")
     } else {
         cx.ident_of("gt")
     };
-    let false_blk_expr = build::mk_block(cx, span,
-                                         ~[], ~[],
-                                         Some(build::mk_bool(cx, span, false)));
-    let base = build::mk_bool(cx, span, equal);
+    let base = cx.expr_bool(span, equal);
 
     cs_fold(
         false, // need foldr,
@@ -98,19 +95,15 @@ fn cs_ord(less: bool, equal: bool,
                 cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`");
             }
 
-            let cmp = build::mk_method_call(cx, span,
-                                            self_f, cx.ident_of("eq"), other_fs.to_owned());
-            let subexpr = build::mk_simple_block(cx, span, subexpr);
-            let elseif = expr_if(cmp, subexpr, Some(false_blk_expr));
-            let elseif = build::mk_expr(cx, span, elseif);
+            let cmp = cx.expr_method_call(span,
+                                          self_f, cx.ident_of("eq"), other_fs.to_owned());
+            let elseif = cx.expr_if(span, cmp,
+                                    subexpr, Some(cx.expr_bool(span, false)));
 
-            let cmp = build::mk_method_call(cx, span,
-                                            self_f, binop, other_fs.to_owned());
-            let true_blk = build::mk_simple_block(cx, span,
-                                                  build::mk_bool(cx, span, true));
-            let if_ = expr_if(cmp, true_blk, Some(elseif));
-
-            build::mk_expr(cx, span, if_)
+            let cmp = cx.expr_method_call(span,
+                                          self_f, binop, other_fs.to_owned());
+            cx.expr_if(span, cmp,
+                        cx.expr_bool(span, true), Some(elseif))
         },
         base,
         |cx, span, args, _| {
@@ -119,7 +112,7 @@ fn cs_ord(less: bool, equal: bool,
             match args {
                 [(self_var, _, _),
                  (other_var, _, _)] =>
-                    build::mk_bool(cx, span,
+                    cx.expr_bool(span,
                                    if less {
                                        self_var < other_var
                                    } else {
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index 4541569b829..f1e952eb5f6 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -11,31 +11,31 @@
 
 use ast::{meta_item, item, expr};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-pub fn expand_deriving_totaleq(cx: @ext_ctxt,
+pub fn expand_deriving_totaleq(cx: @ExtCtxt,
                           span: span,
                           mitem: @meta_item,
                           in_items: ~[@item]) -> ~[@item] {
 
-    fn cs_equals(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
-        cs_and(|cx, span, _, _| build::mk_bool(cx, span, false),
+    fn cs_equals(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
+        cs_and(|cx, span, _, _| cx.expr_bool(span, false),
                cx, span, substr)
     }
 
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"cmp", ~"TotalEq"]),
+        path: Path::new(~["core", "cmp", "TotalEq"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
-                name: ~"equals",
+                name: "equals",
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[borrowed_self()],
-                ret_ty: Literal(Path::new(~[~"bool"])),
+                ret_ty: Literal(Path::new(~["bool"])),
                 const_nonmatching: true,
                 combine_substructure: cs_equals
             }
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index 8f156e6a9e3..e26f4a34304 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -10,26 +10,26 @@
 
 use ast::{meta_item, item, expr};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use core::cmp::{Ordering, Equal, Less, Greater};
 
-pub fn expand_deriving_totalord(cx: @ext_ctxt,
+pub fn expand_deriving_totalord(cx: @ExtCtxt,
                                 span: span,
                                 mitem: @meta_item,
                                 in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"cmp", ~"TotalOrd"]),
+        path: Path::new(~["core", "cmp", "TotalOrd"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
-                name: ~"cmp",
+                name: "cmp",
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[borrowed_self()],
-                ret_ty: Literal(Path::new(~[~"core", ~"cmp", ~"Ordering"])),
+                ret_ty: Literal(Path::new(~["core", "cmp", "Ordering"])),
                 const_nonmatching: false,
                 combine_substructure: cs_cmp
             }
@@ -41,30 +41,31 @@ pub fn expand_deriving_totalord(cx: @ext_ctxt,
 }
 
 
-pub fn ordering_const(cx: @ext_ctxt, span: span, cnst: Ordering) -> @expr {
+pub fn ordering_const(cx: @ExtCtxt, span: span, cnst: Ordering) -> @expr {
     let cnst = match cnst {
         Less => "Less",
         Equal => "Equal",
         Greater => "Greater"
     };
-    build::mk_path_global(cx, span,
-                          ~[cx.ident_of("core"),
-                            cx.ident_of("cmp"),
-                            cx.ident_of(cnst)])
+    cx.expr_path(
+        cx.path_global(span,
+                       ~[cx.ident_of("core"),
+                         cx.ident_of("cmp"),
+                         cx.ident_of(cnst)]))
 }
 
-pub fn cs_cmp(cx: @ext_ctxt, span: span,
+pub fn cs_cmp(cx: @ExtCtxt, span: span,
               substr: &Substructure) -> @expr {
 
     cs_same_method_fold(
         // foldr (possibly) nests the matches in lexical_ordering better
         false,
         |cx, span, old, new| {
-            build::mk_call_global(cx, span,
-                                  ~[cx.ident_of("core"),
-                                    cx.ident_of("cmp"),
-                                    cx.ident_of("lexical_ordering")],
-                                  ~[old, new])
+            cx.expr_call_global(span,
+                                ~[cx.ident_of("core"),
+                                  cx.ident_of("cmp"),
+                                  cx.ident_of("lexical_ordering")],
+                                ~[old, new])
         },
         ordering_const(cx, span, Equal),
         |cx, span, list, _| {
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index fe205112046..a8c84e8e361 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -15,15 +15,15 @@ encodable.rs for more.
 
 use ast;
 use ast::*;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::*;
 use codemap::{span, spanned};
 use ast_util;
 use opt_vec;
 
 pub fn expand_deriving_decodable(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     _mitem: @meta_item,
     in_items: ~[@item]
@@ -38,34 +38,31 @@ pub fn expand_deriving_decodable(
 }
 
 fn create_derived_decodable_impl(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     type_ident: ident,
     generics: &Generics,
     method: @method
 ) -> @item {
-    let decoder_ty_param = build::mk_ty_param(
-        cx,
+    let decoder_ty_param = cx.typaram(
         cx.ident_of("__D"),
         @opt_vec::with(
-            build::mk_trait_ty_param_bound_global(
-                cx,
-                span,
-                ~[
-                    cx.ident_of("std"),
-                    cx.ident_of("serialize"),
-                    cx.ident_of("Decoder"),
-                ]
-            )
-        )
-    );
+            cx.typarambound(
+                cx.path_global(
+                    span,
+                    ~[
+                        cx.ident_of("std"),
+                        cx.ident_of("serialize"),
+                        cx.ident_of("Decoder"),
+                    ]))));
 
     // All the type parameters need to bound to the trait.
     let generic_ty_params = opt_vec::with(decoder_ty_param);
 
     let methods = [method];
-    let trait_path = build::mk_raw_path_global_(
+    let trait_path = cx.path_all(
         span,
+        true,
         ~[
             cx.ident_of("std"),
             cx.ident_of("serialize"),
@@ -73,7 +70,7 @@ fn create_derived_decodable_impl(
         ],
         None,
         ~[
-            build::mk_simple_ty_path(cx, span, cx.ident_of("__D"))
+            cx.ty_ident(span, cx.ident_of("__D"))
         ]
     );
     create_derived_impl(
@@ -91,22 +88,21 @@ fn create_derived_decodable_impl(
 // Creates a method from the given set of statements conforming to the
 // signature of the `decodable` method.
 fn create_decode_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     type_ident: ast::ident,
     generics: &Generics,
     expr: @ast::expr
 ) -> @method {
     // Create the `e` parameter.
-    let d_arg_type = build::mk_ty_rptr(
-        cx,
+    let d_arg_type = cx.ty_rptr(
         span,
-        build::mk_simple_ty_path(cx, span, cx.ident_of("__D")),
+        cx.ty_ident(span, cx.ident_of("__D")),
         None,
         ast::m_mutbl
     );
     let d_ident = cx.ident_of("__d");
-    let d_arg = build::mk_arg(cx, span, d_ident, d_arg_type);
+    let d_arg = cx.arg(span, d_ident, d_arg_type);
 
     // Create the type of the return value.
     let output_type = create_self_type_with_params(
@@ -118,10 +114,10 @@ fn create_decode_method(
 
     // Create the function declaration.
     let inputs = ~[d_arg];
-    let fn_decl = build::mk_fn_decl(inputs, output_type);
+    let fn_decl = cx.fn_decl(inputs, output_type);
 
     // Create the body block.
-    let body_block = build::mk_simple_block(cx, span, expr);
+    let body_block = cx.blk_expr(expr);
 
     // Create the method.
     let explicit_self = spanned { node: sty_static, span: span };
@@ -142,31 +138,31 @@ fn create_decode_method(
 }
 
 fn call_substructure_decode_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span
 ) -> @ast::expr {
     // Call the substructure method.
-    build::mk_call_(
-        cx,
+    cx.expr_call(
         span,
-        build::mk_path_global(
-            cx,
-            span,
-            ~[
-                cx.ident_of("std"),
-                cx.ident_of("serialize"),
-                cx.ident_of("Decodable"),
-                cx.ident_of("decode"),
-            ]
+        cx.expr_path(
+            cx.path_global(
+                span,
+                ~[
+                    cx.ident_of("std"),
+                    cx.ident_of("serialize"),
+                    cx.ident_of("Decodable"),
+                    cx.ident_of("decode"),
+                ]
+            )
         ),
         ~[
-            build::mk_path(cx, span, ~[cx.ident_of("__d")])
+            cx.expr_ident(span, cx.ident_of("__d"))
         ]
     )
 }
 
 fn expand_deriving_decodable_struct_def(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     struct_def: &struct_def,
     type_ident: ident,
@@ -192,7 +188,7 @@ fn expand_deriving_decodable_struct_def(
 }
 
 fn expand_deriving_decodable_enum_def(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     enum_definition: &enum_def,
     type_ident: ident,
@@ -218,63 +214,54 @@ fn expand_deriving_decodable_enum_def(
 }
 
 fn create_read_struct_field(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     idx: uint,
     ident: ident
-) -> build::Field {
+) -> ast::field {
     // Call the substructure method.
     let decode_expr = call_substructure_decode_method(cx, span);
 
-    let d_arg = build::mk_arg(cx,
-                              span,
-                              cx.ident_of("__d"),
-                              build::mk_ty_infer(cx, span));
+    let d_id = cx.ident_of("__d");
 
-    let call_expr = build::mk_method_call(
-        cx,
+    let call_expr = cx.expr_method_call(
         span,
-        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.expr_ident(span, d_id),
         cx.ident_of("read_struct_field"),
         ~[
-            build::mk_base_str(cx, span, cx.str_of(ident)),
-            build::mk_uint(cx, span, idx),
-            build::mk_lambda(cx,
-                             span,
-                             build::mk_fn_decl(~[d_arg],
-                                               build::mk_ty_infer(cx, span)),
-                             decode_expr),
+            cx.expr_str(span, cx.str_of(ident)),
+            cx.expr_uint(span, idx),
+            cx.lambda_expr_1(span, decode_expr, d_id)
         ]
     );
 
-    build::Field { ident: ident, ex: call_expr }
+    cx.field_imm(span, ident, call_expr)
 }
 
 fn create_read_struct_arg(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     idx: uint,
     ident: ident
-) -> build::Field {
+) -> ast::field {
     // Call the substructure method.
     let decode_expr = call_substructure_decode_method(cx, span);
 
-    let call_expr = build::mk_method_call(
-        cx,
+    let call_expr = cx.expr_method_call(
         span,
-        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.expr_ident(span, cx.ident_of("__d")),
         cx.ident_of("read_struct_arg"),
         ~[
-            build::mk_uint(cx, span, idx),
-            build::mk_lambda_no_args(cx, span, decode_expr),
+            cx.expr_uint(span, idx),
+            cx.lambda_expr_0(span, decode_expr),
         ]
     );
 
-    build::Field { ident: ident, ex: call_expr }
+    cx.field_imm(span, ident, call_expr)
 }
 
 fn expand_deriving_decodable_struct_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     struct_def: &struct_def,
     type_ident: ident,
@@ -298,34 +285,19 @@ fn expand_deriving_decodable_struct_method(
         i += 1;
     }
 
-    let d_arg = build::mk_arg(cx,
-                              span,
-                              cx.ident_of("__d"),
-                              build::mk_ty_infer(cx, span));
+    let d_id = cx.ident_of("__d");
 
-    let read_struct_expr = build::mk_method_call(
-        cx,
+    let read_struct_expr = cx.expr_method_call(
         span,
-        build::mk_path(
-            cx,
-            span,
-            ~[cx.ident_of("__d")]
-        ),
+        cx.expr_ident(span, d_id),
         cx.ident_of("read_struct"),
         ~[
-            build::mk_base_str(cx, span, cx.str_of(type_ident)),
-            build::mk_uint(cx, span, fields.len()),
-            build::mk_lambda(
-                cx,
+            cx.expr_str(span, cx.str_of(type_ident)),
+            cx.expr_uint(span, fields.len()),
+            cx.lambda_expr_1(
                 span,
-                build::mk_fn_decl(~[d_arg], build::mk_ty_infer(cx, span)),
-                build::mk_struct_e(
-                    cx,
-                    span,
-                    ~[type_ident],
-                    fields
-                )
-            ),
+                cx.expr_struct_ident(span, type_ident, fields),
+                d_id)
         ]
     );
 
@@ -334,20 +306,20 @@ fn expand_deriving_decodable_struct_method(
 }
 
 fn create_read_variant_arg(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     idx: uint,
     variant: &ast::variant
 ) -> ast::arm {
     // Create the matching pattern.
-    let pat = build::mk_pat_lit(cx, span, build::mk_uint(cx, span, idx));
+    let pat = cx.pat_lit(span, cx.expr_uint(span, idx));
 
     // Feed each argument in this variant to the decode function
     // as well.
     let variant_arg_len = variant_arg_count(cx, span, variant);
 
     let expr = if variant_arg_len == 0 {
-        build::mk_path(cx, span, ~[variant.node.name])
+        cx.expr_ident(span, variant.node.name)
     } else {
         // Feed the discriminant to the decode function.
         let mut args = ~[];
@@ -356,53 +328,38 @@ fn create_read_variant_arg(
             // Call the substructure method.
             let expr = call_substructure_decode_method(cx, span);
 
-            let d_arg = build::mk_arg(cx,
-                                      span,
-                                      cx.ident_of("__d"),
-                                      build::mk_ty_infer(cx, span));
-            let t_infer = build::mk_ty_infer(cx, span);
+            let d_id = cx.ident_of("__d");
 
-            let call_expr = build::mk_method_call(
-                cx,
+            let call_expr = cx.expr_method_call(
                 span,
-                build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+                cx.expr_ident(span, d_id),
                 cx.ident_of("read_enum_variant_arg"),
                 ~[
-                    build::mk_uint(cx, span, j),
-                    build::mk_lambda(cx,
-                                     span,
-                                     build::mk_fn_decl(~[d_arg], t_infer),
-                                     expr),
+                    cx.expr_uint(span, j),
+                    cx.lambda_expr_1(span, expr, d_id),
                 ]
             );
 
             args.push(call_expr);
         }
 
-        build::mk_call(
-            cx,
-            span,
-            ~[variant.node.name],
-            args
-        )
+        cx.expr_call_ident(span, variant.node.name, args)
     };
 
     // Create the arm.
-    build::mk_arm(cx, span, ~[pat], expr)
+    cx.arm(span, ~[pat], expr)
 }
 
 fn create_read_enum_variant(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     enum_definition: &enum_def
 ) -> @expr {
     // Create a vector that contains all the variant names.
-    let expr_arm_names = build::mk_base_vec_e(
-        cx,
+    let expr_arm_names = cx.expr_vec(
         span,
         do enum_definition.variants.map |variant| {
-            build::mk_base_str(
-                cx,
+            cx.expr_str(
                 span,
                 cx.str_of(variant.node.name)
             )
@@ -415,51 +372,24 @@ fn create_read_enum_variant(
     };
 
     // Add the impossible case arm.
-    arms.push(build::mk_unreachable_arm(cx, span));
+    arms.push(cx.arm_unreachable(span));
 
     // Create the read_enum_variant expression.
-    build::mk_method_call(
-        cx,
+    cx.expr_method_call(
         span,
-        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.expr_ident(span, cx.ident_of("__d")),
         cx.ident_of("read_enum_variant"),
         ~[
             expr_arm_names,
-            build::mk_lambda(
-                cx,
-                span,
-                build::mk_fn_decl(
-                    ~[
-                        build::mk_arg(
-                            cx,
-                            span,
-                            cx.ident_of("__d"),
-                            build::mk_ty_infer(cx, span)
-                        ),
-                        build::mk_arg(
-                            cx,
-                            span,
-                            cx.ident_of("__i"),
-                            build::mk_ty_infer(cx, span)
-                        )
-                    ],
-                    build::mk_ty_infer(cx, span)
-                ),
-                build::mk_expr(
-                    cx,
-                    span,
-                    ast::expr_match(
-                        build::mk_path(cx, span, ~[cx.ident_of("__i")]),
-                        arms
-                    )
-                )
-            )
+            cx.lambda_expr(span,
+                           ~[cx.ident_of("__d"), cx.ident_of("__i")],
+                           cx.expr_match(span, cx.expr_ident(span, cx.ident_of("__i")), arms))
         ]
     )
 }
 
 fn expand_deriving_decodable_enum_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     enum_definition: &enum_def,
     type_ident: ast::ident,
@@ -471,24 +401,16 @@ fn expand_deriving_decodable_enum_method(
         enum_definition
     );
 
-    let d_arg = build::mk_arg(cx,
-                              span,
-                              cx.ident_of("__d"),
-                              build::mk_ty_infer(cx, span));
+    let d_id = cx.ident_of("__d");
 
     // Create the read_enum expression
-    let read_enum_expr = build::mk_method_call(
-        cx,
+    let read_enum_expr = cx.expr_method_call(
         span,
-        build::mk_path(cx, span, ~[cx.ident_of("__d")]),
+        cx.expr_ident(span, d_id),
         cx.ident_of("read_enum"),
         ~[
-            build::mk_base_str(cx, span, cx.str_of(type_ident)),
-            build::mk_lambda(cx,
-                             span,
-                             build::mk_fn_decl(~[d_arg],
-                                               build::mk_ty_infer(cx, span)),
-                             read_enum_variant_expr),
+            cx.expr_str(span, cx.str_of(type_ident)),
+            cx.lambda_expr_1(span, read_enum_variant_expr, d_id)
         ]
     );
 
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index b1df8405d76..72a1745f902 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -78,15 +78,15 @@ would yield functions like:
 
 use ast;
 use ast::*;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::*;
 use codemap::{span, spanned};
 use ast_util;
 use opt_vec;
 
 pub fn expand_deriving_encodable(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     _mitem: @meta_item,
     in_items: ~[@item]
@@ -101,34 +101,31 @@ pub fn expand_deriving_encodable(
 }
 
 fn create_derived_encodable_impl(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     type_ident: ident,
     generics: &Generics,
     method: @method
 ) -> @item {
-    let encoder_ty_param = build::mk_ty_param(
-        cx,
+    let encoder_ty_param = cx.typaram(
         cx.ident_of("__E"),
         @opt_vec::with(
-            build::mk_trait_ty_param_bound_global(
-                cx,
-                span,
-                ~[
-                    cx.ident_of("std"),
-                    cx.ident_of("serialize"),
-                    cx.ident_of("Encoder"),
-                ]
-            )
-        )
-    );
+            cx.typarambound(
+                cx.path_global(
+                    span,
+                    ~[
+                        cx.ident_of("std"),
+                        cx.ident_of("serialize"),
+                        cx.ident_of("Encoder"),
+                    ]))));
 
     // All the type parameters need to bound to the trait.
     let generic_ty_params = opt_vec::with(encoder_ty_param);
 
     let methods = [method];
-    let trait_path = build::mk_raw_path_global_(
+    let trait_path = cx.path_all(
         span,
+        true,
         ~[
             cx.ident_of("std"),
             cx.ident_of("serialize"),
@@ -136,7 +133,7 @@ fn create_derived_encodable_impl(
         ],
         None,
         ~[
-            build::mk_simple_ty_path(cx, span, cx.ident_of("__E"))
+            cx.ty_ident(span, cx.ident_of("__E"))
         ]
     );
     create_derived_impl(
@@ -154,29 +151,28 @@ fn create_derived_encodable_impl(
 // Creates a method from the given set of statements conforming to the
 // signature of the `encodable` method.
 fn create_encode_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     statements: ~[@stmt]
 ) -> @method {
     // Create the `e` parameter.
-    let e_arg_type = build::mk_ty_rptr(
-        cx,
+    let e_arg_type = cx.ty_rptr(
         span,
-        build::mk_simple_ty_path(cx, span, cx.ident_of("__E")),
+        cx.ty_ident(span, cx.ident_of("__E")),
         None,
         ast::m_mutbl
     );
-    let e_arg = build::mk_arg(cx, span, cx.ident_of("__e"), e_arg_type);
+    let e_arg = cx.arg(span, cx.ident_of("__e"), e_arg_type);
 
     // Create the type of the return value.
-    let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span };
+    let output_type = cx.ty_nil();
 
     // Create the function declaration.
     let inputs = ~[e_arg];
-    let fn_decl = build::mk_fn_decl(inputs, output_type);
+    let fn_decl = cx.fn_decl(inputs, output_type);
 
     // Create the body block.
-    let body_block = build::mk_block_(cx, span, statements);
+    let body_block = cx.blk(span, statements, None);
 
     // Create the method.
     let explicit_self = spanned { node: sty_region(None, m_imm), span: span };
@@ -197,18 +193,17 @@ fn create_encode_method(
 }
 
 fn call_substructure_encode_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     self_field: @expr
 ) -> @ast::expr {
     // Gather up the parameters we want to chain along.
     let e_ident = cx.ident_of("__e");
-    let e_expr = build::mk_path(cx, span, ~[e_ident]);
+    let e_expr = cx.expr_ident(span, e_ident);
 
     // Call the substructure method.
     let encode_ident = cx.ident_of("encode");
-    build::mk_method_call(
-        cx,
+    cx.expr_method_call(
         span,
         self_field,
         encode_ident,
@@ -217,7 +212,7 @@ fn call_substructure_encode_method(
 }
 
 fn expand_deriving_encodable_struct_def(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     struct_def: &struct_def,
     type_ident: ident,
@@ -242,7 +237,7 @@ fn expand_deriving_encodable_struct_def(
 }
 
 fn expand_deriving_encodable_enum_def(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     enum_definition: &enum_def,
     type_ident: ident,
@@ -267,7 +262,7 @@ fn expand_deriving_encodable_enum_def(
 }
 
 fn expand_deriving_encodable_struct_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     type_ident: ident,
     struct_def: &struct_def
@@ -279,10 +274,9 @@ fn expand_deriving_encodable_struct_method(
         match struct_field.node.kind {
             named_field(ident, _) => {
                 // Create the accessor for this field.
-                let self_field = build::mk_access_(cx,
-                                                   span,
-                                                   build::make_self(cx, span),
-                                                   ident);
+                let self_field = cx.expr_field_access(span,
+                                                      cx.expr_self(span),
+                                                      ident);
 
                 // Call the substructure method.
                 let encode_expr = call_substructure_encode_method(
@@ -292,31 +286,19 @@ fn expand_deriving_encodable_struct_method(
                 );
 
                 let e_ident = cx.ident_of("__e");
-                let e_arg = build::mk_arg(cx,
-                                          span,
-                                          e_ident,
-                                          build::mk_ty_infer(cx, span));
 
-                let blk_expr = build::mk_lambda(
-                    cx,
+                let call_expr = cx.expr_method_call(
                     span,
-                    build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
-                    encode_expr
-                );
-
-                let call_expr = build::mk_method_call(
-                    cx,
-                    span,
-                    build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+                    cx.expr_ident(span, e_ident),
                     cx.ident_of("emit_struct_field"),
                     ~[
-                        build::mk_base_str(cx, span, cx.str_of(ident)),
-                        build::mk_uint(cx, span, idx),
-                        blk_expr
+                        cx.expr_str(span, cx.str_of(ident)),
+                        cx.expr_uint(span, idx),
+                        cx.lambda_expr_1(span, encode_expr, e_ident)
                     ]
                 );
 
-                statements.push(build::mk_stmt(cx, span, call_expr));
+                statements.push(cx.stmt_expr(call_expr));
             }
             unnamed_field => {
                 cx.span_unimpl(
@@ -328,40 +310,26 @@ fn expand_deriving_encodable_struct_method(
         idx += 1;
     }
 
-    let e_arg = build::mk_arg(cx,
-                              span,
-                              cx.ident_of("__e"),
-                              build::mk_ty_infer(cx, span));
-
-    let emit_struct_stmt = build::mk_method_call(
-        cx,
+    let e_id = cx.ident_of("__e");
+    let emit_struct_stmt = cx.expr_method_call(
         span,
-        build::mk_path(
-            cx,
-            span,
-            ~[cx.ident_of("__e")]
-        ),
+        cx.expr_ident(span, e_id),
         cx.ident_of("emit_struct"),
         ~[
-            build::mk_base_str(cx, span, cx.str_of(type_ident)),
-            build::mk_uint(cx, span, statements.len()),
-            build::mk_lambda_stmts(
-                cx,
-                span,
-                build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
-                statements
-            ),
+            cx.expr_str(span, cx.str_of(type_ident)),
+            cx.expr_uint(span, statements.len()),
+            cx.lambda_stmts_1(span, statements, e_id),
         ]
     );
 
-    let statements = ~[build::mk_stmt(cx, span, emit_struct_stmt)];
+    let statements = ~[cx.stmt_expr(emit_struct_stmt)];
 
     // Create the method itself.
     return create_encode_method(cx, span, statements);
 }
 
 fn expand_deriving_encodable_enum_method(
-    cx: @ext_ctxt,
+    cx: @ExtCtxt,
     span: span,
     type_ident: ast::ident,
     enum_definition: &enum_def
@@ -382,91 +350,59 @@ fn expand_deriving_encodable_enum_method(
             let expr = call_substructure_encode_method(cx, span, field);
 
             let e_ident = cx.ident_of("__e");
-            let e_arg = build::mk_arg(cx,
-                                      span,
-                                      e_ident,
-                                      build::mk_ty_infer(cx, span));
-
-            let blk_expr = build::mk_lambda(
-                cx,
-                span,
-                build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
-                expr
-            );
-
-            let call_expr = build::mk_method_call(
-                cx,
+            let call_expr = cx.expr_method_call(
                 span,
-                build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+                cx.expr_ident(span, e_ident),
                 cx.ident_of("emit_enum_variant_arg"),
                 ~[
-                    build::mk_uint(cx, span, j),
-                    blk_expr,
+                    cx.expr_uint(span, j),
+                    cx.lambda_expr_1(span, expr, e_ident),
                 ]
             );
 
-            stmts.push(build::mk_stmt(cx, span, call_expr));
+            stmts.push(cx.stmt_expr(call_expr));
         }
 
         // Create the pattern body.
-        let e_arg = build::mk_arg(cx,
-                                  span,
-                                  cx.ident_of("__e"),
-                                  build::mk_ty_infer(cx, span));
-        let call_expr = build::mk_method_call(
-            cx,
+        let e_id = cx.ident_of("__e");
+
+        let call_expr = cx.expr_method_call(
             span,
-            build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+            cx.expr_ident(span, e_id),
             cx.ident_of("emit_enum_variant"),
             ~[
-                build::mk_base_str(cx, span, cx.str_of(variant.node.name)),
-                build::mk_uint(cx, span, i),
-                build::mk_uint(cx, span, variant_arg_len),
-                build::mk_lambda_stmts(
-                    cx,
-                    span,
-                    build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
-                    stmts
-                )
+                cx.expr_str(span, cx.str_of(variant.node.name)),
+                cx.expr_uint(span, i),
+                cx.expr_uint(span, variant_arg_len),
+                cx.lambda_stmts_1(span, stmts, e_id)
             ]
         );
 
-        let match_body_block = build::mk_simple_block(cx, span, call_expr);
+        //let match_body_block = cx.blk_expr(call_expr);
 
         // Create the arm.
-        ast::arm {
-            pats: ~[pat],
-            guard: None,
-            body: match_body_block,
-        }
+        cx.arm(span, ~[pat], call_expr) //match_body_block)
     };
 
     let e_ident = cx.ident_of("__e");
-    let e_arg = build::mk_arg(cx,
-                              span,
-                              e_ident,
-                              build::mk_ty_infer(cx, span));
 
     // Create the method body.
-    let lambda_expr = build::mk_lambda(
-        cx,
+    let lambda_expr = cx.lambda_expr_1(
         span,
-        build::mk_fn_decl(~[e_arg], build::mk_ty_infer(cx, span)),
-        expand_enum_or_struct_match(cx, span, arms)
-    );
+        expand_enum_or_struct_match(cx, span, arms),
+        e_ident);
 
-    let call_expr = build::mk_method_call(
-        cx,
+    let call_expr = cx.expr_method_call(
         span,
-        build::mk_path(cx, span, ~[cx.ident_of("__e")]),
+        cx.expr_ident(span, e_ident),
         cx.ident_of("emit_enum"),
         ~[
-            build::mk_base_str(cx, span, cx.str_of(type_ident)),
+            cx.expr_str(span, cx.str_of(type_ident)),
             lambda_expr,
         ]
     );
 
-    let stmt = build::mk_stmt(cx, span, call_expr);
+    let stmt = cx.stmt_expr(call_expr);
 
     // Create the method.
     create_encode_method(cx, span, ~[stmt])
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index 2fc9dadfe2c..b61c78721fe 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -165,8 +165,8 @@ StaticEnum(<ast::enum_def of C>, ~[(<ident of C0>, Left(1)),
 use ast;
 use ast::{enum_def, expr, ident, Generics, struct_def};
 
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::*;
 use codemap::{span,respan};
 use opt_vec;
@@ -174,7 +174,7 @@ use opt_vec;
 pub use self::ty::*;
 mod ty;
 
-pub fn expand_deriving_generic(cx: @ext_ctxt,
+pub fn expand_deriving_generic(cx: @ExtCtxt,
                                span: span,
                                _mitem: @ast::meta_item,
                                in_items: ~[@ast::item],
@@ -195,13 +195,13 @@ pub fn expand_deriving_generic(cx: @ext_ctxt,
 
 pub struct TraitDef<'self> {
     /// Path of the trait, including any type parameters
-    path: Path,
+    path: Path<'self>,
     /// Additional bounds required of any type parameters of the type,
     /// other than the current trait
-    additional_bounds: ~[Ty],
+    additional_bounds: ~[Ty<'self>],
 
     /// Any extra lifetimes and/or bounds, e.g. `D: std::serialize::Decoder`
-    generics: LifetimeBounds,
+    generics: LifetimeBounds<'self>,
 
     methods: ~[MethodDef<'self>]
 }
@@ -209,20 +209,20 @@ pub struct TraitDef<'self> {
 
 pub struct MethodDef<'self> {
     /// name of the method
-    name: ~str,
+    name: &'self str,
     /// List of generics, e.g. `R: core::rand::Rng`
-    generics: LifetimeBounds,
+    generics: LifetimeBounds<'self>,
 
     /// Whether there is a self argument (outer Option) i.e. whether
     /// this is a static function, and whether it is a pointer (inner
     /// Option)
-    explicit_self: Option<Option<PtrTy>>,
+    explicit_self: Option<Option<PtrTy<'self>>>,
 
     /// Arguments other than the self argument
-    args: ~[Ty],
+    args: ~[Ty<'self>],
 
     /// Return type
-    ret_ty: Ty,
+    ret_ty: Ty<'self>,
 
     /// if the value of the nonmatching enums is independent of the
     /// actual enum variants, i.e. can use _ => .. match.
@@ -281,7 +281,7 @@ Combine the values of all the fields together. The last argument is
 all the fields of all the structures, see above for details.
 */
 pub type CombineSubstructureFunc<'self> =
-    &'self fn(@ext_ctxt, span, &Substructure) -> @expr;
+    &'self fn(@ExtCtxt, span, &Substructure) -> @expr;
 
 /**
 Deal with non-matching enum variants, the arguments are a list
@@ -289,14 +289,14 @@ representing each variant: (variant index, ast::variant instance,
 [variant fields]), and a list of the nonself args of the type
 */
 pub type EnumNonMatchFunc<'self> =
-    &'self fn(@ext_ctxt, span,
+    &'self fn(@ExtCtxt, span,
               &[(uint, ast::variant,
                  ~[(Option<ident>, @expr)])],
               &[@expr]) -> @expr;
 
 
 impl<'self> TraitDef<'self> {
-    fn create_derived_impl(&self, cx: @ext_ctxt, span: span,
+    fn create_derived_impl(&self, cx: @ExtCtxt, span: span,
                            type_ident: ident, generics: &Generics,
                            methods: ~[@ast::method]) -> @ast::item {
         let trait_path = self.path.to_path(cx, span, type_ident, generics);
@@ -315,7 +315,7 @@ impl<'self> TraitDef<'self> {
                             additional_bounds)
     }
 
-    fn expand_struct_def(&self, cx: @ext_ctxt,
+    fn expand_struct_def(&self, cx: @ExtCtxt,
                          span: span,
                          struct_def: &struct_def,
                          type_ident: ident,
@@ -347,7 +347,7 @@ impl<'self> TraitDef<'self> {
     }
 
     fn expand_enum_def(&self,
-                       cx: @ext_ctxt, span: span,
+                       cx: @ExtCtxt, span: span,
                        enum_def: &enum_def,
                        type_ident: ident,
                        generics: &Generics) -> @ast::item {
@@ -380,7 +380,7 @@ impl<'self> TraitDef<'self> {
 
 impl<'self> MethodDef<'self> {
     fn call_substructure_method(&self,
-                                cx: @ext_ctxt,
+                                cx: @ExtCtxt,
                                 span: span,
                                 type_ident: ident,
                                 self_args: &[@expr],
@@ -398,7 +398,7 @@ impl<'self> MethodDef<'self> {
                                     &substructure)
     }
 
-    fn get_ret_ty(&self, cx: @ext_ctxt, span: span,
+    fn get_ret_ty(&self, cx: @ExtCtxt, span: span,
                      generics: &Generics, type_ident: ident) -> @ast::Ty {
         self.ret_ty.to_ty(cx, span, type_ident, generics)
     }
@@ -407,7 +407,7 @@ impl<'self> MethodDef<'self> {
         self.explicit_self.is_none()
     }
 
-    fn split_self_nonself_args(&self, cx: @ext_ctxt, span: span,
+    fn split_self_nonself_args(&self, cx: @ExtCtxt, span: span,
                              type_ident: ident, generics: &Generics)
         -> (ast::explicit_self, ~[@expr], ~[@expr], ~[(ident, @ast::Ty)]) {
 
@@ -431,7 +431,7 @@ impl<'self> MethodDef<'self> {
             let ident = cx.ident_of(fmt!("__arg_%u", i));
             arg_tys.push((ident, ast_ty));
 
-            let arg_expr = build::mk_path(cx, span, ~[ident]);
+            let arg_expr = cx.expr_ident(span, ident);
 
             match *ty {
                 // for static methods, just treat any Self
@@ -440,7 +440,7 @@ impl<'self> MethodDef<'self> {
                     self_args.push(arg_expr);
                 }
                 Ptr(~Self, _) if nonstatic => {
-                    self_args.push(build::mk_deref(cx, span, arg_expr))
+                    self_args.push(cx.expr_deref(span, arg_expr))
                 }
                 _ => {
                     nonself_args.push(arg_expr);
@@ -451,7 +451,7 @@ impl<'self> MethodDef<'self> {
         (ast_explicit_self, self_args, nonself_args, arg_tys)
     }
 
-    fn create_method(&self, cx: @ext_ctxt, span: span,
+    fn create_method(&self, cx: @ExtCtxt, span: span,
                      type_ident: ident,
                      generics: &Generics,
                      explicit_self: ast::explicit_self,
@@ -461,14 +461,14 @@ impl<'self> MethodDef<'self> {
         let fn_generics = self.generics.to_generics(cx, span, type_ident, generics);
 
         let args = do arg_types.map |&(id, ty)| {
-            build::mk_arg(cx, span, id, ty)
+            cx.arg(span, id, ty)
         };
 
         let ret_type = self.get_ret_ty(cx, span, generics, type_ident);
 
         let method_ident = cx.ident_of(self.name);
-        let fn_decl = build::mk_fn_decl(args, ret_type);
-        let body_block = build::mk_simple_block(cx, span, body);
+        let fn_decl = cx.fn_decl(args, ret_type);
+        let body_block = cx.blk_expr(body);
 
 
         // Create the method.
@@ -509,7 +509,7 @@ impl<'self> MethodDef<'self> {
     ~~~
     */
     fn expand_struct_method_body(&self,
-                                 cx: @ext_ctxt,
+                                 cx: @ExtCtxt,
                                  span: span,
                                  struct_def: &struct_def,
                                  type_ident: ident,
@@ -555,19 +555,14 @@ impl<'self> MethodDef<'self> {
         // structs. This is actually right-to-left, but it shoudn't
         // matter.
         for vec::each2(self_args, patterns) |&arg_expr, &pat| {
-            let match_arm = ast::arm {
-                pats: ~[ pat ],
-                guard: None,
-                body: build::mk_simple_block(cx, span, body)
-            };
-
-            body = build::mk_expr(cx, span, ast::expr_match(arg_expr, ~[match_arm]))
+            body = cx.expr_match(span, arg_expr,
+                                 ~[ cx.arm(span, ~[pat], body) ])
         }
         body
     }
 
     fn expand_static_struct_method_body(&self,
-                                        cx: @ext_ctxt,
+                                        cx: @ExtCtxt,
                                         span: span,
                                         struct_def: &struct_def,
                                         type_ident: ident,
@@ -609,7 +604,7 @@ impl<'self> MethodDef<'self> {
     ~~~
     */
     fn expand_enum_method_body(&self,
-                               cx: @ext_ctxt,
+                               cx: @ExtCtxt,
                                span: span,
                                enum_def: &enum_def,
                                type_ident: ident,
@@ -645,7 +640,7 @@ impl<'self> MethodDef<'self> {
     the first call).
     */
     fn build_enum_match(&self,
-                        cx: @ext_ctxt, span: span,
+                        cx: @ExtCtxt, span: span,
                         enum_def: &enum_def,
                         type_ident: ident,
                         self_args: &[@expr],
@@ -690,7 +685,7 @@ impl<'self> MethodDef<'self> {
                     }
                     let field_tuples =
                         do vec::map_zip(*self_vec,
-                                     enum_matching_fields) |&(id, self_f), &other| {
+                                        enum_matching_fields) |&(id, self_f), &other| {
                         (id, self_f, other)
                     };
                     substructure = EnumMatching(variant_index, variant, field_tuples);
@@ -738,16 +733,16 @@ impl<'self> MethodDef<'self> {
                                                      matches_so_far,
                                                      match_count + 1);
                 matches_so_far.pop();
-                arms.push(build::mk_arm(cx, span, ~[ pattern ], arm_expr));
+                arms.push(cx.arm(span, ~[ pattern ], arm_expr));
 
                 if enum_def.variants.len() > 1 {
                     let e = &EnumNonMatching(&[]);
                     let wild_expr = self.call_substructure_method(cx, span, type_ident,
                                                                   self_args, nonself_args,
                                                                   e);
-                    let wild_arm = build::mk_arm(cx, span,
-                                                 ~[ build::mk_pat_wild(cx, span) ],
-                                                 wild_expr);
+                    let wild_arm = cx.arm(span,
+                                          ~[ cx.pat_wild(span) ],
+                                          wild_expr);
                     arms.push(wild_arm);
                 }
             } else {
@@ -774,19 +769,18 @@ impl<'self> MethodDef<'self> {
                                                          match_count + 1);
                     matches_so_far.pop();
 
-                    let arm = build::mk_arm(cx, span, ~[ pattern ], arm_expr);
+                    let arm = cx.arm(span, ~[ pattern ], arm_expr);
                     arms.push(arm);
                 }
             }
 
             // match foo { arm, arm, arm, ... }
-            build::mk_expr(cx, span,
-                           ast::expr_match(self_args[match_count], arms))
+            cx.expr_match(span, self_args[match_count], arms)
         }
     }
 
     fn expand_static_enum_method_body(&self,
-                               cx: @ext_ctxt,
+                               cx: @ExtCtxt,
                                span: span,
                                enum_def: &enum_def,
                                type_ident: ident,
@@ -810,7 +804,7 @@ impl<'self> MethodDef<'self> {
     }
 }
 
-fn summarise_struct(cx: @ext_ctxt, span: span,
+fn summarise_struct(cx: @ExtCtxt, span: span,
                     struct_def: &struct_def) -> Either<uint, ~[ident]> {
     let mut named_idents = ~[];
     let mut unnamed_count = 0;
@@ -840,12 +834,12 @@ Fold the fields. `use_foldl` controls whether this is done
 left-to-right (`true`) or right-to-left (`false`).
 */
 pub fn cs_fold(use_foldl: bool,
-               f: &fn(@ext_ctxt, span,
+               f: &fn(@ExtCtxt, span,
                       old: @expr,
                       self_f: @expr, other_fs: &[@expr]) -> @expr,
                base: @expr,
                enum_nonmatch_f: EnumNonMatchFunc,
-               cx: @ext_ctxt, span: span,
+               cx: @ExtCtxt, span: span,
                substructure: &Substructure) -> @expr {
     match *substructure.fields {
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
@@ -879,18 +873,18 @@ f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
 ~~~
 */
 #[inline(always)]
-pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr,
+pub fn cs_same_method(f: &fn(@ExtCtxt, span, ~[@expr]) -> @expr,
                       enum_nonmatch_f: EnumNonMatchFunc,
-                      cx: @ext_ctxt, span: span,
+                      cx: @ExtCtxt, span: span,
                       substructure: &Substructure) -> @expr {
     match *substructure.fields {
         EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
             // call self_n.method(other_1_n, other_2_n, ...)
             let called = do all_fields.map |&(_, self_field, other_fields)| {
-                build::mk_method_call(cx, span,
-                                      self_field,
-                                      substructure.method_ident,
-                                      other_fields)
+                cx.expr_method_call(span,
+                                    self_field,
+                                    substructure.method_ident,
+                                    other_fields)
             };
 
             f(cx, span, called)
@@ -911,10 +905,10 @@ fields. `use_foldl` controls whether this is done left-to-right
 */
 #[inline(always)]
 pub fn cs_same_method_fold(use_foldl: bool,
-                           f: &fn(@ext_ctxt, span, @expr, @expr) -> @expr,
+                           f: &fn(@ExtCtxt, span, @expr, @expr) -> @expr,
                            base: @expr,
                            enum_nonmatch_f: EnumNonMatchFunc,
-                           cx: @ext_ctxt, span: span,
+                           cx: @ExtCtxt, span: span,
                            substructure: &Substructure) -> @expr {
     cs_same_method(
         |cx, span, vals| {
@@ -940,14 +934,14 @@ on all the fields.
 #[inline(always)]
 pub fn cs_binop(binop: ast::binop, base: @expr,
                 enum_nonmatch_f: EnumNonMatchFunc,
-                cx: @ext_ctxt, span: span,
+                cx: @ExtCtxt, span: span,
                 substructure: &Substructure) -> @expr {
     cs_same_method_fold(
         true, // foldl is good enough
         |cx, span, old, new| {
-            build::mk_binary(cx, span,
-                             binop,
-                             old, new)
+            cx.expr_binary(span,
+                           binop,
+                           old, new)
 
         },
         base,
@@ -958,18 +952,18 @@ pub fn cs_binop(binop: ast::binop, base: @expr,
 /// cs_binop with binop == or
 #[inline(always)]
 pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
-             cx: @ext_ctxt, span: span,
+             cx: @ExtCtxt, span: span,
              substructure: &Substructure) -> @expr {
-    cs_binop(ast::or, build::mk_bool(cx, span, false),
+    cs_binop(ast::or, cx.expr_bool(span, false),
              enum_nonmatch_f,
              cx, span, substructure)
 }
 /// cs_binop with binop == and
 #[inline(always)]
 pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
-              cx: @ext_ctxt, span: span,
+              cx: @ExtCtxt, span: span,
               substructure: &Substructure) -> @expr {
-    cs_binop(ast::and, build::mk_bool(cx, span, true),
+    cs_binop(ast::and, cx.expr_bool(span, true),
              enum_nonmatch_f,
              cx, span, substructure)
 }
diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs
index 1c9ec6ece2e..ae321c3e409 100644
--- a/src/libsyntax/ext/deriving/iter_bytes.rs
+++ b/src/libsyntax/ext/deriving/iter_bytes.rs
@@ -10,28 +10,28 @@
 
 use ast::{meta_item, item, expr, and};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
+pub fn expand_deriving_iter_bytes(cx: @ExtCtxt,
                                   span: span,
                                   mitem: @meta_item,
                                   in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"to_bytes", ~"IterBytes"]),
+        path: Path::new(~["core", "to_bytes", "IterBytes"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
-                name: ~"iter_bytes",
+                name: "iter_bytes",
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[
-                    Literal(Path::new(~[~"bool"])),
-                    Literal(Path::new(~[~"core", ~"to_bytes", ~"Cb"]))
+                    Literal(Path::new(~["bool"])),
+                    Literal(Path::new(~["core", "to_bytes", "Cb"]))
                 ],
-                ret_ty: Literal(Path::new(~[~"bool"])),
+                ret_ty: Literal(Path::new(~["bool"])),
                 const_nonmatching: false,
                 combine_substructure: iter_bytes_substructure
             }
@@ -41,14 +41,14 @@ pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
     expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
 }
 
-fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
+fn iter_bytes_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
     let lsb0_f = match substr.nonself_args {
         [l, f] => ~[l, f],
         _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`")
     };
     let iter_bytes_ident = substr.method_ident;
     let call_iterbytes = |thing_expr| {
-        build::mk_method_call(cx, span,
+        cx.expr_method_call(span,
                               thing_expr, iter_bytes_ident,
                               copy lsb0_f)
     };
@@ -63,7 +63,7 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
             // iteration function.
             let discriminant = match variant.node.disr_expr {
                 Some(copy d)=> d,
-                None => build::mk_uint(cx, span, index)
+                None => cx.expr_uint(span, index)
             };
 
             exprs.push(call_iterbytes(discriminant));
@@ -82,6 +82,6 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
     }
 
     do vec::foldl(exprs[0], exprs.slice(1, exprs.len())) |prev, me| {
-        build::mk_binary(cx, span, and, prev, *me)
+        cx.expr_binary(span, and, prev, *me)
     }
 }
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 6f4429af12d..7da66f88ca9 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -20,9 +20,9 @@ library.
 
 use ast;
 use ast::{Ty, enum_def, expr, ident, item, Generics, meta_item, struct_def};
-use ext::base::ext_ctxt;
-use ext::build;
-use codemap::{span, respan};
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
+use codemap::span;
 use parse::token::special_idents::clownshoes_extensions;
 use opt_vec;
 
@@ -45,20 +45,20 @@ pub mod totalord;
 
 pub mod generic;
 
-pub type ExpandDerivingStructDefFn<'self> = &'self fn(@ext_ctxt,
+pub type ExpandDerivingStructDefFn<'self> = &'self fn(@ExtCtxt,
                                                        span,
                                                        x: &struct_def,
                                                        ident,
                                                        y: &Generics)
                                                  -> @item;
-pub type ExpandDerivingEnumDefFn<'self> = &'self fn(@ext_ctxt,
+pub type ExpandDerivingEnumDefFn<'self> = &'self fn(@ExtCtxt,
                                                     span,
                                                     x: &enum_def,
                                                     ident,
                                                     y: &Generics)
                                                  -> @item;
 
-pub fn expand_meta_deriving(cx: @ext_ctxt,
+pub fn expand_meta_deriving(cx: @ExtCtxt,
                             _span: span,
                             mitem: @meta_item,
                             in_items: ~[@item])
@@ -113,7 +113,7 @@ pub fn expand_meta_deriving(cx: @ext_ctxt,
     }
 }
 
-pub fn expand_deriving(cx: @ext_ctxt,
+pub fn expand_deriving(cx: @ExtCtxt,
                    span: span,
                    in_items: ~[@item],
                    expand_deriving_struct_def: ExpandDerivingStructDefFn,
@@ -143,38 +143,15 @@ pub fn expand_deriving(cx: @ext_ctxt,
     result
 }
 
-fn create_impl_item(cx: @ext_ctxt, span: span, item: ast::item_) -> @item {
-    let doc_attr = respan(span,
-                          ast::lit_str(@~"Automatically derived."));
-    let doc_attr = respan(span, ast::meta_name_value(@~"doc", doc_attr));
-    let doc_attr = ast::attribute_ {
-        style: ast::attr_outer,
-        value: @doc_attr,
-        is_sugared_doc: false
-    };
-    let doc_attr = respan(span, doc_attr);
-
-    @ast::item {
-        ident: clownshoes_extensions,
-        attrs: ~[doc_attr],
-        id: cx.next_id(),
-        node: item,
-        vis: ast::public,
-        span: span,
-    }
-}
-
-pub fn create_self_type_with_params(cx: @ext_ctxt,
-                                span: span,
-                                type_ident: ident,
-                                generics: &Generics)
-                             -> @Ty {
+pub fn create_self_type_with_params(cx: @ExtCtxt,
+                                    span: span,
+                                    type_ident: ident,
+                                    generics: &Generics)
+    -> @Ty {
     // Create the type parameters on the `self` path.
     let mut self_ty_params = ~[];
     for generics.ty_params.each |ty_param| {
-        let self_ty_param = build::mk_simple_ty_path(cx,
-                                                     span,
-                                                     ty_param.ident);
+        let self_ty_param = cx.ty_ident(span, ty_param.ident);
         self_ty_params.push(self_ty_param);
     }
 
@@ -186,14 +163,10 @@ pub fn create_self_type_with_params(cx: @ext_ctxt,
 
 
     // Create the type of `self`.
-    let self_type = build::mk_raw_path_(span,
-                                        ~[ type_ident ],
-                                        lifetime,
-                                        self_ty_params);
-    build::mk_ty_path_path(cx, span, self_type)
+    cx.ty_path(cx.path_all(span, false, ~[ type_ident ], lifetime, self_ty_params))
 }
 
-pub fn create_derived_impl(cx: @ext_ctxt,
+pub fn create_derived_impl(cx: @ExtCtxt,
                            span: span,
                            type_ident: ident,
                            generics: &Generics,
@@ -222,18 +195,17 @@ pub fn create_derived_impl(cx: @ext_ctxt,
     for generics.ty_params.each |ty_param| {
         // extra restrictions on the generics parameters to the type being derived upon
         let mut bounds = do bounds_paths.map |&bound_path| {
-            build::mk_trait_ty_param_bound_(cx, bound_path)
+            cx.typarambound(bound_path)
         };
 
-        let this_trait_bound =
-            build::mk_trait_ty_param_bound_(cx, trait_path);
+        let this_trait_bound = cx.typarambound(trait_path);
         bounds.push(this_trait_bound);
 
-        impl_generics.ty_params.push(build::mk_ty_param(cx, ty_param.ident, @bounds));
+        impl_generics.ty_params.push(cx.typaram(ty_param.ident, @bounds));
     }
 
     // Create the reference to the trait.
-    let trait_ref = build::mk_trait_ref_(cx, trait_path);
+    let trait_ref = cx.trait_ref(trait_path);
 
     // Create the type of `self`.
     let self_type = create_self_type_with_params(cx,
@@ -241,21 +213,27 @@ pub fn create_derived_impl(cx: @ext_ctxt,
                                                  type_ident,
                                                  generics);
 
-    // Create the impl item.
-    let impl_item = ast::item_impl(impl_generics,
-                              Some(trait_ref),
-                              self_type,
-                              methods.map(|x| *x));
-    return create_impl_item(cx, span, impl_item);
+    let doc_attr = cx.attribute(
+        span,
+        cx.meta_name_value(span,
+                           ~"doc", ast::lit_str(@~"Automatically derived.")));
+    cx.item(
+        span,
+        clownshoes_extensions,
+        ~[doc_attr],
+        ast::item_impl(impl_generics,
+                       Some(trait_ref),
+                       self_type,
+                       methods.map(|x| *x)))
 }
 
-pub fn create_subpatterns(cx: @ext_ctxt,
+pub fn create_subpatterns(cx: @ExtCtxt,
                           span: span,
                           field_paths: ~[@ast::Path],
                           mutbl: ast::mutability)
                    -> ~[@ast::pat] {
     do field_paths.map |&path| {
-        build::mk_pat(cx, span,
+        cx.pat(span,
                       ast::pat_ident(ast::bind_by_ref(mutbl), path, None))
     }
 }
@@ -265,7 +243,7 @@ enum StructType {
     Unknown, Record, Tuple
 }
 
-pub fn create_struct_pattern(cx: @ext_ctxt,
+pub fn create_struct_pattern(cx: @ExtCtxt,
                              span: span,
                              struct_ident: ident,
                              struct_def: &struct_def,
@@ -274,12 +252,12 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
     -> (@ast::pat, ~[(Option<ident>, @expr)]) {
     if struct_def.fields.is_empty() {
         return (
-            build::mk_pat_ident_with_binding_mode(
-                cx, span, struct_ident, ast::bind_infer),
+            cx.pat_ident_binding_mode(
+                span, struct_ident, ast::bind_infer),
             ~[]);
     }
 
-    let matching_path = build::mk_raw_path(span, ~[ struct_ident ]);
+    let matching_path = cx.path(span, ~[ struct_ident ]);
 
     let mut paths = ~[], ident_expr = ~[];
 
@@ -301,10 +279,10 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
                 cx.span_bug(span, "A struct with named and unnamed fields in `deriving`");
             }
         };
-        let path = build::mk_raw_path(span,
-                                      ~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]);
+        let path = cx.path_ident(span,
+                                 cx.ident_of(fmt!("%s_%u", prefix, i)));
         paths.push(path);
-        ident_expr.push((opt_id, build::mk_path_raw(cx, span, path)));
+        ident_expr.push((opt_id, cx.expr_path(path)));
     }
 
     let subpats = create_subpatterns(cx, span, paths, mutbl);
@@ -318,15 +296,15 @@ pub fn create_struct_pattern(cx: @ext_ctxt,
                 push(ast::field_pat { ident: id.get(), pat: pat })
             }
         };
-        build::mk_pat_struct(cx, span, matching_path, field_pats)
+        cx.pat_struct(span, matching_path, field_pats)
     } else {
-        build::mk_pat_enum(cx, span, matching_path, subpats)
+        cx.pat_enum(span, matching_path, subpats)
     };
 
     (pattern, ident_expr)
 }
 
-pub fn create_enum_variant_pattern(cx: @ext_ctxt,
+pub fn create_enum_variant_pattern(cx: @ExtCtxt,
                                    span: span,
                                    variant: &ast::variant,
                                    prefix: &str,
@@ -337,24 +315,24 @@ pub fn create_enum_variant_pattern(cx: @ext_ctxt,
     match variant.node.kind {
         ast::tuple_variant_kind(ref variant_args) => {
             if variant_args.is_empty() {
-                return (build::mk_pat_ident_with_binding_mode(
-                    cx, span, variant_ident, ast::bind_infer), ~[]);
+                return (cx.pat_ident_binding_mode(
+                    span, variant_ident, ast::bind_infer), ~[]);
             }
 
-            let matching_path = build::mk_raw_path(span, ~[ variant_ident ]);
+            let matching_path = cx.path_ident(span, variant_ident);
 
             let mut paths = ~[], ident_expr = ~[];
             for uint::range(0, variant_args.len()) |i| {
-                let path = build::mk_raw_path(span,
-                                              ~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]);
+                let path = cx.path_ident(span,
+                                         cx.ident_of(fmt!("%s_%u", prefix, i)));
 
                 paths.push(path);
-                ident_expr.push((None, build::mk_path_raw(cx, span, path)));
+                ident_expr.push((None, cx.expr_path(path)));
             }
 
             let subpats = create_subpatterns(cx, span, paths, mutbl);
 
-            (build::mk_pat_enum(cx, span, matching_path, subpats),
+            (cx.pat_enum(span, matching_path, subpats),
              ident_expr)
         }
         ast::struct_variant_kind(struct_def) => {
@@ -366,19 +344,17 @@ pub fn create_enum_variant_pattern(cx: @ext_ctxt,
     }
 }
 
-pub fn variant_arg_count(_cx: @ext_ctxt, _span: span, variant: &ast::variant) -> uint {
+pub fn variant_arg_count(_cx: @ExtCtxt, _span: span, variant: &ast::variant) -> uint {
     match variant.node.kind {
         ast::tuple_variant_kind(ref args) => args.len(),
         ast::struct_variant_kind(ref struct_def) => struct_def.fields.len(),
     }
 }
 
-pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
+pub fn expand_enum_or_struct_match(cx: @ExtCtxt,
                                span: span,
                                arms: ~[ ast::arm ])
                             -> @expr {
-    let self_expr = build::make_self(cx, span);
-    let self_expr = build::mk_unary(cx, span, ast::deref, self_expr);
-    let self_match_expr = ast::expr_match(self_expr, arms);
-    build::mk_expr(cx, span, self_match_expr)
+    let self_expr = cx.expr_deref(span, cx.expr_self(span));
+    cx.expr_match(span, self_expr, arms)
 }
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index 2d91fcd346a..16f754727b0 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -11,30 +11,30 @@
 use ast;
 use ast::{meta_item, item, expr, ident};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::{AstBuilder, Duplicate};
 use ext::deriving::generic::*;
 
-pub fn expand_deriving_rand(cx: @ext_ctxt,
+pub fn expand_deriving_rand(cx: @ExtCtxt,
                             span: span,
                             mitem: @meta_item,
                             in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"rand", ~"Rand"]),
+        path: Path::new(~["core", "rand", "Rand"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
-                name: ~"rand",
+                name: "rand",
                 generics: LifetimeBounds {
                     lifetimes: ~[],
-                    bounds: ~[(~"R",
-                               ~[ Path::new(~[~"core", ~"rand", ~"Rng"]) ])]
+                    bounds: ~[("R",
+                               ~[ Path::new(~["core", "rand", "Rng"]) ])]
                 },
                 explicit_self: None,
                 args: ~[
-                    Ptr(~Literal(Path::new_local(~"R")),
+                    Ptr(~Literal(Path::new_local("R")),
                         Borrowed(None, ast::m_mutbl))
                 ],
                 ret_ty: Self,
@@ -47,7 +47,7 @@ pub fn expand_deriving_rand(cx: @ext_ctxt,
     expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
 }
 
-fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
+fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
     let rng = match substr.nonself_args {
         [rng] => ~[ rng ],
         _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
@@ -59,10 +59,9 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
         cx.ident_of("rand")
     ];
     let rand_call = || {
-        build::mk_call_global(cx,
-                              span,
-                              copy rand_ident,
-                              ~[ build::duplicate_expr(cx, rng[0]) ])
+        cx.expr_call_global(span,
+                            copy rand_ident,
+                            ~[ rng[0].duplicate(cx) ])
     };
 
     return match *substr.fields {
@@ -74,67 +73,61 @@ fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr
                 cx.span_fatal(span, "`Rand` cannot be derived for enums with no variants");
             }
 
-            let variant_count = build::mk_uint(cx, span, variants.len());
+            let variant_count = cx.expr_uint(span, variants.len());
 
             // need to specify the uint-ness of the random number
-            let u32_ty = build::mk_ty_path(cx, span, ~[cx.ident_of("uint")]);
-            let r_ty = build::mk_ty_path(cx, span, ~[cx.ident_of("R")]);
-            let rand_name = build::mk_raw_path_(span, copy rand_ident, None, ~[ u32_ty, r_ty ]);
-            let rand_name = build::mk_path_raw(cx, span, rand_name);
+            let u32_ty = cx.ty_ident(span, cx.ident_of("uint"));
+            let r_ty = cx.ty_ident(span, cx.ident_of("R"));
+            let rand_name = cx.path_all(span, false, copy rand_ident, None, ~[ u32_ty, r_ty ]);
+            let rand_name = cx.expr_path(rand_name);
 
-            let rv_call = build::mk_call_(cx,
-                                          span,
-                                          rand_name,
-                                          ~[ build::duplicate_expr(cx, rng[0]) ]);
+            let rv_call = cx.expr_call(span,
+                                       rand_name,
+                                       ~[ rng[0].duplicate(cx) ]);
 
             // rand() % variants.len()
-            let rand_variant = build::mk_binary(cx, span, ast::rem,
+            let rand_variant = cx.expr_binary(span, ast::rem,
                                                 rv_call, variant_count);
 
             let mut arms = do variants.mapi |i, id_sum| {
-                let i_expr = build::mk_uint(cx, span, i);
-                let pat = build::mk_pat_lit(cx, span, i_expr);
+                let i_expr = cx.expr_uint(span, i);
+                let pat = cx.pat_lit(span, i_expr);
 
                 match *id_sum {
                     (ident, ref summary) => {
-                        build::mk_arm(cx, span,
-                                      ~[ pat ],
-                                      rand_thing(cx, span, ident, summary, rand_call))
+                        cx.arm(span,
+                               ~[ pat ],
+                               rand_thing(cx, span, ident, summary, rand_call))
                     }
                 }
             };
 
             // _ => {} at the end. Should never occur
-            arms.push(build::mk_unreachable_arm(cx, span));
+            arms.push(cx.arm_unreachable(span));
 
-            build::mk_expr(cx, span,
-                           ast::expr_match(rand_variant, arms))
+            cx.expr_match(span, rand_variant, arms)
         }
         _ => cx.bug("Non-static method in `deriving(Rand)`")
     };
 
-    fn rand_thing(cx: @ext_ctxt, span: span,
+    fn rand_thing(cx: @ExtCtxt, span: span,
                   ctor_ident: ident,
                   summary: &Either<uint, ~[ident]>,
                   rand_call: &fn() -> @expr) -> @expr {
-        let ctor_ident = ~[ ctor_ident ];
         match *summary {
             Left(copy count) => {
                 if count == 0 {
-                    build::mk_path(cx, span, ctor_ident)
+                    cx.expr_ident(span, ctor_ident)
                 } else {
                     let exprs = vec::from_fn(count, |_| rand_call());
-                    build::mk_call(cx, span, ctor_ident, exprs)
+                    cx.expr_call_ident(span, ctor_ident, exprs)
                 }
             }
             Right(ref fields) => {
                 let rand_fields = do fields.map |ident| {
-                    build::Field {
-                        ident: *ident,
-                        ex: rand_call()
-                    }
+                    cx.field_imm(span, *ident, rand_call())
                 };
-                build::mk_struct_e(cx, span, ctor_ident, rand_fields)
+                cx.expr_struct_ident(span, ctor_ident, rand_fields)
             }
         }
     }
diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs
index f155cb3790f..89b469575e5 100644
--- a/src/libsyntax/ext/deriving/to_str.rs
+++ b/src/libsyntax/ext/deriving/to_str.rs
@@ -10,26 +10,26 @@
 
 use ast::{meta_item, item, expr};
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-pub fn expand_deriving_to_str(cx: @ext_ctxt,
+pub fn expand_deriving_to_str(cx: @ExtCtxt,
                               span: span,
                               mitem: @meta_item,
                               in_items: ~[@item])
     -> ~[@item] {
     let trait_def = TraitDef {
-        path: Path::new(~[~"core", ~"to_str", ~"ToStr"]),
+        path: Path::new(~["core", "to_str", "ToStr"]),
         additional_bounds: ~[],
         generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
-                name: ~"to_str",
+                name: "to_str",
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: ~[],
-                ret_ty: Ptr(~Literal(Path::new_local(~"str")), Owned),
+                ret_ty: Ptr(~Literal(Path::new_local("str")), Owned),
                 const_nonmatching: false,
                 combine_substructure: to_str_substructure
             }
@@ -39,15 +39,15 @@ pub fn expand_deriving_to_str(cx: @ext_ctxt,
     expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
 }
 
-fn to_str_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
+fn to_str_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
     match substr.self_args {
         [self_obj] => {
-            let self_addr = build::mk_addr_of(cx, span, self_obj);
-            build::mk_call_global(cx, span,
-                                  ~[cx.ident_of("core"),
-                                    cx.ident_of("sys"),
-                                    cx.ident_of("log_str")],
-                                  ~[self_addr])
+            let self_addr = cx.expr_addr_of(span, self_obj);
+            cx.expr_call_global(span,
+                                ~[cx.ident_of("core"),
+                                  cx.ident_of("sys"),
+                                  cx.ident_of("log_str")],
+                                ~[self_addr])
         }
         _ => cx.span_bug(span, "Invalid number of arguments in `deriving(ToStr)`")
     }
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index 5fc3aeb789c..99bc2d87b30 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -15,37 +15,36 @@ explicit `Self` type to use when specifying impls to be derived.
 
 use ast;
 use ast::{expr,Generics,ident};
-use ext::base::ext_ctxt;
-use ext::build;
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
 use codemap::{span,respan};
 use opt_vec;
 
 /// The types of pointers
-#[deriving(Eq)]
-pub enum PtrTy {
+pub enum PtrTy<'self> {
     Owned, // ~
     Managed(ast::mutability), // @[mut]
-    Borrowed(Option<~str>, ast::mutability), // &['lifetime] [mut]
+    Borrowed(Option<&'self str>, ast::mutability), // &['lifetime] [mut]
 }
 
 /// A path, e.g. `::core::option::Option::<int>` (global). Has support
 /// for type parameters and a lifetime.
-#[deriving(Eq)]
-pub struct Path {
-    path: ~[~str],
-    lifetime: Option<~str>,
-    params: ~[~Ty],
+pub struct Path<'self> {
+    path: ~[&'self str],
+    lifetime: Option<&'self str>,
+    params: ~[~Ty<'self>],
     global: bool
 }
 
-pub impl Path {
-    fn new(path: ~[~str]) -> Path {
+pub impl<'self> Path<'self> {
+    fn new<'r>(path: ~[&'r str]) -> Path<'r> {
         Path::new_(path, None, ~[], true)
     }
-    fn new_local(path: ~str) -> Path {
+    fn new_local<'r>(path: &'r str) -> Path<'r> {
         Path::new_(~[ path ], None, ~[], false)
     }
-    fn new_(path: ~[~str], lifetime: Option<~str>, params: ~[~Ty], global: bool) -> Path {
+    fn new_<'r>(path: ~[&'r str], lifetime: Option<&'r str>, params: ~[~Ty<'r>], global: bool)
+        -> Path<'r> {
         Path {
             path: path,
             lifetime: lifetime,
@@ -54,87 +53,81 @@ pub impl Path {
         }
     }
 
-    fn to_ty(&self, cx: @ext_ctxt, span: span,
+    fn to_ty(&self, cx: @ExtCtxt, span: span,
              self_ty: ident, self_generics: &Generics) -> @ast::Ty {
-                build::mk_ty_path_path(cx, span,
-                                       self.to_path(cx, span,
-                                                    self_ty, self_generics))
+        cx.ty_path(self.to_path(cx, span,
+                                self_ty, self_generics))
     }
-    fn to_path(&self, cx: @ext_ctxt, span: span,
+    fn to_path(&self, cx: @ExtCtxt, span: span,
                self_ty: ident, self_generics: &Generics) -> @ast::Path {
         let idents = self.path.map(|s| cx.ident_of(*s) );
         let lt = mk_lifetime(cx, span, &self.lifetime);
         let tys = self.params.map(|t| t.to_ty(cx, span, self_ty, self_generics));
 
-        if self.global {
-            build::mk_raw_path_global_(span, idents, lt, tys)
-        } else {
-            build::mk_raw_path_(span, idents, lt, tys)
-        }
+        cx.path_all(span, self.global, idents, lt, tys)
     }
 }
 
 /// A type. Supports pointers (except for *), Self, and literals
-#[deriving(Eq)]
-pub enum Ty {
+pub enum Ty<'self> {
     Self,
     // &/~/@ Ty
-    Ptr(~Ty, PtrTy),
+    Ptr(~Ty<'self>, PtrTy<'self>),
     // mod::mod::Type<[lifetime], [Params...]>, including a plain type
     // parameter, and things like `int`
-    Literal(Path),
+    Literal(Path<'self>),
     // includes nil
-    Tuple(~[Ty])
+    Tuple(~[Ty<'self>])
 }
 
-pub fn borrowed_ptrty() -> PtrTy {
+pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
     Borrowed(None, ast::m_imm)
 }
-pub fn borrowed(ty: ~Ty) -> Ty {
+pub fn borrowed<'r>(ty: ~Ty<'r>) -> Ty<'r> {
     Ptr(ty, borrowed_ptrty())
 }
 
-pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
+pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
     Some(Some(borrowed_ptrty()))
 }
 
-pub fn borrowed_self() -> Ty {
+pub fn borrowed_self<'r>() -> Ty<'r> {
     borrowed(~Self)
 }
 
-pub fn nil_ty() -> Ty {
+pub fn nil_ty() -> Ty<'static> {
     Tuple(~[])
 }
 
-fn mk_lifetime(cx: @ext_ctxt, span: span, lt: &Option<~str>) -> Option<@ast::Lifetime> {
+fn mk_lifetime(cx: @ExtCtxt, span: span, lt: &Option<&str>) -> Option<@ast::Lifetime> {
     match *lt {
-        Some(ref s) => Some(@build::mk_lifetime(cx, span, cx.ident_of(*s))),
+        Some(ref s) => Some(@cx.lifetime(span, cx.ident_of(*s))),
         None => None
     }
 }
 
-pub impl Ty {
-    fn to_ty(&self, cx: @ext_ctxt, span: span,
+pub impl<'self> Ty<'self> {
+    fn to_ty(&self, cx: @ExtCtxt, span: span,
              self_ty: ident, self_generics: &Generics) -> @ast::Ty {
         match *self {
             Ptr(ref ty, ref ptr) => {
                 let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
                 match *ptr {
                     Owned => {
-                        build::mk_ty_uniq(cx, span, raw_ty)
+                        cx.ty_uniq(span, raw_ty)
                     }
                     Managed(mutbl) => {
-                        build::mk_ty_box(cx, span, raw_ty, mutbl)
+                        cx.ty_box(span, raw_ty, mutbl)
                     }
                     Borrowed(ref lt, mutbl) => {
                         let lt = mk_lifetime(cx, span, lt);
-                        build::mk_ty_rptr(cx, span, raw_ty, lt, mutbl)
+                        cx.ty_rptr(span, raw_ty, lt, mutbl)
                     }
                 }
             }
             Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
             Self  => {
-                build::mk_ty_path_path(cx, span, self.to_path(cx, span, self_ty, self_generics))
+                cx.ty_path(self.to_path(cx, span, self_ty, self_generics))
             }
             Tuple(ref fields) => {
                 let ty = if fields.is_empty() {
@@ -143,17 +136,17 @@ pub impl Ty {
                     ast::ty_tup(fields.map(|f| f.to_ty(cx, span, self_ty, self_generics)))
                 };
 
-                build::mk_ty(cx, span, ty)
+                cx.ty(span, ty)
             }
         }
     }
 
-    fn to_path(&self, cx: @ext_ctxt, span: span,
+    fn to_path(&self, cx: @ExtCtxt, span: span,
                self_ty: ident, self_generics: &Generics) -> @ast::Path {
         match *self {
             Self => {
                 let self_params = do self_generics.ty_params.map |ty_param| {
-                    build::mk_ty_path(cx, span, ~[ ty_param.ident ])
+                    cx.ty_ident(span, ty_param.ident)
                 };
                 let lifetime = if self_generics.lifetimes.is_empty() {
                     None
@@ -161,8 +154,8 @@ pub impl Ty {
                     Some(@*self_generics.lifetimes.get(0))
                 };
 
-                build::mk_raw_path_(span, ~[self_ty], lifetime,
-                                    opt_vec::take_vec(self_params))
+                cx.path_all(span, false, ~[self_ty], lifetime,
+                            opt_vec::take_vec(self_params))
             }
             Literal(ref p) => {
                 p.to_path(cx, span, self_ty, self_generics)
@@ -174,14 +167,14 @@ pub impl Ty {
 }
 
 
-fn mk_ty_param(cx: @ext_ctxt, span: span, name: ~str, bounds: ~[Path],
+fn mk_ty_param(cx: @ExtCtxt, span: span, name: &str, bounds: &[Path],
                self_ident: ident, self_generics: &Generics) -> ast::TyParam {
     let bounds = opt_vec::from(
         do bounds.map |b| {
             let path = b.to_path(cx, span, self_ident, self_generics);
-            build::mk_trait_ty_param_bound_(cx, path)
+            cx.typarambound(path)
         });
-    build::mk_ty_param(cx, cx.ident_of(name), @bounds)
+    cx.typaram(cx.ident_of(name), @bounds)
 }
 
 fn mk_generics(lifetimes: ~[ast::Lifetime],  ty_params: ~[ast::TyParam]) -> Generics {
@@ -192,33 +185,37 @@ fn mk_generics(lifetimes: ~[ast::Lifetime],  ty_params: ~[ast::TyParam]) -> Gene
 }
 
 /// Lifetimes and bounds on type parameters
-pub struct LifetimeBounds {
-    lifetimes: ~[~str],
-    bounds: ~[(~str, ~[Path])]
+pub struct LifetimeBounds<'self> {
+    lifetimes: ~[&'self str],
+    bounds: ~[(&'self str, ~[Path<'self>])]
 }
 
-pub impl LifetimeBounds {
-    fn empty() -> LifetimeBounds {
+pub impl<'self> LifetimeBounds<'self> {
+    fn empty() -> LifetimeBounds<'static> {
         LifetimeBounds {
             lifetimes: ~[], bounds: ~[]
         }
     }
-    fn to_generics(&self, cx: @ext_ctxt, span: span,
+    fn to_generics(&self, cx: @ExtCtxt, span: span,
                    self_ty: ident, self_generics: &Generics) -> Generics {
-        let lifetimes = do self.lifetimes.map |&lt| {
-            build::mk_lifetime(cx, span, cx.ident_of(lt))
+        let lifetimes = do self.lifetimes.map |lt| {
+            cx.lifetime(span, cx.ident_of(*lt))
         };
-        let ty_params = do self.bounds.map |&(name, bounds)| {
-            mk_ty_param(cx, span, name, bounds, self_ty, self_generics)
+        let ty_params = do self.bounds.map |t| {
+            match t {
+                &(ref name, ref bounds) => {
+                    mk_ty_param(cx, span, *name, *bounds, self_ty, self_generics)
+                }
+            }
         };
         mk_generics(lifetimes, ty_params)
     }
 }
 
 
-pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: &Option<PtrTy>)
+pub fn get_explicit_self(cx: @ExtCtxt, span: span, self_ptr: &Option<PtrTy>)
     -> (@expr, ast::explicit_self) {
-    let self_path = build::make_self(cx, span);
+    let self_path = cx.expr_self(span);
     match *self_ptr {
         None => {
             (self_path, respan(span, ast::sty_value))
@@ -230,12 +227,12 @@ pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: &Option<PtrTy>)
                     Owned => ast::sty_uniq(ast::m_imm),
                     Managed(mutbl) => ast::sty_box(mutbl),
                     Borrowed(ref lt, mutbl) => {
-                        let lt = lt.map(|s| @build::mk_lifetime(cx, span,
-                                                                cx.ident_of(*s)));
+                        let lt = lt.map(|s| @cx.lifetime(span,
+                                                         cx.ident_of(*s)));
                         ast::sty_region(lt, mutbl)
                     }
                 });
-            let self_expr = build::mk_deref(cx, span, self_path);
+            let self_expr = cx.expr_deref(span, self_path);
             (self_expr, self_ty)
         }
     }
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 4be75d9ee5b..32fbc913999 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -18,9 +18,9 @@ use ast;
 use codemap::span;
 use ext::base::*;
 use ext::base;
-use ext::build::mk_base_str;
+use ext::build::AstBuilder;
 
-pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
 
     let var = get_single_str_from_tts(cx, sp, tts, "env!");
@@ -29,8 +29,8 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
     // Option<str> rather than just an maybe-empty string.
 
     let e = match os::getenv(var) {
-      None => mk_base_str(cx, sp, ~""),
-      Some(ref s) => mk_base_str(cx, sp, copy *s)
+      None => cx.expr_str(sp, ~""),
+      Some(ref s) => cx.expr_str(sp, copy *s)
     };
     MRExpr(e)
 }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index ff0cf6f28ad..b993162cfa3 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -23,7 +23,7 @@ use parse;
 use parse::{parse_item_from_source_str};
 
 pub fn expand_expr(extsbox: @mut SyntaxEnv,
-                   cx: @ext_ctxt,
+                   cx: @ExtCtxt,
                    e: &expr_,
                    s: span,
                    fld: @ast_fold,
@@ -109,7 +109,7 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
 // NB: there is some redundancy between this and expand_item, below, and
 // they might benefit from some amount of semantic and language-UI merger.
 pub fn expand_mod_items(extsbox: @mut SyntaxEnv,
-                        cx: @ext_ctxt,
+                        cx: @ExtCtxt,
                         module_: &ast::_mod,
                         fld: @ast_fold,
                         orig: @fn(&ast::_mod, @ast_fold) -> ast::_mod)
@@ -161,7 +161,7 @@ macro_rules! with_exts_frame (
 
 // When we enter a module, record it, for the sake of `module!`
 pub fn expand_item(extsbox: @mut SyntaxEnv,
-                   cx: @ext_ctxt,
+                   cx: @ExtCtxt,
                    it: @ast::item,
                    fld: @ast_fold,
                    orig: @fn(@ast::item, @ast_fold) -> Option<@ast::item>)
@@ -227,7 +227,7 @@ macro_rules! without_macro_scoping(
 // Support for item-position macro invocations, exactly the same
 // logic as for expression-position macro invocations.
 pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
-                       cx: @ext_ctxt, it: @ast::item,
+                       cx: @ExtCtxt, it: @ast::item,
                        fld: @ast_fold)
                     -> Option<@ast::item> {
     let (pth, tts) = match it.node {
@@ -294,7 +294,7 @@ pub fn expand_item_mac(extsbox: @mut SyntaxEnv,
 
 // expand a stmt
 pub fn expand_stmt(extsbox: @mut SyntaxEnv,
-                   cx: @ext_ctxt,
+                   cx: @ExtCtxt,
                    s: &stmt_,
                    sp: span,
                    fld: @ast_fold,
@@ -360,7 +360,7 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv,
 
 
 pub fn expand_block(extsbox: @mut SyntaxEnv,
-                    cx: @ext_ctxt,
+                    cx: @ExtCtxt,
                     blk: &blk_,
                     sp: span,
                     fld: @ast_fold,
@@ -381,7 +381,7 @@ pub fn expand_block(extsbox: @mut SyntaxEnv,
     }
 }
 
-pub fn new_span(cx: @ext_ctxt, sp: span) -> span {
+pub fn new_span(cx: @ExtCtxt, sp: span) -> span {
     /* this discards information in the case of macro-defining macros */
     return span {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()};
 }
@@ -590,7 +590,7 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess,
     // every method/element of AstFoldFns in fold.rs.
     let extsbox = @mut syntax_expander_table();
     let afp = default_ast_fold();
-    let cx: @ext_ctxt = mk_ctxt(parse_sess, copy cfg);
+    let cx = ExtCtxt::new(parse_sess, copy cfg);
     let f_pre = @AstFoldFns {
         fold_expr: |expr,span,recur|
             expand_expr(extsbox, cx, expr, span, recur, afp.fold_expr),
diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs
index 24046faa684..55d3d4ee834 100644
--- a/src/libsyntax/ext/fmt.rs
+++ b/src/libsyntax/ext/fmt.rs
@@ -18,12 +18,11 @@ use ast;
 use codemap::span;
 use ext::base::*;
 use ext::base;
-use ext::build;
-use ext::build::*;
+use ext::build::AstBuilder;
 
 use core::unstable::extfmt::ct::*;
 
-pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_syntax_ext(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     let args = get_exprs_from_tts(cx, tts);
     if args.len() == 0 {
@@ -34,7 +33,7 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
                     ~"first argument to fmt! must be a string literal.");
     let fmtspan = args[0].span;
     debug!("Format string: %s", fmt);
-    fn parse_fmt_err_(cx: @ext_ctxt, sp: span, msg: &str) -> ! {
+    fn parse_fmt_err_(cx: @ExtCtxt, sp: span, msg: &str) -> ! {
         cx.span_fatal(sp, msg);
     }
     let parse_fmt_err: @fn(&str) -> ! = |s| parse_fmt_err_(cx, fmtspan, s);
@@ -46,23 +45,23 @@ pub fn expand_syntax_ext(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
 // probably be factored out in common with other code that builds
 // expressions.  Also: Cleanup the naming of these functions.
 // Note: Moved many of the common ones to build.rs --kevina
-fn pieces_to_expr(cx: @ext_ctxt, sp: span,
+fn pieces_to_expr(cx: @ExtCtxt, sp: span,
                   pieces: ~[Piece], args: ~[@ast::expr])
    -> @ast::expr {
-    fn make_path_vec(cx: @ext_ctxt, ident: &str) -> ~[ast::ident] {
+    fn make_path_vec(cx: @ExtCtxt, ident: &str) -> ~[ast::ident] {
         let intr = cx.parse_sess().interner;
         return ~[intr.intern("unstable"), intr.intern("extfmt"),
                  intr.intern("rt"), intr.intern(ident)];
     }
-    fn make_rt_path_expr(cx: @ext_ctxt, sp: span, nm: &str) -> @ast::expr {
+    fn make_rt_path_expr(cx: @ExtCtxt, sp: span, nm: &str) -> @ast::expr {
         let path = make_path_vec(cx, nm);
-        return mk_path_global(cx, sp, path);
+        cx.expr_path(cx.path_global(sp, path))
     }
     // Produces an AST expression that represents a RT::conv record,
     // which tells the RT::conv* functions how to perform the conversion
 
-    fn make_rt_conv_expr(cx: @ext_ctxt, sp: span, cnv: &Conv) -> @ast::expr {
-        fn make_flags(cx: @ext_ctxt, sp: span, flags: &[Flag]) -> @ast::expr {
+    fn make_rt_conv_expr(cx: @ExtCtxt, sp: span, cnv: &Conv) -> @ast::expr {
+        fn make_flags(cx: @ExtCtxt, sp: span, flags: &[Flag]) -> @ast::expr {
             let mut tmp_expr = make_rt_path_expr(cx, sp, "flag_none");
             for flags.each |f| {
                 let fstr = match *f {
@@ -72,26 +71,26 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
                   FlagSignAlways => "flag_sign_always",
                   FlagAlternate => "flag_alternate"
                 };
-                tmp_expr = mk_binary(cx, sp, ast::bitor, tmp_expr,
-                                     make_rt_path_expr(cx, sp, fstr));
+                tmp_expr = cx.expr_binary(sp, ast::bitor, tmp_expr,
+                                          make_rt_path_expr(cx, sp, fstr));
             }
             return tmp_expr;
         }
-        fn make_count(cx: @ext_ctxt, sp: span, cnt: Count) -> @ast::expr {
+        fn make_count(cx: @ExtCtxt, sp: span, cnt: Count) -> @ast::expr {
             match cnt {
               CountImplied => {
                 return make_rt_path_expr(cx, sp, "CountImplied");
               }
               CountIs(c) => {
-                let count_lit = mk_uint(cx, sp, c as uint);
+                let count_lit = cx.expr_uint(sp, c as uint);
                 let count_is_path = make_path_vec(cx, "CountIs");
                 let count_is_args = ~[count_lit];
-                return mk_call_global(cx, sp, count_is_path, count_is_args);
+                return cx.expr_call_global(sp, count_is_path, count_is_args);
               }
               _ => cx.span_unimpl(sp, "unimplemented fmt! conversion")
             }
         }
-        fn make_ty(cx: @ext_ctxt, sp: span, t: Ty) -> @ast::expr {
+        fn make_ty(cx: @ExtCtxt, sp: span, t: Ty) -> @ast::expr {
             let rt_type = match t {
               TyHex(c) => match c {
                 CaseUpper =>  "TyHexUpper",
@@ -103,27 +102,18 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
             };
             return make_rt_path_expr(cx, sp, rt_type);
         }
-        fn make_conv_struct(cx: @ext_ctxt, sp: span, flags_expr: @ast::expr,
+        fn make_conv_struct(cx: @ExtCtxt, sp: span, flags_expr: @ast::expr,
                          width_expr: @ast::expr, precision_expr: @ast::expr,
                          ty_expr: @ast::expr) -> @ast::expr {
             let intr = cx.parse_sess().interner;
-            mk_global_struct_e(
-                cx,
+            cx.expr_struct(
                 sp,
-                make_path_vec(cx, "Conv"),
+                cx.path_global(sp, make_path_vec(cx, "Conv")),
                 ~[
-                    build::Field {
-                        ident: intr.intern("flags"), ex: flags_expr
-                    },
-                    build::Field {
-                        ident: intr.intern("width"), ex: width_expr
-                    },
-                    build::Field {
-                        ident: intr.intern("precision"), ex: precision_expr
-                    },
-                    build::Field {
-                        ident: intr.intern("ty"), ex: ty_expr
-                    },
+                    cx.field_imm(sp, intr.intern("flags"), flags_expr),
+                    cx.field_imm(sp, intr.intern("width"), width_expr),
+                    cx.field_imm(sp, intr.intern("precision"), precision_expr),
+                    cx.field_imm(sp, intr.intern("ty"), ty_expr)
                 ]
             )
         }
@@ -134,16 +124,16 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
         make_conv_struct(cx, sp, rt_conv_flags, rt_conv_width,
                          rt_conv_precision, rt_conv_ty)
     }
-    fn make_conv_call(cx: @ext_ctxt, sp: span, conv_type: &str, cnv: &Conv,
+    fn make_conv_call(cx: @ExtCtxt, sp: span, conv_type: &str, cnv: &Conv,
                       arg: @ast::expr, buf: @ast::expr) -> @ast::expr {
         let fname = ~"conv_" + conv_type;
         let path = make_path_vec(cx, fname);
         let cnv_expr = make_rt_conv_expr(cx, sp, cnv);
         let args = ~[cnv_expr, arg, buf];
-        return mk_call_global(cx, arg.span, path, args);
+        cx.expr_call_global(arg.span, path, args)
     }
 
-    fn make_new_conv(cx: @ext_ctxt, sp: span, cnv: &Conv,
+    fn make_new_conv(cx: @ExtCtxt, sp: span, cnv: &Conv,
                      arg: @ast::expr, buf: @ast::expr) -> @ast::expr {
         fn is_signed_type(cnv: &Conv) -> bool {
             match cnv.ty {
@@ -198,10 +188,10 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
             TyChar => ("char", arg),
             TyBits | TyOctal | TyHex(_) | TyInt(Unsigned) => ("uint", arg),
             TyFloat => ("float", arg),
-            TyPoly => ("poly", mk_addr_of(cx, sp, arg))
+            TyPoly => ("poly", cx.expr_addr_of(sp, arg))
         };
         return make_conv_call(cx, arg.span, name, cnv, actual_arg,
-                              mk_mut_addr_of(cx, arg.span, buf));
+                              cx.expr_mut_addr_of(arg.span, buf));
     }
     fn log_conv(c: &Conv) {
         debug!("Building conversion:");
@@ -259,7 +249,7 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
 
     /* 'ident' is the local buffer building up the result of fmt! */
     let ident = cx.parse_sess().interner.intern("__fmtbuf");
-    let buf = || mk_path(cx, fmt_sp, ~[ident]);
+    let buf = || cx.expr_ident(fmt_sp, ident);
     let str_ident = cx.parse_sess().interner.intern("str");
     let push_ident = cx.parse_sess().interner.intern("push_str");
     let mut stms = ~[];
@@ -276,14 +266,14 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
                    buffer with it directly. If it's actually the only piece,
                    then there's no need for it to be mutable */
                 if i == 0 {
-                    stms.push(mk_local(cx, fmt_sp, npieces > 1, ident, mk_uniq_str(cx, fmt_sp, s)));
+                    stms.push(cx.stmt_let(fmt_sp, npieces > 1,
+                                          ident, cx.expr_str_uniq(fmt_sp, s)));
                 } else {
-                    let args = ~[mk_mut_addr_of(cx, fmt_sp, buf()), mk_base_str(cx, fmt_sp, s)];
-                    let call = mk_call_global(cx,
-                                              fmt_sp,
-                                              ~[str_ident, push_ident],
-                                              args);
-                    stms.push(mk_stmt(cx, fmt_sp, call));
+                    let args = ~[cx.expr_mut_addr_of(fmt_sp, buf()), cx.expr_str(fmt_sp, s)];
+                    let call = cx.expr_call_global(fmt_sp,
+                                                   ~[str_ident, push_ident],
+                                                   args);
+                    stms.push(cx.stmt_expr(call));
                 }
             }
 
@@ -300,12 +290,11 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
                 /* If the first portion is a conversion, then the local buffer
                    must be initialized as an empty string */
                 if i == 0 {
-                    stms.push(mk_local(cx, fmt_sp, true, ident,
-                                       mk_uniq_str(cx, fmt_sp, ~"")));
+                    stms.push(cx.stmt_let(fmt_sp, true, ident,
+                                          cx.expr_str_uniq(fmt_sp, ~"")));
                 }
-                stms.push(mk_stmt(cx, fmt_sp,
-                                  make_new_conv(cx, fmt_sp, conv,
-                                                args[n], buf())));
+                stms.push(cx.stmt_expr(make_new_conv(cx, fmt_sp, conv,
+                                                     args[n], buf())));
             }
         }
     }
@@ -317,5 +306,5 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span,
                            nargs, expected_nargs));
     }
 
-    return mk_block(cx, fmt_sp, ~[], stms, Some(buf()));
+    cx.expr_blk(cx.blk(fmt_sp, stms, Some(buf())))
 }
diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs
index 76d9a9420ce..a3f6fb8e97d 100644
--- a/src/libsyntax/ext/log_syntax.rs
+++ b/src/libsyntax/ext/log_syntax.rs
@@ -14,7 +14,7 @@ use ext::base::*;
 use ext::base;
 use print;
 
-pub fn expand_syntax_ext(cx: @ext_ctxt,
+pub fn expand_syntax_ext(cx: @ExtCtxt,
                          sp: codemap::span,
                          tt: &[ast::token_tree])
                       -> base::MacResult {
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index a5148287258..1f2e3f06a73 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -13,16 +13,10 @@
 // To start with, it will be use dummy spans, but it might someday do
 // something smarter.
 
-use abi::AbiSet;
 use ast::ident;
 use ast;
-use ast_util;
-use codemap::{span, respan, dummy_sp, spanned};
-use codemap;
-use ext::base::ext_ctxt;
-use ext::quote::rt::*;
-use opt_vec;
-use opt_vec::OptVec;
+use codemap::span;
+// use ext::quote::rt::*;
 
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
@@ -66,377 +60,3 @@ impl append_types for @ast::Path {
         }
     }
 }
-
-pub trait ext_ctxt_ast_builder {
-    fn ty_param(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>)
-        -> ast::TyParam;
-    fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg;
-    fn expr_block(&self, e: @ast::expr) -> ast::blk;
-    fn fn_decl(&self, inputs: ~[ast::arg], output: @ast::Ty) -> ast::fn_decl;
-    fn item(&self, name: ident, span: span, node: ast::item_) -> @ast::item;
-    fn item_fn_poly(&self,
-                    ame: ident,
-                    inputs: ~[ast::arg],
-                    output: @ast::Ty,
-                    generics: Generics,
-                    body: ast::blk) -> @ast::item;
-    fn item_fn(&self,
-               name: ident,
-               inputs: ~[ast::arg],
-               output: @ast::Ty,
-               body: ast::blk) -> @ast::item;
-    fn item_enum_poly(&self,
-                      name: ident,
-                      span: span,
-                      enum_definition: ast::enum_def,
-                      generics: Generics) -> @ast::item;
-    fn item_enum(&self,
-                 name: ident,
-                 span: span,
-                 enum_definition: ast::enum_def) -> @ast::item;
-    fn item_struct_poly(&self,
-                        name: ident,
-                        span: span,
-                        struct_def: ast::struct_def,
-                        generics: Generics) -> @ast::item;
-    fn item_struct(&self,
-                   name: ident,
-                   span: span,
-                   struct_def: ast::struct_def) -> @ast::item;
-    fn struct_expr(&self,
-                   path: @ast::Path,
-                   fields: ~[ast::field]) -> @ast::expr;
-    fn variant(&self,
-               name: ident,
-               span: span,
-               tys: ~[@ast::Ty]) -> ast::variant;
-    fn item_mod(&self,
-                name: ident,
-                span: span,
-                items: ~[@ast::item]) -> @ast::item;
-    fn ty_path_ast_builder(&self, path: @ast::Path) -> @ast::Ty;
-    fn item_ty_poly(&self,
-                    name: ident,
-                    span: span,
-                    ty: @ast::Ty,
-                    generics: Generics) -> @ast::item;
-    fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item;
-    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
-    fn ty_vars_global(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty];
-    fn ty_field_imm(&self, name: ident, ty: @ast::Ty) -> ast::ty_field;
-    fn field_imm(&self, name: ident, e: @ast::expr) -> ast::field;
-    fn block(&self, stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk;
-    fn stmt_let(&self, ident: ident, e: @ast::expr) -> @ast::stmt;
-    fn stmt_expr(&self, e: @ast::expr) -> @ast::stmt;
-    fn block_expr(&self, b: ast::blk) -> @ast::expr;
-    fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty;
-    fn ty_infer(&self) -> @ast::Ty;
-    fn ty_nil_ast_builder(&self) -> @ast::Ty;
-    fn strip_bounds(&self, bounds: &Generics) -> Generics;
-}
-
-impl ext_ctxt_ast_builder for @ext_ctxt {
-    fn ty_option(&self, ty: @ast::Ty) -> @ast::Ty {
-        self.ty_path_ast_builder(path_global(~[
-            self.ident_of("core"),
-            self.ident_of("option"),
-            self.ident_of("Option")
-        ], dummy_sp()).add_ty(ty))
-    }
-
-    fn block_expr(&self, b: ast::blk) -> @ast::expr {
-        @expr {
-            id: self.next_id(),
-            callee_id: self.next_id(),
-            node: ast::expr_block(b),
-            span: dummy_sp(),
-        }
-    }
-
-    fn stmt_expr(&self, e: @ast::expr) -> @ast::stmt {
-        @spanned { node: ast::stmt_expr(e, self.next_id()),
-                   span: dummy_sp()}
-    }
-
-    fn stmt_let(&self, ident: ident, e: @ast::expr) -> @ast::stmt {
-        let ext_cx = *self;
-        quote_stmt!( let $ident = $e; )
-    }
-
-    fn field_imm(&self, name: ident, e: @ast::expr) -> ast::field {
-        spanned {
-            node: ast::field_ { mutbl: ast::m_imm, ident: name, expr: e },
-            span: dummy_sp(),
-        }
-    }
-
-    fn ty_field_imm(&self, name: ident, ty: @ast::Ty) -> ast::ty_field {
-        spanned {
-            node: ast::ty_field_ {
-                ident: name,
-                mt: ast::mt { ty: ty, mutbl: ast::m_imm },
-            },
-            span: dummy_sp(),
-        }
-    }
-
-    fn ty_infer(&self) -> @ast::Ty {
-        @ast::Ty {
-            id: self.next_id(),
-            node: ast::ty_infer,
-            span: dummy_sp(),
-        }
-    }
-
-    fn ty_param(&self, id: ast::ident, bounds: @OptVec<ast::TyParamBound>)
-        -> ast::TyParam
-    {
-        ast::TyParam { ident: id, id: self.next_id(), bounds: bounds }
-    }
-
-    fn arg(&self, name: ident, ty: @ast::Ty) -> ast::arg {
-        ast::arg {
-            is_mutbl: false,
-            ty: ty,
-            pat: @ast::pat {
-                id: self.next_id(),
-                node: ast::pat_ident(
-                    ast::bind_by_copy,
-                    ast_util::ident_to_path(dummy_sp(), name),
-                    None),
-                span: dummy_sp(),
-            },
-            id: self.next_id(),
-        }
-    }
-
-    fn block(&self, stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk {
-        let blk = ast::blk_ {
-            view_items: ~[],
-            stmts: stmts,
-            expr: Some(e),
-            id: self.next_id(),
-            rules: ast::default_blk,
-        };
-
-        spanned { node: blk, span: dummy_sp() }
-    }
-
-    fn expr_block(&self, e: @ast::expr) -> ast::blk {
-        self.block(~[], e)
-    }
-
-    fn fn_decl(&self, inputs: ~[ast::arg],
-               output: @ast::Ty) -> ast::fn_decl {
-        ast::fn_decl {
-            inputs: inputs,
-            output: output,
-            cf: ast::return_val,
-        }
-    }
-
-    fn item(&self, name: ident, span: span,
-            node: ast::item_) -> @ast::item {
-
-        // XXX: Would be nice if our generated code didn't violate
-        // Rust coding conventions
-        let non_camel_case_attribute = respan(dummy_sp(), ast::attribute_ {
-            style: ast::attr_outer,
-            value: @respan(dummy_sp(),
-                          ast::meta_list(@~"allow", ~[
-                              @respan(dummy_sp(),
-                                      ast::meta_word(
-                                         @~"non_camel_case_types"))
-                          ])),
-            is_sugared_doc: false
-        });
-
-        @ast::item { ident: name,
-                     attrs: ~[non_camel_case_attribute],
-                     id: self.next_id(),
-                     node: node,
-                     vis: ast::public,
-                     span: span }
-    }
-
-    fn item_fn_poly(&self, name: ident,
-                    inputs: ~[ast::arg],
-                    output: @ast::Ty,
-                    generics: Generics,
-                    body: ast::blk) -> @ast::item {
-        self.item(name,
-                  dummy_sp(),
-                  ast::item_fn(self.fn_decl(inputs, output),
-                               ast::impure_fn,
-                               AbiSet::Rust(),
-                               generics,
-                               body))
-    }
-
-    fn item_fn(&self,
-               name: ident,
-               inputs: ~[ast::arg],
-               output: @ast::Ty,
-               body: ast::blk
-    ) -> @ast::item {
-        self.item_fn_poly(
-            name,
-            inputs,
-            output,
-            ast_util::empty_generics(),
-            body
-        )
-    }
-
-    fn item_enum_poly(&self, name: ident, span: span,
-                      enum_definition: ast::enum_def,
-                      generics: Generics) -> @ast::item {
-        self.item(name, span, ast::item_enum(enum_definition, generics))
-    }
-
-    fn item_enum(&self, name: ident, span: span,
-                 enum_definition: ast::enum_def) -> @ast::item {
-        self.item_enum_poly(name, span, enum_definition,
-                            ast_util::empty_generics())
-    }
-
-    fn item_struct(
-        &self, name: ident,
-        span: span,
-        struct_def: ast::struct_def
-    ) -> @ast::item {
-        self.item_struct_poly(
-            name,
-            span,
-            struct_def,
-            ast_util::empty_generics()
-        )
-    }
-
-    fn item_struct_poly(
-        &self,
-        name: ident,
-        span: span,
-        struct_def: ast::struct_def,
-        generics: Generics
-    ) -> @ast::item {
-        self.item(name, span, ast::item_struct(@struct_def, generics))
-    }
-
-    fn struct_expr(&self, path: @ast::Path,
-                   fields: ~[ast::field]) -> @ast::expr {
-        @ast::expr {
-            id: self.next_id(),
-            callee_id: self.next_id(),
-            node: ast::expr_struct(path, fields, None),
-            span: dummy_sp()
-        }
-    }
-
-    fn variant(&self, name: ident, span: span,
-               tys: ~[@ast::Ty]) -> ast::variant {
-        let args = do tys.map |ty| {
-            ast::variant_arg { ty: *ty, id: self.next_id() }
-        };
-
-        spanned {
-            node: ast::variant_ {
-                name: name,
-                attrs: ~[],
-                kind: ast::tuple_variant_kind(args),
-                id: self.next_id(),
-                disr_expr: None,
-                vis: ast::public
-            },
-            span: span,
-        }
-    }
-
-    fn item_mod(&self, name: ident, span: span,
-                items: ~[@ast::item]) -> @ast::item {
-
-        // XXX: Total hack: import `core::kinds::Owned` to work around a
-        // parser bug whereby `fn f<T:::kinds::Owned>` doesn't parse.
-        let vi = ast::view_item_use(~[
-            @codemap::spanned {
-                node: ast::view_path_simple(
-                    self.ident_of("Owned"),
-                    path(
-                        ~[
-                            self.ident_of("core"),
-                            self.ident_of("kinds"),
-                            self.ident_of("Owned")
-                        ],
-                        codemap::dummy_sp()
-                    ),
-                    self.next_id()
-                ),
-                span: codemap::dummy_sp()
-            }
-        ]);
-        let vi = @ast::view_item {
-            node: vi,
-            attrs: ~[],
-            vis: ast::private,
-            span: codemap::dummy_sp()
-        };
-
-        self.item(
-            name,
-            span,
-            ast::item_mod(ast::_mod {
-                view_items: ~[vi],
-                items: items,
-            })
-        )
-    }
-
-    fn ty_path_ast_builder(&self, path: @ast::Path) -> @ast::Ty {
-        @ast::Ty {
-            id: self.next_id(),
-            node: ast::ty_path(path, self.next_id()),
-            span: path.span,
-        }
-    }
-
-    fn ty_nil_ast_builder(&self) -> @ast::Ty {
-        @ast::Ty {
-            id: self.next_id(),
-            node: ast::ty_nil,
-            span: dummy_sp(),
-        }
-    }
-
-    fn strip_bounds(&self, generics: &Generics) -> Generics {
-        let no_bounds = @opt_vec::Empty;
-        let new_params = do generics.ty_params.map |ty_param| {
-            ast::TyParam { bounds: no_bounds, ..copy *ty_param }
-        };
-        Generics {
-            ty_params: new_params,
-            .. copy *generics
-        }
-    }
-
-    fn item_ty_poly(&self, name: ident, span: span, ty: @ast::Ty,
-                    generics: Generics) -> @ast::item {
-        self.item(name, span, ast::item_ty(ty, generics))
-    }
-
-    fn item_ty(&self, name: ident, span: span, ty: @ast::Ty) -> @ast::item {
-        self.item_ty_poly(name, span, ty, ast_util::empty_generics())
-    }
-
-    fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
-        opt_vec::take_vec(
-            ty_params.map(|p| self.ty_path_ast_builder(
-                path(~[p.ident], dummy_sp()))))
-    }
-
-    fn ty_vars_global(&self,
-                      ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
-        opt_vec::take_vec(
-            ty_params.map(|p| self.ty_path_ast_builder(
-                path(~[p.ident], dummy_sp()))))
-    }
-}
diff --git a/src/libsyntax/ext/pipes/check.rs b/src/libsyntax/ext/pipes/check.rs
index 38e43d1ade5..c0b7f5bbb84 100644
--- a/src/libsyntax/ext/pipes/check.rs
+++ b/src/libsyntax/ext/pipes/check.rs
@@ -31,11 +31,11 @@ that.
 
 use ast;
 use codemap::span;
-use ext::base::ext_ctxt;
+use ext::base::ExtCtxt;
 use ext::pipes::proto::{state, protocol, next_state};
 use ext::pipes::proto;
 
-impl proto::visitor<(), (), ()> for @ext_ctxt {
+impl proto::visitor<(), (), ()> for @ExtCtxt {
     fn visit_proto(&self, _proto: protocol, _states: &[()]) { }
 
     fn visit_state(&self, state: state, _m: &[()]) {
diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs
index 104e5f94d17..8d45e47d54e 100644
--- a/src/libsyntax/ext/pipes/liveness.rs
+++ b/src/libsyntax/ext/pipes/liveness.rs
@@ -37,12 +37,12 @@ updating the states using rule (2) until there are no changes.
 
 */
 
-use ext::base::ext_ctxt;
+use ext::base::ExtCtxt;
 use ext::pipes::proto::{protocol_};
 
 use std::bitv::Bitv;
 
-pub fn analyze(proto: @mut protocol_, _cx: @ext_ctxt) {
+pub fn analyze(proto: @mut protocol_, _cx: @ExtCtxt) {
     debug!("initializing colive analysis");
     let num_states = proto.num_states();
     let mut colive = do (copy proto.states).map_to_vec |state| {
diff --git a/src/libsyntax/ext/pipes/mod.rs b/src/libsyntax/ext/pipes/mod.rs
index 642f22e9736..46de21d1c0b 100644
--- a/src/libsyntax/ext/pipes/mod.rs
+++ b/src/libsyntax/ext/pipes/mod.rs
@@ -46,7 +46,7 @@ FIXME (#3072) - This is still incomplete.
 use ast;
 use codemap::span;
 use ext::base;
-use ext::base::ext_ctxt;
+use ext::base::ExtCtxt;
 use ext::pipes::parse_proto::proto_parser;
 use ext::pipes::pipec::gen_init;
 use ext::pipes::proto::visit;
@@ -63,7 +63,7 @@ pub mod check;
 pub mod liveness;
 
 
-pub fn expand_proto(cx: @ext_ctxt, _sp: span, id: ast::ident,
+pub fn expand_proto(cx: @ExtCtxt, _sp: span, id: ast::ident,
                     tt: ~[ast::token_tree]) -> base::MacResult {
     let sess = cx.parse_sess();
     let cfg = cx.cfg();
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 8a9c714e7e9..0482dffe6d4 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -12,8 +12,9 @@
 
 use ast;
 use codemap::{dummy_sp, spanned};
-use ext::base::ext_ctxt;
-use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path};
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
+use ext::pipes::ast_builder::{append_types, path};
 use ext::pipes::ast_builder::{path_global};
 use ext::pipes::proto::*;
 use ext::quote::rt::*;
@@ -21,27 +22,27 @@ use opt_vec;
 use opt_vec::OptVec;
 
 pub trait gen_send {
-    fn gen_send(&mut self, cx: @ext_ctxt, try: bool) -> @ast::item;
-    fn to_ty(&mut self, cx: @ext_ctxt) -> @ast::Ty;
+    fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item;
+    fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty;
 }
 
 pub trait to_type_decls {
-    fn to_type_decls(&self, cx: @ext_ctxt) -> ~[@ast::item];
-    fn to_endpoint_decls(&self, cx: @ext_ctxt,
+    fn to_type_decls(&self, cx: @ExtCtxt) -> ~[@ast::item];
+    fn to_endpoint_decls(&self, cx: @ExtCtxt,
                          dir: direction) -> ~[@ast::item];
 }
 
 pub trait gen_init {
-    fn gen_init(&self, cx: @ext_ctxt) -> @ast::item;
-    fn compile(&self, cx: @ext_ctxt) -> @ast::item;
-    fn buffer_ty_path(&self, cx: @ext_ctxt) -> @ast::Ty;
-    fn gen_buffer_type(&self, cx: @ext_ctxt) -> @ast::item;
-    fn gen_buffer_init(&self, ext_cx: @ext_ctxt) -> @ast::expr;
-    fn gen_init_bounded(&self, ext_cx: @ext_ctxt) -> @ast::expr;
+    fn gen_init(&self, cx: @ExtCtxt) -> @ast::item;
+    fn compile(&self, cx: @ExtCtxt) -> @ast::item;
+    fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty;
+    fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item;
+    fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr;
+    fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr;
 }
 
 impl gen_send for message {
-    fn gen_send(&mut self, cx: @ext_ctxt, try: bool) -> @ast::item {
+    fn gen_send(&mut self, cx: @ExtCtxt, try: bool) -> @ast::item {
         debug!("pipec: gen_send");
         let name = self.name();
 
@@ -52,14 +53,13 @@ impl gen_send for message {
             assert!(next_state.tys.len() ==
                 next.generics.ty_params.len());
             let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str()));
-            let args_ast = vec::map_zip(arg_names, *tys, |n, t| cx.arg(*n, *t));
+            let args_ast = vec::map_zip(arg_names, *tys, |n, t| cx.arg(span, *n, *t));
 
-            let pipe_ty = cx.ty_path_ast_builder(
+            let pipe_ty = cx.ty_path(
                 path(~[this.data_name()], span)
-                .add_tys(cx.ty_vars_global(&this.generics.ty_params)));
+                .add_tys(cx.ty_vars(&this.generics.ty_params)));
             let args_ast = vec::append(
-                ~[cx.arg(cx.ident_of("pipe"),
-                              pipe_ty)],
+                ~[cx.arg(span, cx.ident_of("pipe"), pipe_ty)],
                 args_ast);
 
             let mut body = ~"{\n";
@@ -111,20 +111,21 @@ impl gen_send for message {
 
             let body = cx.parse_expr(body);
 
-            let mut rty = cx.ty_path_ast_builder(path(~[next.data_name()],
-                                                      span)
-                                               .add_tys(copy next_state.tys));
+            let mut rty = cx.ty_path(path(~[next.data_name()],
+                                          span)
+                                     .add_tys(copy next_state.tys));
             if try {
                 rty = cx.ty_option(rty);
             }
 
             let name = cx.ident_of(if try { ~"try_" + name } else { name } );
 
-            cx.item_fn_poly(name,
+            cx.item_fn_poly(dummy_sp(),
+                            name,
                             args_ast,
                             rty,
                             self.get_generics(),
-                            cx.expr_block(body))
+                            cx.blk_expr(body))
           }
 
             message(ref _id, span, ref tys, this, None) => {
@@ -132,14 +133,15 @@ impl gen_send for message {
                 let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str()));
 
                 let args_ast = do vec::map_zip(arg_names, *tys) |n, t| {
-                    cx.arg(cx.ident_of(*n), *t)
+                    cx.arg(span, cx.ident_of(*n), *t)
                 };
 
                 let args_ast = vec::append(
-                    ~[cx.arg(cx.ident_of("pipe"),
-                             cx.ty_path_ast_builder(
+                    ~[cx.arg(span,
+                             cx.ident_of("pipe"),
+                             cx.ty_path(
                                  path(~[this.data_name()], span)
-                                 .add_tys(cx.ty_vars_global(
+                                 .add_tys(cx.ty_vars(
                                      &this.generics.ty_params))))],
                     args_ast);
 
@@ -171,27 +173,28 @@ impl gen_send for message {
 
                 let name = if try { ~"try_" + name } else { name };
 
-                cx.item_fn_poly(cx.ident_of(name),
+                cx.item_fn_poly(dummy_sp(),
+                                cx.ident_of(name),
                                 args_ast,
                                 if try {
-                                    cx.ty_option(cx.ty_nil_ast_builder())
+                                    cx.ty_option(cx.ty_nil())
                                 } else {
-                                    cx.ty_nil_ast_builder()
+                                    cx.ty_nil()
                                 },
                                 self.get_generics(),
-                                cx.expr_block(body))
+                                cx.blk_expr(body))
             }
           }
         }
 
-    fn to_ty(&mut self, cx: @ext_ctxt) -> @ast::Ty {
-        cx.ty_path_ast_builder(path(~[cx.ident_of(self.name())], self.span())
-          .add_tys(cx.ty_vars_global(&self.get_generics().ty_params)))
+    fn to_ty(&mut self, cx: @ExtCtxt) -> @ast::Ty {
+        cx.ty_path(path(~[cx.ident_of(self.name())], self.span())
+          .add_tys(cx.ty_vars(&self.get_generics().ty_params)))
     }
 }
 
 impl to_type_decls for state {
-    fn to_type_decls(&self, cx: @ext_ctxt) -> ~[@ast::item] {
+    fn to_type_decls(&self, cx: @ExtCtxt) -> ~[@ast::item] {
         debug!("pipec: to_type_decls");
         // This compiles into two different type declarations. Say the
         // state is called ping. This will generate both `ping` and
@@ -217,7 +220,7 @@ impl to_type_decls for state {
                 };
 
                 vec::append_one(tys,
-                                cx.ty_path_ast_builder(
+                                cx.ty_path(
                                     path(~[cx.ident_of(dir),
                                            cx.ident_of(next_name)], span)
                                     .add_tys(copy next_state.tys)))
@@ -225,22 +228,22 @@ impl to_type_decls for state {
               None => tys
             };
 
-            let v = cx.variant(cx.ident_of(name), span, tys);
+            let v = cx.variant(span, cx.ident_of(name), tys);
 
             items_msg.push(v);
         }
 
         ~[
             cx.item_enum_poly(
-                name,
                 self.span,
+                name,
                 ast::enum_def { variants: items_msg },
                 cx.strip_bounds(&self.generics)
             )
         ]
     }
 
-    fn to_endpoint_decls(&self, cx: @ext_ctxt,
+    fn to_endpoint_decls(&self, cx: @ExtCtxt,
                          dir: direction) -> ~[@ast::item] {
         debug!("pipec: to_endpoint_decls");
         let dir = match dir {
@@ -262,33 +265,33 @@ impl to_type_decls for state {
         if !self.proto.is_bounded() {
             items.push(
                 cx.item_ty_poly(
-                    self.data_name(),
                     self.span,
-                    cx.ty_path_ast_builder(
+                    self.data_name(),
+                    cx.ty_path(
                         path_global(~[cx.ident_of("core"),
                                       cx.ident_of("pipes"),
                                       cx.ident_of(dir.to_str() + "Packet")],
                              dummy_sp())
-                        .add_ty(cx.ty_path_ast_builder(
+                        .add_ty(cx.ty_path(
                             path(~[cx.ident_of("super"),
                                    self.data_name()],
                                  dummy_sp())
-                            .add_tys(cx.ty_vars_global(
+                            .add_tys(cx.ty_vars(
                                 &self.generics.ty_params))))),
                     cx.strip_bounds(&self.generics)));
         }
         else {
             items.push(
                 cx.item_ty_poly(
-                    self.data_name(),
                     self.span,
-                    cx.ty_path_ast_builder(
+                    self.data_name(),
+                    cx.ty_path(
                         path_global(~[cx.ident_of("core"),
                                       cx.ident_of("pipes"),
                                       cx.ident_of(dir.to_str()
                                                   + "PacketBuffered")],
                              dummy_sp())
-                        .add_tys(~[cx.ty_path_ast_builder(
+                        .add_tys(~[cx.ty_path(
                             path(~[cx.ident_of("super"),
                                    self.data_name()],
                                         dummy_sp())
@@ -302,7 +305,7 @@ impl to_type_decls for state {
 }
 
 impl gen_init for protocol {
-    fn gen_init(&self, cx: @ext_ctxt) -> @ast::item {
+    fn gen_init(&self, cx: @ExtCtxt) -> @ast::item {
         let ext_cx = cx;
 
         debug!("gen_init");
@@ -340,19 +343,22 @@ impl gen_init for protocol {
                            body.to_source(cx)))
     }
 
-    fn gen_buffer_init(&self, ext_cx: @ext_ctxt) -> @ast::expr {
-        ext_cx.struct_expr(path(~[ext_cx.ident_of("__Buffer")],
-                                dummy_sp()),
-                      self.states.map_to_vec(|s| {
-            let fty = s.to_ty(ext_cx);
-            ext_cx.field_imm(ext_cx.ident_of(s.name),
-                             quote_expr!(
-                                 ::core::pipes::mk_packet::<$fty>()
-                             ))
-        }))
+    fn gen_buffer_init(&self, ext_cx: @ExtCtxt) -> @ast::expr {
+        ext_cx.expr_struct(
+            dummy_sp(),
+            path(~[ext_cx.ident_of("__Buffer")],
+                 dummy_sp()),
+            self.states.map_to_vec(|s| {
+                let fty = s.to_ty(ext_cx);
+                ext_cx.field_imm(dummy_sp(),
+                                 ext_cx.ident_of(s.name),
+                                 quote_expr!(
+                                     ::core::pipes::mk_packet::<$fty>()
+                                 ))
+            }))
     }
 
-    fn gen_init_bounded(&self, ext_cx: @ext_ctxt) -> @ast::expr {
+    fn gen_init_bounded(&self, ext_cx: @ExtCtxt) -> @ast::expr {
         debug!("gen_init_bounded");
         let buffer_fields = self.gen_buffer_init(ext_cx);
         let buffer = quote_expr!(~::core::pipes::Buffer {
@@ -360,15 +366,16 @@ impl gen_init for protocol {
             data: $buffer_fields,
         });
 
-        let entangle_body = ext_cx.block_expr(
-            ext_cx.block(
+        let entangle_body = ext_cx.expr_blk(
+            ext_cx.blk(
+                dummy_sp(),
                 self.states.map_to_vec(
                     |s| ext_cx.parse_stmt(
                         fmt!("data.%s.set_buffer(buffer)",
                              s.name))),
-                ext_cx.parse_expr(fmt!(
+                Some(ext_cx.parse_expr(fmt!(
                     "::core::ptr::to_mut_unsafe_ptr(&mut (data.%s))",
-                    self.states[0].name))));
+                    self.states[0].name)))));
 
         quote_expr!({
             let buffer = $buffer;
@@ -378,7 +385,7 @@ impl gen_init for protocol {
         })
     }
 
-    fn buffer_ty_path(&self, cx: @ext_ctxt) -> @ast::Ty {
+    fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty {
         let mut params: OptVec<ast::TyParam> = opt_vec::Empty;
         for (copy self.states).each |s| {
             for s.generics.ty_params.each |tp| {
@@ -389,13 +396,13 @@ impl gen_init for protocol {
             }
         }
 
-        cx.ty_path_ast_builder(path(~[cx.ident_of("super"),
-                                      cx.ident_of("__Buffer")],
-                                    copy self.span)
-                               .add_tys(cx.ty_vars_global(&params)))
+        cx.ty_path(path(~[cx.ident_of("super"),
+                          cx.ident_of("__Buffer")],
+                        copy self.span)
+                   .add_tys(cx.ty_vars_global(&params)))
     }
 
-    fn gen_buffer_type(&self, cx: @ext_ctxt) -> @ast::item {
+    fn gen_buffer_type(&self, cx: @ExtCtxt) -> @ast::item {
         let ext_cx = cx;
         let mut params: OptVec<ast::TyParam> = opt_vec::Empty;
         let fields = do (copy self.states).map_to_vec |s| {
@@ -427,8 +434,8 @@ impl gen_init for protocol {
         };
 
         cx.item_struct_poly(
-            cx.ident_of("__Buffer"),
             dummy_sp(),
+            cx.ident_of("__Buffer"),
             ast::struct_def {
                 fields: fields,
                 ctor_id: None
@@ -436,7 +443,7 @@ impl gen_init for protocol {
             cx.strip_bounds(&generics))
     }
 
-    fn compile(&self, cx: @ext_ctxt) -> @ast::item {
+    fn compile(&self, cx: @ExtCtxt) -> @ast::item {
         let mut items = ~[self.gen_init(cx)];
         let mut client_states = ~[];
         let mut server_states = ~[];
@@ -452,13 +459,24 @@ impl gen_init for protocol {
             items.push(self.gen_buffer_type(cx))
         }
 
-        items.push(cx.item_mod(cx.ident_of("client"),
-                               copy self.span,
+        items.push(cx.item_mod(copy self.span,
+                               cx.ident_of("client"),
+                               ~[], ~[],
                                client_states));
-        items.push(cx.item_mod(cx.ident_of("server"),
-                               copy self.span,
+        items.push(cx.item_mod(copy self.span,
+                               cx.ident_of("server"),
+                               ~[], ~[],
                                server_states));
 
-        cx.item_mod(cx.ident_of(copy self.name), copy self.span, items)
+        // XXX: Would be nice if our generated code didn't violate
+        // Rust coding conventions
+        let allows = cx.attribute(
+            copy self.span,
+            cx.meta_list(copy self.span,
+                         ~"allow",
+                         ~[cx.meta_word(copy self.span, ~"non_camel_case_types"),
+                           cx.meta_word(copy self.span, ~"unused_mut")]));
+        cx.item_mod(copy self.span, cx.ident_of(copy self.name),
+                    ~[allows], ~[], items)
     }
 }
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 7bf58bc6f32..4471c5bb9b8 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -10,8 +10,9 @@
 
 use ast;
 use codemap::span;
-use ext::base::ext_ctxt;
-use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path};
+use ext::base::ExtCtxt;
+use ext::build::AstBuilder;
+use ext::pipes::ast_builder::{append_types, path};
 
 #[deriving(Eq)]
 pub enum direction { send, recv }
@@ -92,8 +93,8 @@ pub impl state_ {
     }
 
     /// Returns the type that is used for the messages.
-    fn to_ty(&self, cx: @ext_ctxt) -> @ast::Ty {
-        cx.ty_path_ast_builder
+    fn to_ty(&self, cx: @ExtCtxt) -> @ast::Ty {
+        cx.ty_path
             (path(~[cx.ident_of(self.name)],self.span).add_tys(
                 cx.ty_vars(&self.generics.ty_params)))
     }
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 2134c2ba19b..1c57d500c22 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -10,9 +10,9 @@
 
 use ast;
 use codemap::{BytePos, Pos, span};
-use ext::base::ext_ctxt;
+use ext::base::ExtCtxt;
 use ext::base;
-use ext::build;
+use ext::build::AstBuilder;
 use parse::token::*;
 use parse::token;
 use parse;
@@ -30,7 +30,7 @@ use parse;
 
 pub mod rt {
     use ast;
-    use ext::base::ext_ctxt;
+    use ext::base::ExtCtxt;
     use parse;
     use print::pprust;
 
@@ -44,11 +44,11 @@ pub mod rt {
     use print::pprust::{item_to_str, ty_to_str};
 
     pub trait ToTokens {
-        pub fn to_tokens(&self, _cx: @ext_ctxt) -> ~[token_tree];
+        pub fn to_tokens(&self, _cx: @ExtCtxt) -> ~[token_tree];
     }
 
     impl ToTokens for ~[token_tree] {
-        pub fn to_tokens(&self, _cx: @ext_ctxt) -> ~[token_tree] {
+        pub fn to_tokens(&self, _cx: @ExtCtxt) -> ~[token_tree] {
             copy *self
         }
     }
@@ -57,10 +57,10 @@ pub mod rt {
 
     trait ToSource : ToTokens {
         // Takes a thing and generates a string containing rust code for it.
-        pub fn to_source(cx: @ext_ctxt) -> ~str;
+        pub fn to_source(cx: @ExtCtxt) -> ~str;
 
         // If you can make source, you can definitely make tokens.
-        pub fn to_tokens(cx: @ext_ctxt) -> ~[token_tree] {
+        pub fn to_tokens(cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
@@ -69,80 +69,80 @@ pub mod rt {
 
     pub trait ToSource {
         // Takes a thing and generates a string containing rust code for it.
-        pub fn to_source(&self, cx: @ext_ctxt) -> ~str;
+        pub fn to_source(&self, cx: @ExtCtxt) -> ~str;
     }
 
     impl ToSource for ast::ident {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             copy *cx.parse_sess().interner.get(*self)
         }
     }
 
     impl ToSource for @ast::item {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             item_to_str(*self, cx.parse_sess().interner)
         }
     }
 
     impl<'self> ToSource for &'self [@ast::item] {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             str::connect(self.map(|i| i.to_source(cx)), "\n\n")
         }
     }
 
     impl ToSource for @ast::Ty {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             ty_to_str(*self, cx.parse_sess().interner)
         }
     }
 
     impl<'self> ToSource for &'self [@ast::Ty] {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             str::connect(self.map(|i| i.to_source(cx)), ", ")
         }
     }
 
     impl ToSource for Generics {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             pprust::generics_to_str(self, cx.parse_sess().interner)
         }
     }
 
     impl ToSource for @ast::expr {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             pprust::expr_to_str(*self, cx.parse_sess().interner)
         }
     }
 
     impl ToSource for ast::blk {
-        fn to_source(&self, cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, cx: @ExtCtxt) -> ~str {
             pprust::block_to_str(self, cx.parse_sess().interner)
         }
     }
 
     impl<'self> ToSource for &'self str {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_str(@str::to_owned(*self)));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for int {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for i8 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i8));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for i16 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i16));
             pprust::lit_to_str(@lit)
         }
@@ -150,49 +150,49 @@ pub mod rt {
 
 
     impl ToSource for i32 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i32));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for i64 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i64));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for uint {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for u8 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u8));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for u16 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u16));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for u32 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u32));
             pprust::lit_to_str(@lit)
         }
     }
 
     impl ToSource for u64 {
-        fn to_source(&self, _cx: @ext_ctxt) -> ~str {
+        fn to_source(&self, _cx: @ExtCtxt) -> ~str {
             let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u64));
             pprust::lit_to_str(@lit)
         }
@@ -201,115 +201,115 @@ pub mod rt {
     // Alas ... we write these out instead. All redundant.
 
     impl ToTokens for ast::ident {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for @ast::item {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl<'self> ToTokens for &'self [@ast::item] {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for @ast::Ty {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl<'self> ToTokens for &'self [@ast::Ty] {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for Generics {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for @ast::expr {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for ast::blk {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl<'self> ToTokens for &'self str {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for int {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for i8 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for i16 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for i32 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for i64 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for uint {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for u8 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for u16 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for u32 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
 
     impl ToTokens for u64 {
-        fn to_tokens(&self, cx: @ext_ctxt) -> ~[token_tree] {
+        fn to_tokens(&self, cx: @ExtCtxt) -> ~[token_tree] {
             cx.parse_tts(self.to_source(cx))
         }
     }
@@ -321,7 +321,7 @@ pub mod rt {
         fn parse_tts(&self, s: ~str) -> ~[ast::token_tree];
     }
 
-    impl ExtParseUtils for @ext_ctxt {
+    impl ExtParseUtils for ExtCtxt {
 
         fn parse_item(&self, s: ~str) -> @ast::item {
             let res = parse::parse_item_from_source_str(
@@ -367,74 +367,74 @@ pub mod rt {
 
 }
 
-pub fn expand_quote_tokens(cx: @ext_ctxt,
+pub fn expand_quote_tokens(cx: @ExtCtxt,
                            sp: span,
                            tts: &[ast::token_tree]) -> base::MacResult {
     base::MRExpr(expand_tts(cx, sp, tts))
 }
 
-pub fn expand_quote_expr(cx: @ext_ctxt,
+pub fn expand_quote_expr(cx: @ExtCtxt,
                          sp: span,
                          tts: &[ast::token_tree]) -> base::MacResult {
     base::MRExpr(expand_parse_call(cx, sp, "parse_expr", ~[], tts))
 }
 
-pub fn expand_quote_item(cx: @ext_ctxt,
+pub fn expand_quote_item(cx: @ExtCtxt,
                          sp: span,
                          tts: &[ast::token_tree]) -> base::MacResult {
-    let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
+    let e_attrs = cx.expr_vec_uniq(sp, ~[]);
     base::MRExpr(expand_parse_call(cx, sp, "parse_item",
                                     ~[e_attrs], tts))
 }
 
-pub fn expand_quote_pat(cx: @ext_ctxt,
+pub fn expand_quote_pat(cx: @ExtCtxt,
                         sp: span,
                         tts: &[ast::token_tree]) -> base::MacResult {
-    let e_refutable = build::mk_lit(cx, sp, ast::lit_bool(true));
+    let e_refutable = cx.expr_lit(sp, ast::lit_bool(true));
     base::MRExpr(expand_parse_call(cx, sp, "parse_pat",
                                     ~[e_refutable], tts))
 }
 
-pub fn expand_quote_ty(cx: @ext_ctxt,
+pub fn expand_quote_ty(cx: @ExtCtxt,
                        sp: span,
                        tts: &[ast::token_tree]) -> base::MacResult {
-    let e_param_colons = build::mk_lit(cx, sp, ast::lit_bool(false));
+    let e_param_colons = cx.expr_lit(sp, ast::lit_bool(false));
     base::MRExpr(expand_parse_call(cx, sp, "parse_ty",
                                     ~[e_param_colons], tts))
 }
 
-pub fn expand_quote_stmt(cx: @ext_ctxt,
+pub fn expand_quote_stmt(cx: @ExtCtxt,
                          sp: span,
                          tts: &[ast::token_tree]) -> base::MacResult {
-    let e_attrs = build::mk_uniq_vec_e(cx, sp, ~[]);
+    let e_attrs = cx.expr_vec_uniq(sp, ~[]);
     base::MRExpr(expand_parse_call(cx, sp, "parse_stmt",
                                     ~[e_attrs], tts))
 }
 
-fn ids_ext(cx: @ext_ctxt, strs: ~[~str]) -> ~[ast::ident] {
+fn ids_ext(cx: @ExtCtxt, strs: ~[~str]) -> ~[ast::ident] {
     strs.map(|str| cx.parse_sess().interner.intern(*str))
 }
 
-fn id_ext(cx: @ext_ctxt, str: &str) -> ast::ident {
+fn id_ext(cx: @ExtCtxt, str: &str) -> ast::ident {
     cx.parse_sess().interner.intern(str)
 }
 
 // Lift an ident to the expr that evaluates to that ident.
-fn mk_ident(cx: @ext_ctxt, sp: span, ident: ast::ident) -> @ast::expr {
-    let e_str = build::mk_base_str(cx, sp, cx.str_of(ident));
-    build::mk_method_call(cx, sp,
-                          build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
-                          id_ext(cx, "ident_of"),
-                          ~[e_str])
+fn mk_ident(cx: @ExtCtxt, sp: span, ident: ast::ident) -> @ast::expr {
+    let e_str = cx.expr_str(sp, cx.str_of(ident));
+    cx.expr_method_call(sp,
+                        cx.expr_ident(sp, id_ext(cx, "ext_cx")),
+                        id_ext(cx, "ident_of"),
+                        ~[e_str])
 }
 
-fn mk_bytepos(cx: @ext_ctxt, sp: span, bpos: BytePos) -> @ast::expr {
-    let path = ids_ext(cx, ~[~"BytePos"]);
-    let arg = build::mk_uint(cx, sp, bpos.to_uint());
-    build::mk_call(cx, sp, path, ~[arg])
+fn mk_bytepos(cx: @ExtCtxt, sp: span, bpos: BytePos) -> @ast::expr {
+    let path = id_ext(cx, "BytePos");
+    let arg = cx.expr_uint(sp, bpos.to_uint());
+    cx.expr_call_ident(sp, path, ~[arg])
 }
 
-fn mk_binop(cx: @ext_ctxt, sp: span, bop: token::binop) -> @ast::expr {
+fn mk_binop(cx: @ExtCtxt, sp: span, bop: token::binop) -> @ast::expr {
     let name = match bop {
         PLUS => "PLUS",
         MINUS => "MINUS",
@@ -447,22 +447,21 @@ fn mk_binop(cx: @ext_ctxt, sp: span, bop: token::binop) -> @ast::expr {
         SHL => "SHL",
         SHR => "SHR"
     };
-    build::mk_path(cx, sp,
-                   ids_ext(cx, ~[name.to_owned()]))
+    cx.expr_ident(sp, id_ext(cx, name))
 }
 
-fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
+fn mk_token(cx: @ExtCtxt, sp: span, tok: &token::Token) -> @ast::expr {
 
     match *tok {
         BINOP(binop) => {
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"BINOP"]),
-                                  ~[mk_binop(cx, sp, binop)]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "BINOP"),
+                                      ~[mk_binop(cx, sp, binop)]);
         }
         BINOPEQ(binop) => {
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"BINOPEQ"]),
-                                  ~[mk_binop(cx, sp, binop)]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "BINOPEQ"),
+                                      ~[mk_binop(cx, sp, binop)]);
         }
 
         LIT_INT(i, ity) => {
@@ -474,15 +473,13 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
                 ast::ty_i32 => ~"ty_i32",
                 ast::ty_i64 => ~"ty_i64"
             };
-            let e_ity =
-                build::mk_path(cx, sp,
-                               ids_ext(cx, ~[s_ity]));
+            let e_ity = cx.expr_ident(sp, id_ext(cx, s_ity));
 
-            let e_i64 = build::mk_lit(cx, sp, ast::lit_int(i, ast::ty_i64));
+            let e_i64 = cx.expr_lit(sp, ast::lit_int(i, ast::ty_i64));
 
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"LIT_INT"]),
-                                  ~[e_i64, e_ity]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "LIT_INT"),
+                                      ~[e_i64, e_ity]);
         }
 
         LIT_UINT(u, uty) => {
@@ -493,24 +490,21 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
                 ast::ty_u32 => ~"ty_u32",
                 ast::ty_u64 => ~"ty_u64"
             };
-            let e_uty =
-                build::mk_path(cx, sp,
-                               ids_ext(cx, ~[s_uty]));
+            let e_uty = cx.expr_ident(sp, id_ext(cx, s_uty));
 
-            let e_u64 = build::mk_lit(cx, sp, ast::lit_uint(u, ast::ty_u64));
+            let e_u64 = cx.expr_lit(sp, ast::lit_uint(u, ast::ty_u64));
 
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"LIT_UINT"]),
-                                  ~[e_u64, e_uty]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "LIT_UINT"),
+                                      ~[e_u64, e_uty]);
         }
 
         LIT_INT_UNSUFFIXED(i) => {
-            let e_i64 = build::mk_lit(cx, sp,
-                                      ast::lit_int(i, ast::ty_i64));
+            let e_i64 = cx.expr_lit(sp, ast::lit_int(i, ast::ty_i64));
 
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"LIT_INT_UNSUFFIXED"]),
-                                  ~[e_i64]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "LIT_INT_UNSUFFIXED"),
+                                      ~[e_i64]);
         }
 
         LIT_FLOAT(fident, fty) => {
@@ -519,40 +513,38 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
                 ast::ty_f32 => ~"ty_f32",
                 ast::ty_f64 => ~"ty_f64"
             };
-            let e_fty =
-                build::mk_path(cx, sp,
-                               ids_ext(cx, ~[s_fty]));
+            let e_fty = cx.expr_ident(sp, id_ext(cx, s_fty));
 
             let e_fident = mk_ident(cx, sp, fident);
 
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"LIT_FLOAT"]),
-                                  ~[e_fident, e_fty]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "LIT_FLOAT"),
+                                      ~[e_fident, e_fty]);
         }
 
         LIT_STR(ident) => {
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"LIT_STR"]),
-                                  ~[mk_ident(cx, sp, ident)]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "LIT_STR"),
+                                      ~[mk_ident(cx, sp, ident)]);
         }
 
         IDENT(ident, b) => {
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"IDENT"]),
-                                  ~[mk_ident(cx, sp, ident),
-                                    build::mk_lit(cx, sp, ast::lit_bool(b))]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "IDENT"),
+                                      ~[mk_ident(cx, sp, ident),
+                                        cx.expr_bool(sp, b)]);
         }
 
         LIFETIME(ident) => {
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"LIFETIME"]),
-                                  ~[mk_ident(cx, sp, ident)]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "LIFETIME"),
+                                      ~[mk_ident(cx, sp, ident)]);
         }
 
         DOC_COMMENT(ident) => {
-            return build::mk_call(cx, sp,
-                                  ids_ext(cx, ~[~"DOC_COMMENT"]),
-                                  ~[mk_ident(cx, sp, ident)]);
+            return cx.expr_call_ident(sp,
+                                      id_ext(cx, "DOC_COMMENT"),
+                                      ~[mk_ident(cx, sp, ident)]);
         }
 
         INTERPOLATED(_) => fail!("quote! with interpolated token"),
@@ -595,30 +587,26 @@ fn mk_token(cx: @ext_ctxt, sp: span, tok: &token::Token) -> @ast::expr {
         EOF => "EOF",
         _ => fail!()
     };
-    build::mk_path(cx, sp,
-                   ids_ext(cx, ~[name.to_owned()]))
+    cx.expr_ident(sp, id_ext(cx, name))
 }
 
 
-fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree)
+fn mk_tt(cx: @ExtCtxt, sp: span, tt: &ast::token_tree)
     -> ~[@ast::stmt] {
 
     match *tt {
 
         ast::tt_tok(sp, ref tok) => {
-            let e_sp = build::mk_path(cx, sp,
-                                      ids_ext(cx, ~[~"sp"]));
-            let e_tok =
-                build::mk_call(cx, sp,
-                               ids_ext(cx, ~[~"tt_tok"]),
-                               ~[e_sp, mk_token(cx, sp, tok)]);
+            let e_sp = cx.expr_ident(sp, id_ext(cx, "sp"));
+            let e_tok = cx.expr_call_ident(sp,
+                                           id_ext(cx, "tt_tok"),
+                                           ~[e_sp, mk_token(cx, sp, tok)]);
             let e_push =
-                build::mk_method_call(cx, sp,
-                                      build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])),
-                                      id_ext(cx, "push"),
-                                      ~[e_tok]);
-            ~[build::mk_stmt(cx, sp, e_push)]
-
+                cx.expr_method_call(sp,
+                                    cx.expr_ident(sp, id_ext(cx, "tt")),
+                                    id_ext(cx, "push"),
+                                    ~[e_tok]);
+            ~[cx.stmt_expr(e_push)]
         }
 
         ast::tt_delim(ref tts) => mk_tts(cx, sp, *tts),
@@ -629,24 +617,23 @@ fn mk_tt(cx: @ext_ctxt, sp: span, tt: &ast::token_tree)
             // tt.push_all_move($ident.to_tokens(ext_cx))
 
             let e_to_toks =
-                build::mk_method_call(cx, sp,
-                                      build::mk_path(cx, sp, ~[ident]),
-                                      id_ext(cx, "to_tokens"),
-                                      ~[build::mk_path(cx, sp,
-                                                       ids_ext(cx, ~[~"ext_cx"]))]);
+                cx.expr_method_call(sp,
+                                    cx.expr_ident(sp, ident),
+                                    id_ext(cx, "to_tokens"),
+                                    ~[cx.expr_ident(sp, id_ext(cx, "ext_cx"))]);
 
             let e_push =
-                build::mk_method_call(cx, sp,
-                                      build::mk_path(cx, sp, ids_ext(cx, ~[~"tt"])),
-                                      id_ext(cx, "push_all_move"),
-                                      ~[e_to_toks]);
+                cx.expr_method_call(sp,
+                                    cx.expr_ident(sp, id_ext(cx, "tt")),
+                                    id_ext(cx, "push_all_move"),
+                                    ~[e_to_toks]);
 
-            ~[build::mk_stmt(cx, sp, e_push)]
+            ~[cx.stmt_expr(e_push)]
         }
     }
 }
 
-fn mk_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+fn mk_tts(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> ~[@ast::stmt] {
     let mut ss = ~[];
     for tts.each |tt| {
@@ -655,7 +642,7 @@ fn mk_tts(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
     ss
 }
 
-fn expand_tts(cx: @ext_ctxt,
+fn expand_tts(cx: @ExtCtxt,
               sp: span,
               tts: &[ast::token_tree]) -> @ast::expr {
 
@@ -677,11 +664,11 @@ fn expand_tts(cx: @ext_ctxt,
     // We want to emit a block expression that does a sequence of 'use's to
     // import the runtime module, followed by a tt-building expression.
 
-    let uses = ~[ build::mk_glob_use(cx, sp, ast::public,
-                                     ids_ext(cx, ~[~"syntax",
-                                                   ~"ext",
-                                                   ~"quote",
-                                                   ~"rt"])) ];
+    let uses = ~[ cx.view_use_glob(sp, ast::public,
+                                   ids_ext(cx, ~[~"syntax",
+                                                 ~"ext",
+                                                 ~"quote",
+                                                 ~"rt"])) ];
 
     // We also bind a single value, sp, to ext_cx.call_site()
     //
@@ -709,54 +696,53 @@ fn expand_tts(cx: @ext_ctxt,
     // of quotes, for example) but at this point it seems not likely to be
     // worth the hassle.
 
-    let e_sp = build::mk_method_call(cx, sp,
-                                     build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
-                                     id_ext(cx, "call_site"),
-                                     ~[]);
+    let e_sp = cx.expr_method_call(sp,
+                                   cx.expr_ident(sp, id_ext(cx, "ext_cx")),
+                                   id_ext(cx, "call_site"),
+                                   ~[]);
 
-    let stmt_let_sp = build::mk_local(cx, sp, false,
-                                      id_ext(cx, "sp"),
-                                      e_sp);
+    let stmt_let_sp = cx.stmt_let(sp, false,
+                                  id_ext(cx, "sp"),
+                                  e_sp);
 
-    let stmt_let_tt = build::mk_local(cx, sp, true,
-                                      id_ext(cx, "tt"),
-                                      build::mk_uniq_vec_e(cx, sp, ~[]));
+    let stmt_let_tt = cx.stmt_let(sp, true,
+                                  id_ext(cx, "tt"),
+                                  cx.expr_vec_uniq(sp, ~[]));
 
-    build::mk_block(cx, sp, uses,
-                    ~[stmt_let_sp,
-                      stmt_let_tt] + mk_tts(cx, sp, tts),
-                    Some(build::mk_path(cx, sp,
-                                        ids_ext(cx, ~[~"tt"]))))
+    cx.expr_blk(
+        cx.blk_all(sp, uses,
+                   ~[stmt_let_sp,
+                     stmt_let_tt] + mk_tts(cx, sp, tts),
+                   Some(cx.expr_ident(sp, id_ext(cx, "tt")))))
 }
 
-fn expand_parse_call(cx: @ext_ctxt,
+fn expand_parse_call(cx: @ExtCtxt,
                      sp: span,
                      parse_method: &str,
                      arg_exprs: ~[@ast::expr],
                      tts: &[ast::token_tree]) -> @ast::expr {
     let tts_expr = expand_tts(cx, sp, tts);
 
-    let cfg_call = || build::mk_method_call(
-        cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
+    let cfg_call = || cx.expr_method_call(
+        sp, cx.expr_ident(sp, id_ext(cx, "ext_cx")),
         id_ext(cx, "cfg"), ~[]);
 
-    let parse_sess_call = || build::mk_method_call(
-        cx, sp, build::mk_path(cx, sp, ids_ext(cx, ~[~"ext_cx"])),
+    let parse_sess_call = || cx.expr_method_call(
+        sp, cx.expr_ident(sp, id_ext(cx, "ext_cx")),
         id_ext(cx, "parse_sess"), ~[]);
 
     let new_parser_call =
-        build::mk_call_global(cx, sp,
-                              ids_ext(cx, ~[~"syntax",
-                                            ~"ext",
-                                            ~"quote",
-                                            ~"rt",
-                                            ~"new_parser_from_tts"]),
-                              ~[parse_sess_call(),
-                                cfg_call(),
-                                tts_expr]);
-
-    build::mk_method_call(cx, sp,
-                          new_parser_call,
-                          id_ext(cx, parse_method),
-                          arg_exprs)
+        cx.expr_call_global(sp,
+                            ids_ext(cx, ~[~"syntax",
+                                          ~"ext",
+                                          ~"quote",
+                                          ~"rt",
+                                          ~"new_parser_from_tts"]),
+                            ~[parse_sess_call(),
+                              cfg_call(),
+                              tts_expr]);
+
+    cx.expr_method_call(sp, new_parser_call,
+                        id_ext(cx, parse_method),
+                        arg_exprs)
 }
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index c0d9b3f06af..30e6b7cfc65 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -14,7 +14,7 @@ use codemap::{FileMap, Loc, Pos, ExpandedFrom, span};
 use codemap::{CallInfo, NameAndSpan};
 use ext::base::*;
 use ext::base;
-use ext::build::{mk_base_vec_e, mk_uint, mk_u8, mk_base_str};
+use ext::build::AstBuilder;
 use parse;
 use print::pprust;
 
@@ -23,49 +23,49 @@ use print::pprust;
 // a given file into the current one.
 
 /* line!(): expands to the current line number */
-pub fn expand_line(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_line(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     base::check_zero_tts(cx, sp, tts, "line!");
 
     let topmost = topmost_expn_info(cx.backtrace().get());
     let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
 
-    base::MRExpr(mk_uint(cx, topmost.call_site, loc.line))
+    base::MRExpr(cx.expr_uint(topmost.call_site, loc.line))
 }
 
 /* col!(): expands to the current column number */
-pub fn expand_col(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_col(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     base::check_zero_tts(cx, sp, tts, "col!");
 
     let topmost = topmost_expn_info(cx.backtrace().get());
     let loc = cx.codemap().lookup_char_pos(topmost.call_site.lo);
-    base::MRExpr(mk_uint(cx, topmost.call_site, loc.col.to_uint()))
+    base::MRExpr(cx.expr_uint(topmost.call_site, loc.col.to_uint()))
 }
 
 /* file!(): expands to the current filename */
 /* The filemap (`loc.file`) contains a bunch more information we could spit
  * out if we wanted. */
-pub fn expand_file(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_file(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     base::check_zero_tts(cx, sp, tts, "file!");
 
     let topmost = topmost_expn_info(cx.backtrace().get());
     let Loc { file: @FileMap { name: filename, _ }, _ } =
         cx.codemap().lookup_char_pos(topmost.call_site.lo);
-    base::MRExpr(mk_base_str(cx, topmost.call_site, filename))
+    base::MRExpr(cx.expr_str(topmost.call_site, filename))
 }
 
-pub fn expand_stringify(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_stringify(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     let s = pprust::tts_to_str(tts, cx.parse_sess().interner);
-    base::MRExpr(mk_base_str(cx, sp, s))
+    base::MRExpr(cx.expr_str(sp, s))
 }
 
-pub fn expand_mod(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_mod(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     base::check_zero_tts(cx, sp, tts, "module_path!");
-    base::MRExpr(mk_base_str(cx, sp,
+    base::MRExpr(cx.expr_str(sp,
                               str::connect(cx.mod_path().map(
                                   |x| cx.str_of(*x)), "::")))
 }
@@ -73,7 +73,7 @@ pub fn expand_mod(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
 // include! : parse the given file as an expr
 // This is generally a bad idea because it's going to behave
 // unhygienically.
-pub fn expand_include(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_include(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     let file = get_single_str_from_tts(cx, sp, tts, "include!");
     let p = parse::new_sub_parser_from_file(
@@ -83,7 +83,7 @@ pub fn expand_include(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
 }
 
 // include_str! : read the given file, insert it as a literal string expr
-pub fn expand_include_str(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_include_str(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     let file = get_single_str_from_tts(cx, sp, tts, "include_str!");
     let res = io::read_whole_file_str(&res_rel_file(cx, sp, &Path(file)));
@@ -94,18 +94,18 @@ pub fn expand_include_str(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
       }
     }
 
-    base::MRExpr(mk_base_str(cx, sp, result::unwrap(res)))
+    base::MRExpr(cx.expr_str(sp, result::unwrap(res)))
 }
 
-pub fn expand_include_bin(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
+pub fn expand_include_bin(cx: @ExtCtxt, sp: span, tts: &[ast::token_tree])
     -> base::MacResult {
     let file = get_single_str_from_tts(cx, sp, tts, "include_bin!");
     match io::read_whole_file(&res_rel_file(cx, sp, &Path(file))) {
       result::Ok(src) => {
         let u8_exprs = vec::map(src, |char| {
-            mk_u8(cx, sp, *char)
+            cx.expr_u8(sp, *char)
         });
-        base::MRExpr(mk_base_vec_e(cx, sp, u8_exprs))
+        base::MRExpr(cx.expr_vec(sp, u8_exprs))
       }
       result::Err(ref e) => {
         cx.parse_sess().span_diagnostic.handler().fatal((*e))
@@ -141,7 +141,7 @@ fn topmost_expn_info(expn_info: @codemap::ExpnInfo) -> @codemap::ExpnInfo {
 
 // resolve a file-system path to an absolute file-system path (if it
 // isn't already)
-fn res_rel_file(cx: @ext_ctxt, sp: codemap::span, arg: &Path) -> Path {
+fn res_rel_file(cx: @ExtCtxt, sp: codemap::span, arg: &Path) -> Path {
     // NB: relative paths are resolved relative to the compilation unit
     if !arg.is_absolute {
         let cu = Path(cx.codemap().span_to_filename(sp));
diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs
index 0ecb3b2a3f4..25607a8bfa7 100644
--- a/src/libsyntax/ext/trace_macros.rs
+++ b/src/libsyntax/ext/trace_macros.rs
@@ -10,12 +10,12 @@
 
 use ast;
 use codemap::span;
-use ext::base::ext_ctxt;
+use ext::base::ExtCtxt;
 use ext::base;
 use parse::lexer::{new_tt_reader, reader};
 use parse::parser::Parser;
 
-pub fn expand_trace_macros(cx: @ext_ctxt,
+pub fn expand_trace_macros(cx: @ExtCtxt,
                            sp: span,
                            tt: &[ast::token_tree])
                         -> base::MacResult {
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index d34eca342e9..3814243efc4 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -13,7 +13,7 @@ use ast::{ident, matcher_, matcher, match_tok, match_nonterminal, match_seq};
 use ast::{tt_delim};
 use ast;
 use codemap::{span, spanned, dummy_sp};
-use ext::base::{ext_ctxt, MacResult, MRAny, MRDef, MacroDef, NormalTT};
+use ext::base::{ExtCtxt, MacResult, MRAny, MRDef, MacroDef, NormalTT};
 use ext::base;
 use ext::tt::macro_parser::{error};
 use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
@@ -26,7 +26,7 @@ use print;
 
 use core::io;
 
-pub fn add_new_extension(cx: @ext_ctxt,
+pub fn add_new_extension(cx: @ExtCtxt,
                          sp: span,
                          name: ident,
                          arg: ~[ast::token_tree])
@@ -73,7 +73,7 @@ pub fn add_new_extension(cx: @ext_ctxt,
     };
 
     // Given `lhses` and `rhses`, this is the new macro we create
-    fn generic_extension(cx: @ext_ctxt, sp: span, name: ident,
+    fn generic_extension(cx: @ExtCtxt, sp: span, name: ident,
                          arg: &[ast::token_tree],
                          lhses: &[@named_match], rhses: &[@named_match])
     -> MacResult {
@@ -145,7 +145,7 @@ pub fn add_new_extension(cx: @ext_ctxt,
         cx.span_fatal(best_fail_spot, best_fail_msg);
     }
 
-    let exp: @fn(@ext_ctxt, span, &[ast::token_tree]) -> MacResult =
+    let exp: @fn(@ExtCtxt, span, &[ast::token_tree]) -> MacResult =
         |cx, sp, arg| generic_extension(cx, sp, name, arg, *lhses, *rhses);
 
     return MRDef(MacroDef{