about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2013-02-05 10:33:28 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2013-02-05 10:33:28 -0800
commit2dcb3ed745d04048941a8130f3603c5759b2b142 (patch)
treeb02ae43f09244c7f4549a9c4171516d0cc257997 /src/libsyntax
parent6f0bede97c3468eaba8cf59702d04c7ede8f4b0a (diff)
parent2f46b763da2c098913884f101b6d71d69af41b49 (diff)
Merge
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs33
-rw-r--r--src/libsyntax/ast_map.rs12
-rw-r--r--src/libsyntax/ast_util.rs74
-rw-r--r--src/libsyntax/attr.rs16
-rw-r--r--src/libsyntax/codemap.rs136
-rw-r--r--src/libsyntax/diagnostic.rs4
-rw-r--r--src/libsyntax/ext/auto_encode.rs93
-rw-r--r--src/libsyntax/ext/base.rs5
-rw-r--r--src/libsyntax/ext/build.rs25
-rw-r--r--src/libsyntax/ext/deriving.rs4
-rw-r--r--src/libsyntax/ext/expand.rs15
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs13
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs4
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs2
-rw-r--r--src/libsyntax/ext/pipes/proto.rs4
-rw-r--r--src/libsyntax/ext/quote.rs8
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs21
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs7
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs17
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/attr.rs2
-rw-r--r--src/libsyntax/parse/classify.rs4
-rw-r--r--src/libsyntax/parse/comments.rs8
-rw-r--r--src/libsyntax/parse/common.rs13
-rw-r--r--src/libsyntax/parse/eval.rs5
-rw-r--r--src/libsyntax/parse/lexer.rs119
-rw-r--r--src/libsyntax/parse/mod.rs3
-rw-r--r--src/libsyntax/parse/obsolete.rs5
-rw-r--r--src/libsyntax/parse/parser.rs196
-rw-r--r--src/libsyntax/parse/token.rs14
-rw-r--r--src/libsyntax/print/pp.rs20
-rw-r--r--src/libsyntax/print/pprust.rs46
-rw-r--r--src/libsyntax/syntax.rc4
-rw-r--r--src/libsyntax/util/interner.rs6
-rw-r--r--src/libsyntax/util/testing.rs24
-rw-r--r--src/libsyntax/visit.rs1
36 files changed, 556 insertions, 408 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e85f41c54a2..bc808495ca3 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -10,7 +10,7 @@
 
 // The Rust abstract syntax tree.
 
-use codemap::{span, FileName};
+use codemap::{span, FileName, spanned};
 
 use core::cast;
 use core::cmp;
@@ -21,10 +21,6 @@ use core::to_bytes;
 use core::to_str::ToStr;
 use std::serialize::{Encodable, Decodable, Encoder, Decoder};
 
-#[auto_encode]
-#[auto_decode]
-pub struct spanned<T> { node: T, span: span }
-
 /* can't import macros yet, so this is copied from token.rs. See its comment
  * there. */
 macro_rules! interner_key (
@@ -40,7 +36,7 @@ pub impl<S: Encoder> ident: Encodable<S> {
         let intr = match unsafe {
             task::local_data::local_data_get(interner_key!())
         } {
-            None => fail ~"encode: TLS interner not set up",
+            None => die!(~"encode: TLS interner not set up"),
             Some(intr) => intr
         };
 
@@ -53,7 +49,7 @@ pub impl<D: Decoder> ident: Decodable<D> {
         let intr = match unsafe {
             task::local_data::local_data_get(interner_key!())
         } {
-            None => fail ~"decode: TLS interner not set up",
+            None => die!(~"decode: TLS interner not set up"),
             Some(intr) => intr
         };
 
@@ -690,7 +686,7 @@ pub enum expr_ {
     expr_cast(@expr, @Ty),
     expr_if(@expr, blk, Option<@expr>),
     expr_while(@expr, blk),
-    /* Conditionless loop (can be exited with break, cont, ret, or fail)
+    /* Conditionless loop (can be exited with break, cont, or ret)
        Same semantics as while(true) { body }, but typestate knows that the
        (implicit) condition is always true. */
     expr_loop(blk, Option<ident>),
@@ -716,7 +712,6 @@ pub enum expr_ {
     expr_index(@expr, @expr),
     expr_path(@path),
     expr_addr_of(mutability, @expr),
-    expr_fail(Option<@expr>),
     expr_break(Option<ident>),
     expr_again(Option<ident>),
     expr_ret(Option<@expr>),
@@ -928,8 +923,8 @@ pub enum trait_method {
 pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, }
 
 pub impl int_ty : ToStr {
-    pure fn to_str() -> ~str {
-        ::ast_util::int_ty_to_str(self)
+    pure fn to_str(&self) -> ~str {
+        ::ast_util::int_ty_to_str(*self)
     }
 }
 
@@ -964,8 +959,8 @@ pub impl int_ty : cmp::Eq {
 pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, }
 
 pub impl uint_ty : ToStr {
-    pure fn to_str() -> ~str {
-        ::ast_util::uint_ty_to_str(self)
+    pure fn to_str(&self) -> ~str {
+        ::ast_util::uint_ty_to_str(*self)
     }
 }
 
@@ -998,8 +993,8 @@ pub impl uint_ty : cmp::Eq {
 pub enum float_ty { ty_f, ty_f32, ty_f64, }
 
 pub impl float_ty : ToStr {
-    pure fn to_str() -> ~str {
-        ::ast_util::float_ty_to_str(self)
+    pure fn to_str(&self) -> ~str {
+        ::ast_util::float_ty_to_str(*self)
     }
 }
 
@@ -1101,8 +1096,8 @@ pub enum Onceness {
 }
 
 pub impl Onceness : ToStr {
-    pure fn to_str() -> ~str {
-        match self {
+    pure fn to_str(&self) -> ~str {
+        match *self {
             Once => ~"once",
             Many => ~"many"
         }
@@ -1193,8 +1188,8 @@ pub enum purity {
 }
 
 pub impl purity : ToStr {
-    pure fn to_str() -> ~str {
-        match self {
+    pure fn to_str(&self) -> ~str {
+        match *self {
             impure_fn => ~"impure",
             unsafe_fn => ~"unsafe",
             pure_fn => ~"pure",
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index a96829ed063..e6a4639ad80 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -25,8 +25,8 @@ use core::cmp;
 use core::either;
 use core::str;
 use core::vec;
-use std::map::HashMap;
-use std::map;
+use std::oldmap::HashMap;
+use std::oldmap;
 use std;
 
 pub enum path_elt {
@@ -106,7 +106,7 @@ pub enum ast_node {
     node_struct_ctor(@struct_def, @item, @path),
 }
 
-pub type map = std::map::HashMap<node_id, ast_node>;
+pub type map = std::oldmap::HashMap<node_id, ast_node>;
 pub struct ctx {
     map: map,
     mut path: path,
@@ -134,7 +134,7 @@ pub fn mk_ast_map_visitor() -> vt {
 
 pub fn map_crate(diag: span_handler, c: crate) -> map {
     let cx = ctx {
-        map: std::map::HashMap(),
+        map: std::oldmap::HashMap(),
         mut path: ~[],
         mut local_id: 0u,
         diag: diag,
@@ -316,7 +316,7 @@ pub fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node,
                     cx.map.insert(ctor_id,
                                   node_struct_ctor(struct_def, item, p));
                 }
-                _ => fail ~"struct def parent wasn't an item"
+                _ => die!(~"struct def parent wasn't an item")
             }
         }
     }
@@ -400,7 +400,7 @@ pub fn node_item_query<Result>(items: map, id: node_id,
                            error_msg: ~str) -> Result {
     match items.find(id) {
         Some(node_item(it, _)) => query(it),
-        _ => fail(error_msg)
+        _ => die!(error_msg)
     }
 }
 
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 1ae23240404..c659d6d6020 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -13,7 +13,7 @@ use core::prelude::*;
 use ast::*;
 use ast;
 use ast_util;
-use codemap::{span, BytePos};
+use codemap::{span, BytePos, dummy_sp};
 use parse::token;
 use visit;
 
@@ -24,28 +24,6 @@ use core::str;
 use core::to_bytes;
 use core::vec;
 
-pub pure fn spanned<T>(+lo: BytePos, +hi: BytePos, +t: T) -> spanned<T> {
-    respan(mk_sp(lo, hi), move t)
-}
-
-pub pure fn respan<T>(sp: span, +t: T) -> spanned<T> {
-    spanned {node: t, span: sp}
-}
-
-pub pure fn dummy_spanned<T>(+t: T) -> spanned<T> {
-    respan(dummy_sp(), move t)
-}
-
-/* assuming that we're not in macro expansion */
-pub pure fn mk_sp(+lo: BytePos, +hi: BytePos) -> span {
-    span {lo: lo, hi: hi, expn_info: None}
-}
-
-// make this a const, once the compiler supports it
-pub pure fn dummy_sp() -> span { return mk_sp(BytePos(0), BytePos(0)); }
-
-
-
 pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner)
                      -> ~str {
     // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
@@ -66,7 +44,7 @@ pub pure fn stmt_id(s: stmt) -> node_id {
       stmt_decl(_, id) => id,
       stmt_expr(_, id) => id,
       stmt_semi(_, id) => id,
-      stmt_mac(*) => fail ~"attempted to analyze unexpanded stmt",
+      stmt_mac(*) => die!(~"attempted to analyze unexpanded stmt")
     }
 }
 
@@ -75,7 +53,7 @@ pub fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} {
       def_variant(enum_id, var_id) => {
         return {enm: enum_id, var: var_id}
       }
-      _ => fail ~"non-variant in variant_def_ids"
+      _ => die!(~"non-variant in variant_def_ids")
     }
 }
 
@@ -93,7 +71,7 @@ pub pure fn def_id_of_def(d: def) -> def_id {
         local_def(id)
       }
 
-      def_prim_ty(_) => fail
+      def_prim_ty(_) => die!()
     }
 }
 
@@ -320,38 +298,38 @@ pub pure fn struct_field_visibility(field: ast::struct_field) -> visibility {
 }
 
 pub trait inlined_item_utils {
-    fn ident() -> ident;
-    fn id() -> ast::node_id;
-    fn accept<E>(e: E, v: visit::vt<E>);
+    fn ident(&self) -> ident;
+    fn id(&self) -> ast::node_id;
+    fn accept<E>(&self, e: E, v: visit::vt<E>);
 }
 
 pub impl inlined_item: inlined_item_utils {
-    fn ident() -> ident {
-        match self {
-          ii_item(i) => /* FIXME (#2543) */ copy i.ident,
-          ii_foreign(i) => /* FIXME (#2543) */ copy i.ident,
-          ii_method(_, m) => /* FIXME (#2543) */ copy m.ident,
-          ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm
+    fn ident(&self) -> ident {
+        match *self {
+            ii_item(i) => /* FIXME (#2543) */ copy i.ident,
+            ii_foreign(i) => /* FIXME (#2543) */ copy i.ident,
+            ii_method(_, m) => /* FIXME (#2543) */ copy m.ident,
+            ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm
         }
     }
 
-    fn id() -> ast::node_id {
-        match self {
-          ii_item(i) => i.id,
-          ii_foreign(i) => i.id,
-          ii_method(_, m) => m.id,
-          ii_dtor(ref dtor, _, _, _) => (*dtor).node.id
+    fn id(&self) -> ast::node_id {
+        match *self {
+            ii_item(i) => i.id,
+            ii_foreign(i) => i.id,
+            ii_method(_, m) => m.id,
+            ii_dtor(ref dtor, _, _, _) => (*dtor).node.id
         }
     }
 
-    fn accept<E>(e: E, v: visit::vt<E>) {
-        match self {
-          ii_item(i) => (v.visit_item)(i, e, v),
-          ii_foreign(i) => (v.visit_foreign_item)(i, e, v),
-          ii_method(_, m) => visit::visit_method_helper(m, e, v),
-          ii_dtor(ref dtor, _, tps, parent_id) => {
+    fn accept<E>(&self, e: E, v: visit::vt<E>) {
+        match *self {
+            ii_item(i) => (v.visit_item)(i, e, v),
+            ii_foreign(i) => (v.visit_foreign_item)(i, e, v),
+            ii_method(_, m) => visit::visit_method_helper(m, e, v),
+            ii_dtor(ref dtor, _, tps, parent_id) => {
               visit::visit_struct_dtor_helper((*dtor), tps, parent_id, e, v);
-          }
+            }
         }
     }
 }
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index dd6a996b730..ca28641c4a3 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -13,7 +13,7 @@
 use core::prelude::*;
 
 use ast;
-use ast_util::{spanned, dummy_spanned};
+use codemap::{spanned, dummy_spanned};
 use attr;
 use codemap::BytePos;
 use diagnostic::span_handler;
@@ -24,8 +24,8 @@ use core::either::Either;
 use core::either;
 use core::option;
 use core::vec;
-use std::map::HashMap;
-use std::map;
+use std::oldmap::HashMap;
+use std::oldmap;
 use std;
 
 /* Constructors */
@@ -199,7 +199,7 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool {
             // FIXME (#607): Needs implementing
             // This involves probably sorting the list by name and
             // meta_item variant
-            fail ~"unimplemented meta_item variant"
+            die!(~"unimplemented meta_item variant")
           }
         }
 }
@@ -269,9 +269,9 @@ pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] {
     }
 
     // This is sort of stupid here, converting to a vec of mutables and back
-    let v: ~[mut @ast::meta_item] = vec::cast_to_mut(items);
+    let mut v: ~[@ast::meta_item] = items;
     std::sort::quick_sort(v, lteq);
-    vec::cast_from_mut(move v)
+    move v
 }
 
 pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) ->
@@ -358,12 +358,12 @@ pub fn find_inline_attr(attrs: &[ast::attribute]) -> inline_attr {
 
 pub fn require_unique_names(diagnostic: span_handler,
                             metas: &[@ast::meta_item]) {
-    let map = map::HashMap();
+    let map = oldmap::HashMap();
     for metas.each |meta| {
         let name = get_meta_item_name(*meta);
 
         // FIXME: How do I silence the warnings? --pcw (#2619)
-        if map.contains_key(name) {
+        if map.contains_key_ref(&name) {
             diagnostic.span_fatal(meta.span,
                                   fmt!("duplicate meta item `%s`", name));
         }
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 980d4a236e0..31ed65d8065 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -23,8 +23,6 @@ source code snippets, etc.
 
 use core::prelude::*;
 
-use ast_util;
-
 use core::cmp;
 use core::dvec::DVec;
 use core::str;
@@ -130,6 +128,10 @@ pub struct span {
     expn_info: Option<@ExpnInfo>
 }
 
+#[auto_encode]
+#[auto_decode]
+pub struct spanned<T> { node: T, span: span }
+
 pub impl span : cmp::Eq {
     pure fn eq(&self, other: &span) -> bool {
         return (*self).lo == (*other).lo && (*self).hi == (*other).hi;
@@ -144,10 +146,32 @@ pub impl<S: Encoder> span: Encodable<S> {
 
 pub impl<D: Decoder> span: Decodable<D> {
     static fn decode(_d: &D) -> span {
-        ast_util::dummy_sp()
+        dummy_sp()
     }
 }
 
+pub pure fn spanned<T>(+lo: BytePos, +hi: BytePos, +t: T) -> spanned<T> {
+    respan(mk_sp(lo, hi), move t)
+}
+
+pub pure fn respan<T>(sp: span, +t: T) -> spanned<T> {
+    spanned {node: t, span: sp}
+}
+
+pub pure fn dummy_spanned<T>(+t: T) -> spanned<T> {
+    respan(dummy_sp(), move t)
+}
+
+/* assuming that we're not in macro expansion */
+pub pure fn mk_sp(+lo: BytePos, +hi: BytePos) -> span {
+    span {lo: lo, hi: hi, expn_info: None}
+}
+
+// make this a const, once the compiler supports it
+pub pure fn dummy_sp() -> span { return mk_sp(BytePos(0), BytePos(0)); }
+
+
+
 /// A source code location used for error reporting
 pub struct Loc {
     /// Information about the original source
@@ -158,6 +182,20 @@ pub struct Loc {
     col: CharPos
 }
 
+/// A source code location used as the result of lookup_char_pos_adj
+// Actually, *none* of the clients use the filename *or* file field;
+// perhaps they should just be removed.
+pub struct LocWithOpt {
+    filename: ~str,
+    line: uint,
+    col: CharPos,
+    file: Option<@FileMap>,
+}
+
+// used to be structural records. Better names, anyone?
+pub struct FileMapAndLine {fm: @FileMap, line: uint}
+pub struct FileMapAndBytePos {fm: @FileMap, pos: BytePos}
+
 /// Extra information for tracking macro expansion of spans
 pub enum ExpnInfo {
     ExpandedFrom({call_site: span,
@@ -204,10 +242,19 @@ pub struct FileMap {
 }
 
 pub impl FileMap {
+    // EFFECT: register a start-of-line offset in the
+    // table of line-beginnings.
+    // UNCHECKED INVARIANT: these offsets must be added in the right
+    // order and must be in the right places; there is shared knowledge
+    // about what ends a line between this file and parse.rs
     fn next_line(&self, +pos: BytePos) {
+        // the new charpos must be > the last one (or it's the first one).
+        assert ((self.lines.len() == 0)
+                || (self.lines[self.lines.len() - 1] < pos));
         self.lines.push(pos);
     }
 
+    // get a line from the list of pre-computed line-beginnings
     pub fn get_line(&self, line: int) -> ~str {
         unsafe {
             let begin: BytePos = self.lines[line] - self.start_pos;
@@ -279,27 +326,25 @@ pub impl CodeMap {
         return self.lookup_pos(pos);
     }
 
-    pub fn lookup_char_pos_adj(&self, +pos: BytePos)
-        -> {filename: ~str, line: uint, col: CharPos, file: Option<@FileMap>}
+    pub fn lookup_char_pos_adj(&self, +pos: BytePos) -> LocWithOpt
     {
         let loc = self.lookup_char_pos(pos);
         match (loc.file.substr) {
-            FssNone => {
-                {filename: /* FIXME (#2543) */ copy loc.file.name,
-                 line: loc.line,
-                 col: loc.col,
-                 file: Some(loc.file)}
-            }
-            FssInternal(sp) => {
-                self.lookup_char_pos_adj(
-                    sp.lo + (pos - loc.file.start_pos))
-            }
-            FssExternal(ref eloc) => {
-                {filename: /* FIXME (#2543) */ copy (*eloc).filename,
-                 line: (*eloc).line + loc.line - 1u,
-                 col: if loc.line == 1 {eloc.col + loc.col} else {loc.col},
-                 file: None}
-            }
+            FssNone =>
+            LocWithOpt {
+                filename: /* FIXME (#2543) */ copy loc.file.name,
+                line: loc.line,
+                col: loc.col,
+                file: Some(loc.file)},
+            FssInternal(sp) =>
+            self.lookup_char_pos_adj(
+                sp.lo + (pos - loc.file.start_pos)),
+            FssExternal(ref eloc) =>
+            LocWithOpt {
+                filename: /* FIXME (#2543) */ copy (*eloc).filename,
+                line: (*eloc).line + loc.line - 1u,
+                col: if loc.line == 1 {eloc.col + loc.col} else {loc.col},
+                file: None}
         }
     }
 
@@ -319,7 +364,7 @@ pub impl CodeMap {
     }
 
     pub fn span_to_str(&self, sp: span) -> ~str {
-        if self.files.len() == 0 && sp == ast_util::dummy_sp() {
+        if self.files.len() == 0 && sp == dummy_sp() {
             return ~"no-location";
         }
 
@@ -356,7 +401,7 @@ pub impl CodeMap {
         for self.files.each |fm| { if fm.name == filename { return *fm; } }
         //XXjdm the following triggers a mismatched type bug
         //      (or expected function, found _|_)
-        fail; // ("asking for " + filename + " which we don't know about");
+        die!(); // ("asking for " + filename + " which we don't know about");
     }
 
 }
@@ -376,15 +421,14 @@ priv impl CodeMap {
             }
         }
         if (a >= len) {
-            fail fmt!("position %u does not resolve to a source location",
-                      pos.to_uint())
+            die!(fmt!("position %u does not resolve to a source location",
+                      pos.to_uint()))
         }
 
         return a;
     }
 
-    fn lookup_line(&self, +pos: BytePos)
-        -> {fm: @FileMap, line: uint}
+    fn lookup_line(&self, pos: BytePos) -> FileMapAndLine
     {
         let idx = self.lookup_filemap_idx(pos);
         let f = self.files[idx];
@@ -394,11 +438,11 @@ priv impl CodeMap {
             let m = (a + b) / 2u;
             if f.lines[m] > pos { b = m; } else { a = m; }
         }
-        return {fm: f, line: a};
+        return FileMapAndLine {fm: f, line: a};
     }
 
     fn lookup_pos(&self, +pos: BytePos) -> Loc {
-        let {fm: f, line: a} = self.lookup_line(pos);
+        let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
         let line = a + 1u; // Line numbers start at 1
         let chpos = self.bytepos_to_local_charpos(pos);
         let linebpos = f.lines[a];
@@ -424,11 +468,11 @@ priv impl CodeMap {
     }
 
     fn lookup_byte_offset(&self, +bpos: BytePos)
-        -> {fm: @FileMap, pos: BytePos} {
+        -> FileMapAndBytePos {
         let idx = self.lookup_filemap_idx(bpos);
         let fm = self.files[idx];
         let offset = bpos - fm.start_pos;
-        return {fm: fm, pos: offset};
+        return FileMapAndBytePos {fm: fm, pos: offset};
     }
 
     // Converts an absolute BytePos to a CharPos relative to the file it is
@@ -458,6 +502,36 @@ priv impl CodeMap {
     }
 }
 
+#[cfg(test)]
+mod test {
+    use super::*;
+    use util::testing::check_equal;
+
+    #[test]
+    fn t1 () {
+        let cm = CodeMap::new();
+        let fm = cm.new_filemap(~"blork.rs",@~"first line.\nsecond line");
+        fm.next_line(BytePos(0));
+        check_equal(&fm.get_line(0),&~"first line.");
+        // TESTING BROKEN BEHAVIOR:
+        fm.next_line(BytePos(10));
+        check_equal(&fm.get_line(1),&~".");
+    }
+
+    #[test]
+    #[should_fail]
+    fn t2 () {
+        let cm = CodeMap::new();
+        let fm = cm.new_filemap(~"blork.rs",@~"first line.\nsecond line");
+        // TESTING *REALLY* BROKEN BEHAVIOR:
+        fm.next_line(BytePos(0));
+        fm.next_line(BytePos(10));
+        fm.next_line(BytePos(2));
+    }
+}
+
+
+
 //
 // Local Variables:
 // mode: rust
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index d2f6b7956ef..c454f5dde2b 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -63,7 +63,7 @@ struct codemap_t {
 impl codemap_t: span_handler {
     fn span_fatal(sp: span, msg: &str) -> ! {
         self.handler.emit(Some((self.cm, sp)), msg, fatal);
-        fail;
+        die!();
     }
     fn span_err(sp: span, msg: &str) {
         self.handler.emit(Some((self.cm, sp)), msg, error);
@@ -89,7 +89,7 @@ impl codemap_t: span_handler {
 impl handler_t: handler {
     fn fatal(msg: &str) -> ! {
         (self.emit)(None, msg, fatal);
-        fail;
+        die!();
     }
     fn err(msg: &str) {
         (self.emit)(None, msg, error);
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index a2484e2d6df..03aa0cde811 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -98,8 +98,8 @@ use ext::base::*;
 use parse;
 
 use core::vec;
-use std::map;
-use std::map::HashMap;
+use std::oldmap;
+use std::oldmap::HashMap;
 
 // Transitional reexports so qquote can find the paths it is looking for
 mod syntax {
@@ -311,7 +311,7 @@ priv impl ext_ctxt {
     }
 
     fn stmt(expr: @ast::expr) -> @ast::stmt {
-        @ast::spanned { node: ast::stmt_semi(expr, self.next_id()),
+        @codemap::spanned { node: ast::stmt_semi(expr, self.next_id()),
                        span: expr.span }
     }
 
@@ -322,7 +322,7 @@ priv impl ext_ctxt {
                 self.expr(
                     span,
                     ast::expr_lit(
-                        @ast::spanned { node: ast::lit_str(s),
+                        @codemap::spanned { node: ast::lit_str(s),
                                         span: span})),
                 ast::expr_vstore_uniq))
     }
@@ -331,7 +331,7 @@ priv impl ext_ctxt {
         self.expr(
             span,
             ast::expr_lit(
-                @ast::spanned { node: ast::lit_uint(i as u64, ast::ty_u),
+                @codemap::spanned { node: ast::lit_uint(i as u64, ast::ty_u),
                                 span: span}))
     }
 
@@ -342,7 +342,7 @@ priv impl ext_ctxt {
     }
 
     fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk {
-        ast::spanned {
+        codemap::spanned {
             node: ast::blk_ {
                 view_items: ~[],
                 stmts: stmts,
@@ -355,7 +355,7 @@ priv impl ext_ctxt {
     }
 
     fn expr_blk(expr: @ast::expr) -> ast::blk {
-        ast::spanned {
+        codemap::spanned {
             node: ast::blk_ {
                 view_items: ~[],
                 stmts: ~[],
@@ -593,7 +593,7 @@ fn mk_ser_method(
         ident: cx.ident_of(~"encode"),
         attrs: ~[],
         tps: ~[],
-        self_ty: ast::spanned { node: ast::sty_region(ast::m_imm),
+        self_ty: codemap::spanned { node: ast::sty_region(ast::m_imm),
                                 span: span },
         purity: ast::impure_fn,
         decl: ser_decl,
@@ -651,7 +651,7 @@ fn mk_deser_method(
         ident: cx.ident_of(~"decode"),
         attrs: ~[],
         tps: ~[],
-        self_ty: ast::spanned { node: ast::sty_static, span: span },
+        self_ty: codemap::spanned { node: ast::sty_static, span: span },
         purity: ast::impure_fn,
         decl: deser_decl,
         body: deser_body,
@@ -762,7 +762,7 @@ fn mk_struct_deser_impl(
             ]
         );
 
-        ast::spanned {
+        codemap::spanned {
             node: ast::field_ {
                 mutbl: field.mutbl,
                 ident: field.ident,
@@ -812,8 +812,8 @@ fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] {
     do fields.map |field| {
         let (ident, mutbl) = match field.node.kind {
             ast::named_field(ident, mutbl, _) => (ident, mutbl),
-            _ => fail ~"[auto_encode] does not support \
-                        unnamed fields",
+            _ => die!(~"[auto_encode] does not support \
+                        unnamed fields")
         };
 
         field {
@@ -954,9 +954,9 @@ fn mk_enum_ser_body(
             ast::tuple_variant_kind(args) =>
                 ser_variant(cx, span, variant.node.name, v_idx, args),
             ast::struct_variant_kind(*) =>
-                fail ~"struct variants unimplemented",
+                die!(~"struct variants unimplemented"),
             ast::enum_variant_kind(*) =>
-                fail ~"enum variants unimplemented",
+                die!(~"enum variants unimplemented"),
         }
     };
 
@@ -1025,7 +1025,7 @@ fn mk_enum_deser_variant_nary(
 }
 
 fn mk_enum_deser_body(
-    cx: ext_ctxt,
+    ext_cx: ext_ctxt,
     span: span,
     name: ast::ident,
     variants: ~[ast::variant]
@@ -1035,11 +1035,11 @@ fn mk_enum_deser_body(
             ast::tuple_variant_kind(args) => {
                 if args.is_empty() {
                     // for a nullary variant v, do "v"
-                    cx.expr_path(span, ~[variant.node.name])
+                    ext_cx.expr_path(span, ~[variant.node.name])
                 } else {
                     // for an n-ary variant v, do "v(a_1, ..., a_n)"
                     mk_enum_deser_variant_nary(
-                        cx,
+                        ext_cx,
                         span,
                         variant.node.name,
                         args
@@ -1047,100 +1047,105 @@ fn mk_enum_deser_body(
                 }
             },
             ast::struct_variant_kind(*) =>
-                fail ~"struct variants unimplemented",
+                die!(~"struct variants unimplemented"),
             ast::enum_variant_kind(*) =>
-                fail ~"enum variants unimplemented",
+                die!(~"enum variants unimplemented")
         };
 
         let pat = @ast::pat {
-            id: cx.next_id(),
-            node: ast::pat_lit(cx.lit_uint(span, v_idx)),
+            id: ext_cx.next_id(),
+            node: ast::pat_lit(ext_cx.lit_uint(span, v_idx)),
             span: span,
         };
 
         ast::arm {
             pats: ~[pat],
             guard: None,
-            body: cx.expr_blk(body),
+            body: ext_cx.expr_blk(body),
         }
     };
 
+    let quoted_expr = quote_expr!(
+      ::core::sys::begin_unwind(~"explicit failure", ~"empty", 1);
+    ).node;
+
     let impossible_case = ast::arm {
         pats: ~[@ast::pat {
-            id: cx.next_id(),
+            id: ext_cx.next_id(),
             node: ast::pat_wild,
             span: span,
         }],
         guard: None,
 
         // FIXME(#3198): proper error message
-        body: cx.expr_blk(cx.expr(span, ast::expr_fail(None))),
+        body: ext_cx.expr_blk(ext_cx.expr(span, quoted_expr)),
     };
 
     arms.push(impossible_case);
 
     // ast for `|i| { match i { $(arms) } }`
-    let expr_lambda = cx.expr(
+    let expr_lambda = ext_cx.expr(
         span,
         ast::expr_fn_block(
             ast::fn_decl {
                 inputs: ~[ast::arg {
-                    mode: ast::infer(cx.next_id()),
+                    mode: ast::infer(ext_cx.next_id()),
                     is_mutbl: false,
                     ty: @ast::Ty {
-                        id: cx.next_id(),
+                        id: ext_cx.next_id(),
                         node: ast::ty_infer,
                         span: span
                     },
                     pat: @ast::pat {
-                        id: cx.next_id(),
+                        id: ext_cx.next_id(),
                         node: ast::pat_ident(
                             ast::bind_by_copy,
-                            ast_util::ident_to_path(span, cx.ident_of(~"i")),
+                            ast_util::ident_to_path(span,
+                                ext_cx.ident_of(~"i")),
                             None),
                         span: span,
                     },
-                    id: cx.next_id(),
+                    id: ext_cx.next_id(),
                 }],
                 output: @ast::Ty {
-                    id: cx.next_id(),
+                    id: ext_cx.next_id(),
                     node: ast::ty_infer,
                     span: span,
                 },
                 cf: ast::return_val,
             },
-            cx.expr_blk(
-                cx.expr(
+            ext_cx.expr_blk(
+                ext_cx.expr(
                     span,
-                    ast::expr_match(cx.expr_var(span, ~"i"), arms)
+                    ast::expr_match(ext_cx.expr_var(span, ~"i"), arms)
                 )
             )
         )
     );
 
     // ast for `__d.read_enum_variant($(expr_lambda))`
-    let expr_lambda = cx.lambda_expr(
-        cx.expr_call(
+    let expr_lambda = ext_cx.lambda_expr(
+        ext_cx.expr_call(
             span,
-            cx.expr_field(
+            ext_cx.expr_field(
                 span,
-                cx.expr_var(span, ~"__d"),
-                cx.ident_of(~"read_enum_variant")
+                ext_cx.expr_var(span, ~"__d"),
+                ext_cx.ident_of(~"read_enum_variant")
             ),
             ~[expr_lambda]
         )
     );
 
     // ast for `__d.read_enum($(e_name), $(expr_lambda))`
-    cx.expr_call(
+    ext_cx.expr_call(
         span,
-        cx.expr_field(
+        ext_cx.expr_field(
             span,
-            cx.expr_var(span, ~"__d"),
-            cx.ident_of(~"read_enum")
+            ext_cx.expr_var(span, ~"__d"),
+            ext_cx.ident_of(~"read_enum")
         ),
         ~[
-            cx.lit_str(span, @cx.str_of(name)),
+            ext_cx.lit_str(span, @ext_cx.str_of(name)),
             expr_lambda
         ]
     )
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index d0974e0654c..3efae955965 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -11,9 +11,8 @@
 use core::prelude::*;
 
 use ast;
-use ast_util::dummy_sp;
 use codemap;
-use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom};
+use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom, dummy_sp};
 use diagnostic::span_handler;
 use ext;
 use parse;
@@ -21,7 +20,7 @@ use parse::{parser, token};
 
 use core::io;
 use core::vec;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 // new-style macro! tt code:
 //
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 6d44a412742..4d8fd39c960 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -32,7 +32,7 @@ pub fn mk_expr(cx: ext_ctxt,
 }
 
 pub fn mk_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
-    let sp_lit = @ast::spanned { node: lit, span: sp };
+    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 {
@@ -149,7 +149,7 @@ pub fn mk_uniq_str(cx: ext_ctxt, sp: span, s: ~str) -> @ast::expr {
 }
 pub fn mk_field(sp: span, f: &{ident: ast::ident, ex: @ast::expr})
              -> ast::field {
-    ast::spanned {
+    codemap::spanned {
         node: ast::field_ { mutbl: ast::m_imm, ident: f.ident, expr: f.ex },
         span: sp,
     }
@@ -188,7 +188,7 @@ pub fn mk_global_struct_e(cx: ext_ctxt,
 pub fn mk_glob_use(cx: ext_ctxt,
                    sp: span,
                    path: ~[ast::ident]) -> @ast::view_item {
-    let glob = @ast::spanned {
+    let glob = @codemap::spanned {
         node: ast::view_path_glob(mk_raw_path(sp, path), cx.next_id()),
         span: sp,
     };
@@ -209,7 +209,7 @@ pub fn mk_local(cx: ext_ctxt, sp: span, mutbl: bool,
         span: sp,
     };
     let ty = @ast::Ty { id: cx.next_id(), node: ast::ty_infer, span: sp };
-    let local = @ast::spanned {
+    let local = @codemap::spanned {
         node: ast::local_ {
             is_mutbl: mutbl,
             ty: ty,
@@ -219,14 +219,14 @@ pub fn mk_local(cx: ext_ctxt, sp: span, mutbl: bool,
         },
         span: sp,
     };
-    let decl = ast::spanned {node: ast::decl_local(~[local]), span: sp};
-    @ast::spanned { node: ast::stmt_decl(@decl, 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 = ast::spanned {
+    let blk = codemap::spanned {
         node: ast::blk_ {
              view_items: view_items,
              stmts: stmts,
@@ -242,7 +242,7 @@ pub fn mk_block_(cx: ext_ctxt,
                  span: span,
                  +stmts: ~[@ast::stmt])
               -> ast::blk {
-    ast::spanned {
+    codemap::spanned {
         node: ast::blk_ {
             view_items: ~[],
             stmts: stmts,
@@ -257,7 +257,7 @@ pub fn mk_simple_block(cx: ext_ctxt,
                        span: span,
                        expr: @ast::expr)
                     -> ast::blk {
-    ast::spanned {
+    codemap::spanned {
         node: ast::blk_ {
             view_items: ~[],
             stmts: ~[],
@@ -307,13 +307,14 @@ pub fn mk_pat_struct(cx: ext_ctxt,
     mk_pat(cx, span, move pat)
 }
 pub fn mk_bool(cx: ext_ctxt, span: span, value: bool) -> @ast::expr {
-    let lit_expr = ast::expr_lit(@ast::spanned { node: ast::lit_bool(value),
-                                                 span: span });
+    let lit_expr = ast::expr_lit(@codemap::spanned {
+        node: ast::lit_bool(value),
+        span: span });
     build::mk_expr(cx, span, move 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());
-    @ast::spanned { node: move stmt_, span: span }
+    @codemap::spanned { node: move stmt_, span: span }
 }
 pub fn mk_ty_path(cx: ext_ctxt,
                   span: span,
diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs
index d542b104e54..8e87357f8b5 100644
--- a/src/libsyntax/ext/deriving.rs
+++ b/src/libsyntax/ext/deriving.rs
@@ -18,12 +18,12 @@ use ast::{TraitTyParamBound, Ty, and, bind_by_ref, binop, deref, enum_def};
 use ast::{enum_variant_kind, expr, expr_match, ident, item, item_};
 use ast::{item_enum, item_impl, item_struct, m_imm, meta_item, method};
 use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
-use ast::{re_anon, spanned, stmt, struct_def, struct_variant_kind};
+use ast::{re_anon, stmt, struct_def, struct_variant_kind};
 use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, ty_param};
 use ast::{ty_param_bound, ty_path, ty_rptr, unnamed_field, variant};
 use ext::base::ext_ctxt;
 use ext::build;
-use codemap::span;
+use codemap::{span, spanned};
 use parse::token::special_idents::clownshoes_extensions;
 
 use core::dvec;
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 0ab94710f40..227a86e0766 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -20,7 +20,7 @@ use parse::{parser, parse_expr_from_source_str, new_parser_from_tts};
 
 use core::option;
 use core::vec;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 pub fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
                    e: expr_, s: span, fld: ast_fold,
@@ -154,7 +154,7 @@ pub fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>,
                        fld: ast_fold) -> Option<@ast::item> {
 
     let (pth, tts) = match it.node {
-        item_mac(ast::spanned { node: mac_invoc_tt(pth, ref tts), _}) => {
+        item_mac(codemap::spanned { node: mac_invoc_tt(pth, ref tts), _}) => {
             (pth, (*tts))
         }
         _ => cx.span_bug(it.span, ~"invalid item macro invocation")
@@ -234,7 +234,7 @@ pub fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
                 {call_site: sp, callie: {name: *extname, span: exp_sp}}));
             let expanded = match exp(cx, mac.span, tts) {
                 MRExpr(e) =>
-                    @ast::spanned { node: stmt_expr(e, cx.next_id()),
+                    @codemap::spanned { node: stmt_expr(e, cx.next_id()),
                                     span: e.span},
                 MRAny(_,_,stmt_mkr) => stmt_mkr(),
                 _ => cx.span_fatal(
@@ -296,6 +296,15 @@ pub fn core_macros() -> ~str {
         )
     )
 
+    macro_rules! fail(
+        ($msg: expr) => (
+            ::core::sys::begin_unwind($msg, file!().to_owned(), line!())
+        );
+        () => (
+            die!(~\"explicit failure\")
+        )
+    )
+
     macro_rules! fail_unless(
         ($cond:expr) => {
             if !$cond {
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 8abca3d97f9..58ab05987a6 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -17,10 +17,11 @@ use core::prelude::*;
 
 use ast::{ident, node_id};
 use ast;
-use ast_util::{ident_to_path, respan, dummy_sp};
+use ast_util::{ident_to_path};
 use ast_util;
 use attr;
-use codemap::span;
+use codemap::{span, respan, dummy_sp};
+use codemap;
 use ext::base::{ext_ctxt, mk_ctxt};
 use ext::quote::rt::*;
 
@@ -310,7 +311,7 @@ pub impl ext_ctxt: ext_ctxt_ast_builder {
         // 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_import(~[
-            @ast::spanned {
+            @codemap::spanned {
                 node: ast::view_path_simple(
                     self.ident_of(~"Owned"),
                     path(
@@ -319,19 +320,19 @@ pub impl ext_ctxt: ext_ctxt_ast_builder {
                             self.ident_of(~"kinds"),
                             self.ident_of(~"Owned")
                         ],
-                        ast_util::dummy_sp()
+                        codemap::dummy_sp()
                     ),
                     ast::type_value_ns,
                     self.next_id()
                 ),
-                span: ast_util::dummy_sp()
+                span: codemap::dummy_sp()
             }
         ]);
         let vi = @ast::view_item {
             node: vi,
             attrs: ~[],
             vis: ast::private,
-            span: ast_util::dummy_sp()
+            span: codemap::dummy_sp()
         };
 
         self.item(
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index a74214c8758..1502332859c 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -40,13 +40,13 @@ pub impl parser::Parser: proto_parser {
         self.expect(token::COLON);
         let dir = match copy self.token {
           token::IDENT(n, _) => self.interner.get(n),
-          _ => fail
+          _ => die!()
         };
         self.bump();
         let dir = match dir {
           @~"send" => send,
           @~"recv" => recv,
-          _ => fail
+          _ => die!()
         };
 
         let typarms = if self.token == token::LT {
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 7bf4f2dc1d9..da0ac4e08ab 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -11,7 +11,7 @@
 // A protocol compiler for Rust.
 
 use ast::ident;
-use ast_util::dummy_sp;
+use codemap::dummy_sp;
 use ext::base::ext_ctxt;
 use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path};
 use ext::pipes::ast_builder::{path_global};
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 5c2dd82eb7f..6a1d9357694 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -34,8 +34,8 @@ pub impl direction : cmp::Eq {
 }
 
 pub impl direction: ToStr {
-    pure fn to_str() -> ~str {
-        match self {
+    pure fn to_str(&self) -> ~str {
+        match *self {
           send => ~"Send",
           recv => ~"Recv"
         }
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 7605e01fbf0..4a9a22de50f 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -184,7 +184,7 @@ pub mod rt {
                 Some(ast) => ast,
                 None => {
                     error!("Parse error with ```\n%s\n```", s);
-                    fail
+                    die!()
                 }
             }
         }
@@ -399,7 +399,7 @@ fn mk_token(cx: ext_ctxt, sp: span, tok: token::Token) -> @ast::expr {
                                   ~[mk_ident(cx, sp, ident)]);
         }
 
-        INTERPOLATED(_) => fail ~"quote! with interpolated token",
+        INTERPOLATED(_) => die!(~"quote! with interpolated token"),
 
         _ => ()
     }
@@ -437,7 +437,7 @@ fn mk_token(cx: ext_ctxt, sp: span, tok: token::Token) -> @ast::expr {
         DOLLAR => "DOLLAR",
         UNDERSCORE => "UNDERSCORE",
         EOF => "EOF",
-        _ => fail
+        _ => die!()
     };
     build::mk_path(cx, sp,
                    ids_ext(cx, ~[name.to_owned()]))
@@ -467,7 +467,7 @@ fn mk_tt(cx: ext_ctxt, sp: span, tt: &ast::token_tree)
         }
 
         ast::tt_delim(ref tts) => mk_tts(cx, sp, *tts),
-        ast::tt_seq(*) => fail ~"tt_seq in quote!",
+        ast::tt_seq(*) => die!(~"tt_seq in quote!"),
 
         ast::tt_nonterminal(sp, ident) => {
 
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 4c0550b3c3a..9548db70b94 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -10,8 +10,7 @@
 
 // Earley-like parser for macros.
 use ast::{matcher, match_tok, match_seq, match_nonterminal, ident};
-use ast_util::mk_sp;
-use codemap::BytePos;
+use codemap::{BytePos, mk_sp};
 use codemap;
 use parse::common::*; //resolve bug?
 use parse::lexer::*; //resolve bug?
@@ -27,7 +26,7 @@ use core::option;
 use core::str;
 use core::uint;
 use core::vec;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 /* This is an Earley-like parser, without support for in-grammar nonterminals,
 only by calling out to the main rust parser for named nonterminals (which it
@@ -125,7 +124,7 @@ pub type matcher_pos = ~{
 pub fn copy_up(&& mpu: matcher_pos_up) -> matcher_pos {
     match &mpu {
       &matcher_pos_up(Some(ref mp)) => copy (*mp),
-      _ => fail
+      _ => die!()
     }
 }
 
@@ -189,16 +188,16 @@ pub fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@named_match])
     fn n_rec(p_s: parse_sess, m: matcher, res: ~[@named_match],
              ret_val: HashMap<ident, @named_match>) {
         match m {
-          ast::spanned {node: match_tok(_), _} => (),
-          ast::spanned {node: match_seq(ref more_ms, _, _, _, _), _} => {
+          codemap::spanned {node: match_tok(_), _} => (),
+          codemap::spanned {node: match_seq(ref more_ms, _, _, _, _), _} => {
             for (*more_ms).each() |next_m| {
                 n_rec(p_s, *next_m, res, ret_val)
             };
           }
-          ast::spanned {
+          codemap::spanned {
                 node: match_nonterminal(bind_name, _, idx), span: sp
           } => {
-            if ret_val.contains_key(bind_name) {
+            if ret_val.contains_key_ref(&bind_name) {
                 p_s.span_diagnostic.span_fatal(sp, ~"Duplicated bind name: "+
                                                *p_s.interner.get(bind_name))
             }
@@ -239,7 +238,7 @@ pub fn parse(sess: parse_sess,
         let mut next_eis = ~[]; // or proceed normally
         let mut eof_eis = ~[];
 
-        let {tok: tok, sp: sp} = rdr.peek();
+        let TokenAndSpan {tok: tok, sp: sp} = rdr.peek();
 
         /* we append new items to this while we go */
         while cur_eis.len() > 0u { /* for each Earley Item */
@@ -362,7 +361,7 @@ pub fn parse(sess: parse_sess,
                         fmt!("%s ('%s')", *sess.interner.get(name),
                              *sess.interner.get(bind))
                       }
-                      _ => fail
+                      _ => die!()
                     } }), ~" or ");
                 return error(sp, fmt!(
                     "Local ambiguity: multiple parsing options: \
@@ -387,7 +386,7 @@ pub fn parse(sess: parse_sess,
                         parse_nt(rust_parser, *sess.interner.get(name))));
                     ei.idx += 1u;
                   }
-                  _ => fail
+                  _ => die!()
                 }
                 cur_eis.push(move ei);
 
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index f7ef79db466..31172cbfa85 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -13,8 +13,7 @@ use core::prelude::*;
 use ast::{ident, matcher_, matcher, match_tok, match_nonterminal, match_seq};
 use ast::{tt_delim};
 use ast;
-use ast_util::dummy_sp;
-use codemap::span;
+use codemap::{span, spanned, dummy_sp};
 use ext::base::{ext_ctxt, MacResult, MRAny, MRDef, MacroDef, NormalTT};
 use ext::base;
 use ext::tt::macro_parser::{error};
@@ -27,13 +26,13 @@ use parse::token::{FAT_ARROW, SEMI, LBRACE, RBRACE, nt_matchers, nt_tt};
 use print;
 
 use core::io;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 pub fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
                          arg: ~[ast::token_tree]) -> base::MacResult {
     // these spans won't matter, anyways
     fn ms(m: matcher_) -> matcher {
-        ast::spanned { node: m, span: dummy_sp() }
+        spanned { node: m, span: dummy_sp() }
     }
 
     let lhs_nm =  cx.parse_sess().interner.gensym(@~"lhs");
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index b3b1e04976a..6bf90617a6e 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -13,15 +13,16 @@ use core::prelude::*;
 use ast;
 use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
 use ast_util;
-use codemap::span;
+use codemap::{span, dummy_sp};
 use diagnostic::span_handler;
 use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
 use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
+use parse::lexer::TokenAndSpan;
 
 use core::option;
 use core::vec;
 use std;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 enum tt_frame_up { /* to break a circularity */
     tt_frame_up(Option<tt_frame>)
@@ -43,7 +44,7 @@ pub type tt_reader = @{
     interner: @ident_interner,
     mut cur: tt_frame,
     /* for MBE-style macro transcription */
-    interpolations: std::map::HashMap<ident, @named_match>,
+    interpolations: std::oldmap::HashMap<ident, @named_match>,
     mut repeat_idx: ~[uint],
     mut repeat_len: ~[uint],
     /* cached: */
@@ -55,21 +56,21 @@ pub type tt_reader = @{
  *  `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
  *  should) be none. */
 pub fn new_tt_reader(sp_diag: span_handler, itr: @ident_interner,
-                     interp: Option<std::map::HashMap<ident,@named_match>>,
+                     interp: Option<std::oldmap::HashMap<ident,@named_match>>,
                      src: ~[ast::token_tree])
                   -> tt_reader {
     let r = @{sp_diag: sp_diag, interner: itr,
               mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false,
                          sep: None, up: tt_frame_up(option::None)},
               interpolations: match interp { /* just a convienience */
-                None => std::map::HashMap(),
+                None => std::oldmap::HashMap(),
                 Some(x) => x
               },
               mut repeat_idx: ~[],
               mut repeat_len: ~[],
               /* dummy values, never read: */
               mut cur_tok: EOF,
-              mut cur_span: ast_util::dummy_sp()
+              mut cur_span: dummy_sp()
              };
     tt_next_token(r); /* get cur_tok and cur_span set up */
     return r;
@@ -149,8 +150,8 @@ fn lockstep_iter_size(t: token_tree, r: tt_reader) -> lis {
 }
 
 
-pub fn tt_next_token(&&r: tt_reader) -> {tok: Token, sp: span} {
-    let ret_val = { tok: r.cur_tok, sp: r.cur_span };
+pub fn tt_next_token(&&r: tt_reader) -> TokenAndSpan {
+    let ret_val = TokenAndSpan { tok: r.cur_tok, sp: r.cur_span };
     while r.cur.idx >= r.cur.readme.len() {
         /* done with this set; pop or repeat? */
         if ! r.cur.dotdotdoted
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 5c80a6664de..cfa8a3c1153 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -495,7 +495,6 @@ pub fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
             expr_index(fld.fold_expr(el), fld.fold_expr(er))
           }
           expr_path(pth) => expr_path(fld.fold_path(pth)),
-          expr_fail(e) => expr_fail(option::map(&e, |x| fld.fold_expr(*x))),
           expr_break(opt_ident) =>
             expr_break(option::map(&opt_ident, |x| fld.fold_ident(*x))),
           expr_again(opt_ident) =>
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 3ed31c0953c..e6ba543cf79 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -11,7 +11,7 @@
 use core::prelude::*;
 
 use ast;
-use ast_util::spanned;
+use codemap::spanned;
 use codemap::BytePos;
 use parse::common::*; //resolve bug?
 use parse::token;
diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs
index afe6823e76d..4ceb04c55d0 100644
--- a/src/libsyntax/parse/classify.rs
+++ b/src/libsyntax/parse/classify.rs
@@ -13,6 +13,7 @@
  */
 
 use ast;
+use codemap;
 use ast_util::operator_prec;
 
 pub fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
@@ -31,7 +32,8 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
 pub fn expr_is_simple_block(e: @ast::expr) -> bool {
     match e.node {
         ast::expr_block(
-            ast::spanned { node: ast::blk_ { rules: ast::default_blk, _ }, _ }
+            codemap::spanned {
+                node: ast::blk_ { rules: ast::default_blk, _ }, _ }
         ) => true,
       _ => false
     }
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 26de85548e1..d7640ce3a23 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -14,7 +14,7 @@ use ast;
 use codemap::{BytePos, CharPos, CodeMap, FileMap, Pos};
 use diagnostic;
 use parse::lexer::{is_whitespace, get_str_from, reader};
-use parse::lexer::{string_reader, bump, is_eof, nextch};
+use parse::lexer::{string_reader, bump, is_eof, nextch, TokenAndSpan};
 use parse::lexer;
 use parse::token;
 use parse;
@@ -117,7 +117,7 @@ pub fn strip_doc_comment_decoration(comment: ~str) -> ~str {
         return str::connect(lines, ~"\n");
     }
 
-    fail ~"not a doc-comment: " + comment;
+    die!(~"not a doc-comment: " + comment);
 }
 
 fn read_to_eol(rdr: string_reader) -> ~str {
@@ -295,7 +295,7 @@ fn consume_comment(rdr: string_reader, code_to_the_left: bool,
         read_block_comment(rdr, code_to_the_left, comments);
     } else if rdr.curr == '#' && nextch(rdr) == '!' {
         read_shebang_comment(rdr, code_to_the_left, comments);
-    } else { fail; }
+    } else { die!(); }
     debug!("<<< consume comment");
 }
 
@@ -334,7 +334,7 @@ pub fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
         let bstart = rdr.pos;
         rdr.next_token();
         //discard, and look ahead; we're working with internal state
-        let {tok: tok, sp: sp} = rdr.peek();
+        let TokenAndSpan {tok: tok, sp: sp} = rdr.peek();
         if token::is_lit(tok) {
             let s = get_str_from(rdr, bstart);
             literals.push({lit: s, pos: sp.lo});
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
index 583ad982000..d82a5a18039 100644
--- a/src/libsyntax/parse/common.rs
+++ b/src/libsyntax/parse/common.rs
@@ -11,15 +11,14 @@
 use core::prelude::*;
 
 use ast;
-use ast_util::spanned;
-use codemap::BytePos;
+use codemap::{BytePos, spanned};
 use parse::lexer::reader;
 use parse::parser::Parser;
 use parse::token;
 
 use core::option::{None, Option, Some};
 use core::option;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 pub type seq_sep = {
     sep: Option<token::Token>,
@@ -190,7 +189,9 @@ pub impl Parser {
         if self.token == token::GT {
             self.bump();
         } else if self.token == token::BINOP(token::SHR) {
-            self.swap(token::GT, self.span.lo + BytePos(1u), self.span.hi);
+            self.replace_token(token::GT,
+                               self.span.lo + BytePos(1u),
+                               self.span.hi);
         } else {
             let mut s: ~str = ~"expected `";
             s += token_to_str(self.reader, token::GT);
@@ -229,7 +230,7 @@ pub impl Parser {
     }
 
     fn parse_seq_lt_gt<T: Copy>(sep: Option<token::Token>,
-                                f: fn(Parser) -> T) -> ast::spanned<~[T]> {
+                                f: fn(Parser) -> T) -> spanned<~[T]> {
         let lo = self.span.lo;
         self.expect(token::LT);
         let result = self.parse_seq_to_before_gt::<T>(sep, f);
@@ -277,7 +278,7 @@ pub impl Parser {
     // NB: Do not use this function unless you actually plan to place the
     // spanned list in the AST.
     fn parse_seq<T: Copy>(bra: token::Token, ket: token::Token, sep: seq_sep,
-                          f: fn(Parser) -> T) -> ast::spanned<~[T]> {
+                          f: fn(Parser) -> T) -> spanned<~[T]> {
         let lo = self.span.lo;
         self.expect(bra);
         let result = self.parse_seq_to_before_end::<T>(ket, sep, f);
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index caab03afb76..5decb2351e3 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -10,8 +10,7 @@
 
 use parser::Parser;
 use attr::parser_attr;
-use ast_util::mk_sp;
-use codemap::span;
+use codemap::{span, mk_sp};
 
 type ctx =
     @{sess: parse::parse_sess,
@@ -75,7 +74,7 @@ fn parse_companion_mod(cx: ctx, prefix: &Path, suffix: &Option<Path>)
         // XXX: Using a dummy span, but this code will go away soon
         let p0 = new_sub_parser_from_file(cx.sess, cx.cfg,
                                           modpath,
-                                          ast_util::dummy_sp());
+                                          codemap::dummy_sp());
         let inner_attrs = p0.parse_inner_attrs_and_next();
         let m0 = p0.parse_mod_items(token::EOF, inner_attrs.next);
         return (m0.view_items, m0.items, inner_attrs.inner);
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index c3b94182cc2..381183e736c 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -30,14 +30,17 @@ use std;
 
 pub trait reader {
     fn is_eof() -> bool;
-    fn next_token() -> {tok: token::Token, sp: span};
+    fn next_token() -> TokenAndSpan;
     fn fatal(~str) -> !;
     fn span_diag() -> span_handler;
     pure fn interner() -> @token::ident_interner;
-    fn peek() -> {tok: token::Token, sp: span};
+    fn peek() -> TokenAndSpan;
     fn dup() -> reader;
 }
 
+#[deriving_eq]
+pub struct TokenAndSpan {tok: token::Token, sp: span}
+
 pub type string_reader = @{
     span_diagnostic: span_handler,
     src: @~str,
@@ -79,11 +82,14 @@ pub fn new_low_level_string_reader(span_diagnostic: span_handler,
               filemap: filemap, interner: itr,
               /* dummy values; not read */
               mut peek_tok: token::EOF,
-              mut peek_span: ast_util::dummy_sp()};
+              mut peek_span: codemap::dummy_sp()};
     bump(r);
     return r;
 }
 
+// duplicating the string reader is probably a bad idea, in
+// that using them will cause interleaved pushes of line
+// offsets to the underlying filemap...
 fn dup_string_reader(&&r: string_reader) -> string_reader {
     @{span_diagnostic: r.span_diagnostic, src: r.src,
       mut pos: r.pos,
@@ -95,8 +101,9 @@ fn dup_string_reader(&&r: string_reader) -> string_reader {
 
 impl string_reader: reader {
     fn is_eof() -> bool { is_eof(self) }
-    fn next_token() -> {tok: token::Token, sp: span} {
-        let ret_val = {tok: self.peek_tok, sp: self.peek_span};
+    // return the next token. EFFECT: advances the string_reader.
+    fn next_token() -> TokenAndSpan {
+        let ret_val = TokenAndSpan {tok: self.peek_tok, sp: self.peek_span};
         string_advance_token(self);
         return ret_val;
     }
@@ -105,15 +112,15 @@ impl string_reader: reader {
     }
     fn span_diag() -> span_handler { self.span_diagnostic }
     pure fn interner() -> @token::ident_interner { self.interner }
-    fn peek() -> {tok: token::Token, sp: span} {
-        {tok: self.peek_tok, sp: self.peek_span}
+    fn peek() -> TokenAndSpan {
+        TokenAndSpan {tok: self.peek_tok, sp: self.peek_span}
     }
     fn dup() -> reader { dup_string_reader(self) as reader }
 }
 
 pub impl tt_reader: reader {
     fn is_eof() -> bool { self.cur_tok == token::EOF }
-    fn next_token() -> {tok: token::Token, sp: span} {
+    fn next_token() -> TokenAndSpan {
         /* weird resolve bug: if the following `if`, or any of its
         statements are removed, we get resolution errors */
         if false {
@@ -127,27 +134,29 @@ pub impl tt_reader: reader {
     }
     fn span_diag() -> span_handler { self.sp_diag }
     pure fn interner() -> @token::ident_interner { self.interner }
-    fn peek() -> {tok: token::Token, sp: span} {
-        { tok: self.cur_tok, sp: self.cur_span }
+    fn peek() -> TokenAndSpan {
+        TokenAndSpan { tok: self.cur_tok, sp: self.cur_span }
     }
     fn dup() -> reader { dup_tt_reader(self) as reader }
 }
 
+// EFFECT: advance peek_tok and peek_span to refer to the next token.
 fn string_advance_token(&&r: string_reader) {
-    for consume_whitespace_and_comments(r).each |comment| {
-        r.peek_tok = comment.tok;
-        r.peek_span = comment.sp;
-        return;
+    match (consume_whitespace_and_comments(r)) {
+        Some(comment) => {
+            r.peek_tok = comment.tok;
+            r.peek_span = comment.sp;
+        },
+        None => {
+            if is_eof(r) {
+                r.peek_tok = token::EOF;
+            } else {
+                let start_bytepos = r.last_pos;
+                r.peek_tok = next_token_inner(r);
+                r.peek_span = codemap::mk_sp(start_bytepos, r.last_pos);
+            };
+        }
     }
-
-    if is_eof(r) {
-        r.peek_tok = token::EOF;
-    } else {
-        let start_bytepos = r.last_pos;
-        r.peek_tok = next_token_inner(r);
-        r.peek_span = ast_util::mk_sp(start_bytepos, r.last_pos);
-    };
-
 }
 
 fn byte_offset(rdr: string_reader) -> BytePos {
@@ -163,6 +172,8 @@ pub fn get_str_from(rdr: string_reader, start: BytePos) -> ~str {
     }
 }
 
+// EFFECT: advance the StringReader by one character. If a newline is
+// discovered, add it to the FileMap's list of line start offsets.
 pub fn bump(rdr: string_reader) {
     rdr.last_pos = rdr.pos;
     let current_byte_offset = byte_offset(rdr).to_uint();;
@@ -203,7 +214,7 @@ fn hex_digit_val(c: char) -> int {
     if in_range(c, '0', '9') { return (c as int) - ('0' as int); }
     if in_range(c, 'a', 'f') { return (c as int) - ('a' as int) + 10; }
     if in_range(c, 'A', 'F') { return (c as int) - ('A' as int) + 10; }
-    fail;
+    die!();
 }
 
 fn bin_digit_value(c: char) -> int { if c == '0' { return 0; } return 1; }
@@ -233,16 +244,19 @@ fn is_hex_digit(c: char) -> bool {
 
 fn is_bin_digit(c: char) -> bool { return c == '0' || c == '1'; }
 
-// might return a sugared-doc-attr
+// EFFECT: eats whitespace and comments.
+// returns a Some(sugared-doc-attr) if one exists, None otherwise.
 fn consume_whitespace_and_comments(rdr: string_reader)
-                                -> Option<{tok: token::Token, sp: span}> {
+    -> Option<TokenAndSpan> {
     while is_whitespace(rdr.curr) { bump(rdr); }
     return consume_any_line_comment(rdr);
 }
 
-// might return a sugared-doc-attr
+// PRECONDITION: rdr.curr is not whitespace
+// EFFECT: eats any kind of comment.
+// returns a Some(sugared-doc-attr) if one exists, None otherwise
 fn consume_any_line_comment(rdr: string_reader)
-                                -> Option<{tok: token::Token, sp: span}> {
+                                -> Option<TokenAndSpan> {
     if rdr.curr == '/' {
         match nextch(rdr) {
           '/' => {
@@ -256,9 +270,9 @@ fn consume_any_line_comment(rdr: string_reader)
                     str::push_char(&mut acc, rdr.curr);
                     bump(rdr);
                 }
-                return Some({
+                return Some(TokenAndSpan{
                     tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
-                    sp: ast_util::mk_sp(start_bpos, rdr.pos)
+                    sp: codemap::mk_sp(start_bpos, rdr.pos)
                 });
             } else {
                 while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); }
@@ -285,7 +299,7 @@ fn consume_any_line_comment(rdr: string_reader)
 
 // might return a sugared-doc-attr
 fn consume_block_comment(rdr: string_reader)
-                                -> Option<{tok: token::Token, sp: span}> {
+                                -> Option<TokenAndSpan> {
 
     // block comments starting with "/**" or "/*!" are doc-comments
     if rdr.curr == '*' || rdr.curr == '!' {
@@ -301,9 +315,9 @@ fn consume_block_comment(rdr: string_reader)
             acc += ~"*/";
             bump(rdr);
             bump(rdr);
-            return Some({
+            return Some(TokenAndSpan{
                 tok: token::DOC_COMMENT(rdr.interner.intern(@acc)),
-                sp: ast_util::mk_sp(start_bpos, rdr.pos)
+                sp: codemap::mk_sp(start_bpos, rdr.pos)
             });
         }
     } else {
@@ -403,7 +417,7 @@ fn scan_number(c: char, rdr: string_reader) -> token::Token {
         if str::len(num_str) == 0u {
             rdr.fatal(~"no valid digits found for number");
         }
-        let parsed = u64::from_str_radix(num_str, base as u64).get();
+        let parsed = u64::from_str_radix(num_str, base as uint).get();
         match tp {
           either::Left(t) => return token::LIT_INT(parsed as i64, t),
           either::Right(t) => return token::LIT_UINT(parsed, t)
@@ -457,7 +471,7 @@ fn scan_number(c: char, rdr: string_reader) -> token::Token {
         if str::len(num_str) == 0u {
             rdr.fatal(~"no valid digits found for number");
         }
-        let parsed = u64::from_str_radix(num_str, base as u64).get();
+        let parsed = u64::from_str_radix(num_str, base as uint).get();
 
         debug!("lexing %s as an unsuffixed integer literal",
                num_str);
@@ -702,6 +716,41 @@ fn consume_whitespace(rdr: string_reader) {
     while is_whitespace(rdr.curr) && !is_eof(rdr) { bump(rdr); }
 }
 
+#[cfg(test)]
+pub mod test {
+
+    use super::*;
+    use util::interner;
+    use diagnostic;
+    use util::testing::{check_equal, check_equal_ptr};
+    #[test] fn t1 () {
+        let teststr =
+            @~"/* my source file */
+fn main() { io::println(~\"zebra\"); }\n";
+        let cm = CodeMap::new();
+        let fm = cm.new_filemap(~"zebra.rs",teststr);
+        let ident_interner = token::mk_ident_interner(); // interner::mk();
+        let id = ident_interner.intern(@~"fn");
+        let span_handler =
+            diagnostic::mk_span_handler(diagnostic::mk_handler(None),@cm);
+        let string_reader = new_string_reader(span_handler,fm,ident_interner);
+        let tok1 = string_reader.next_token();
+        let tok2 = TokenAndSpan{
+            tok:token::IDENT(id, false),
+            sp:span {lo:BytePos(21),hi:BytePos(23),expn_info: None}};
+        check_equal (tok1,tok2);
+        // the 'main' id is already read:
+        check_equal (string_reader.last_pos,BytePos(28));
+        // read another token:
+        let tok3 = string_reader.next_token();
+        let tok4 = TokenAndSpan{
+            tok:token::IDENT(ident_interner.intern (@~"main"), false),
+            sp:span {lo:BytePos(24),hi:BytePos(28),expn_info: None}};
+        check_equal (tok3,tok4);
+        // the lparen is already read:
+        check_equal (string_reader.last_pos,BytePos(29))
+    }
+}
 
 //
 // Local Variables:
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index f9088bfd635..6169233c1b7 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -10,6 +10,7 @@
 
 //! The main parser interface
 
+
 use ast::node_id;
 use ast;
 use codemap::{span, CodeMap, FileMap, CharPos, BytePos};
@@ -33,6 +34,7 @@ pub mod token;
 pub mod comments;
 pub mod attr;
 
+
 /// Common routines shared by parser mods
 pub mod common;
 
@@ -215,3 +217,4 @@ pub fn new_parser_from_tts(sess: parse_sess, cfg: ast::crate_cfg,
                                     None, tts);
     return Parser(sess, cfg, trdr as reader)
 }
+
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 7dad15f9dfc..cdde542bb1f 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -21,8 +21,7 @@ use core::prelude::*;
 
 use ast::{expr, expr_lit, lit_nil};
 use ast;
-use ast_util::{respan};
-use codemap::span;
+use codemap::{span, respan};
 use parse::parser::Parser;
 use parse::token::Token;
 use parse::token;
@@ -138,7 +137,7 @@ pub impl Parser {
                    desc: &str) {
         self.span_err(sp, fmt!("obsolete syntax: %s", kind_str));
 
-        if !self.obsolete_set.contains_key(kind) {
+        if !self.obsolete_set.contains_key_ref(&kind) {
             self.sess.span_diagnostic.handler().note(fmt!("%s", desc));
             self.obsolete_set.insert(kind, ());
         }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 48f38092f88..5cd78dd9049 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -20,7 +20,7 @@ use ast::{decl_local, default_blk, deref, div, enum_def, enum_variant_kind};
 use ast::{expl, expr, expr_, expr_addr_of, expr_match, expr_again};
 use ast::{expr_assert, expr_assign, expr_assign_op, expr_binary, expr_block};
 use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body};
-use ast::{expr_fail, expr_field, expr_fn, expr_fn_block, expr_if, expr_index};
+use ast::{expr_field, expr_fn, expr_fn_block, expr_if, expr_index};
 use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac};
 use ast::{expr_method_call, expr_paren, expr_path, expr_rec, expr_repeat};
 use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary};
@@ -55,15 +55,16 @@ use ast::{view_path, view_path_glob, view_path_list, view_path_simple};
 use ast::{visibility, vstore, vstore_box, vstore_fixed, vstore_slice};
 use ast::{vstore_uniq};
 use ast;
-use ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec};
+use ast_util::{ident_to_path, operator_prec};
 use ast_util;
 use classify;
-use codemap::{span,FssNone, BytePos};
+use codemap::{span,FssNone, BytePos, spanned, respan, mk_sp};
 use codemap;
 use parse::attr::parser_attr;
 use parse::common::{seq_sep_none, token_to_str};
 use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed};
 use parse::lexer::reader;
+use parse::lexer::TokenAndSpan;
 use parse::obsolete::{ObsoleteClassTraits, ObsoleteModeInFnType};
 use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator};
 use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove};
@@ -86,7 +87,7 @@ use core::either;
 use core::result::Result;
 use core::vec::push;
 use core::vec;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 #[deriving_eq]
 enum restriction {
@@ -193,7 +194,7 @@ pub fn Parser(sess: parse_sess,
         token: tok0.tok,
         span: span0,
         last_span: span0,
-        buffer: [mut {tok: tok0.tok, sp: span0}, ..4],
+        mut buffer: [TokenAndSpan {tok: tok0.tok, sp: span0}, ..4],
         buffer_start: 0,
         buffer_end: 0,
         tokens_consumed: 0u,
@@ -213,7 +214,7 @@ pub struct Parser {
     mut token: token::Token,
     mut span: span,
     mut last_span: span,
-    mut buffer: [mut {tok: token::Token, sp: span} * 4],
+    mut buffer: [TokenAndSpan * 4],
     mut buffer_start: int,
     mut buffer_end: int,
     mut tokens_consumed: uint,
@@ -234,6 +235,7 @@ pub struct Parser {
 }
 
 pub impl Parser {
+    // advance the parser by one token
     fn bump() {
         self.last_span = self.span;
         let next = if self.buffer_start == self.buffer_end {
@@ -247,7 +249,8 @@ pub impl Parser {
         self.span = next.sp;
         self.tokens_consumed += 1u;
     }
-    fn swap(next: token::Token, +lo: BytePos, +hi: BytePos) {
+    // EFFECT: replace the current token and span with the given one
+    fn replace_token(next: token::Token, +lo: BytePos, +hi: BytePos) {
         self.token = next;
         self.span = mk_sp(lo, hi);
     }
@@ -800,7 +803,7 @@ pub impl Parser {
             self.bump();
             self.lit_from_token(tok)
         };
-        ast::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
+        codemap::spanned { node: lit, span: mk_sp(lo, self.last_span.hi) }
     }
 
     fn parse_path_without_tps() -> @path {
@@ -875,7 +878,7 @@ pub impl Parser {
                 self.parse_seq_lt_gt(Some(token::COMMA),
                                      |p| p.parse_ty(false))
             } else {
-                ast::spanned {node: ~[], span: path.span}
+                codemap::spanned {node: ~[], span: path.span}
             }
         };
 
@@ -917,14 +920,14 @@ pub impl Parser {
         @expr {
             id: self.get_id(),
             callee_id: self.get_id(),
-            node: expr_mac(ast::spanned {node: m, span: mk_sp(lo, hi)}),
+            node: expr_mac(codemap::spanned {node: m, span: mk_sp(lo, hi)}),
             span: mk_sp(lo, hi),
         }
     }
 
     fn mk_lit_u32(i: u32) -> @expr {
         let span = self.span;
-        let lv_lit = @ast::spanned { node: lit_uint(i as u64, ty_u32),
+        let lv_lit = @codemap::spanned { node: lit_uint(i as u64, ty_u32),
                                      span: span };
 
         @expr {
@@ -1031,12 +1034,6 @@ pub impl Parser {
                 }
             }
             hi = self.span.hi;
-        } else if self.eat_keyword(~"fail") {
-            if can_begin_expr(self.token) {
-                let e = self.parse_expr();
-                hi = e.span.hi;
-                ex = expr_fail(Some(e));
-            } else { ex = expr_fail(None); }
         } else if self.eat_keyword(~"log") {
             self.expect(token::LPAREN);
             let lvl = self.parse_expr();
@@ -1404,7 +1401,7 @@ pub impl Parser {
                 hi = e.span.hi;
                 // HACK: turn &[...] into a &-evec
                 ex = match e.node {
-                  expr_vec(*) | expr_lit(@ast::spanned {
+                  expr_vec(*) | expr_lit(@codemap::spanned {
                     node: lit_str(_), span: _
                   })
                   if m == m_imm => {
@@ -1429,7 +1426,7 @@ pub impl Parser {
               expr_vec(*) if m == m_mutbl =>
                 expr_vstore(e, expr_vstore_mut_box),
               expr_vec(*) if m == m_imm => expr_vstore(e, expr_vstore_box),
-              expr_lit(@ast::spanned {
+              expr_lit(@codemap::spanned {
                   node: lit_str(_), span: _}) if m == m_imm =>
                 expr_vstore(e, expr_vstore_box),
               _ => expr_unary(box(m), e)
@@ -1442,7 +1439,7 @@ pub impl Parser {
             hi = e.span.hi;
             // HACK: turn ~[...] into a ~-evec
             ex = match e.node {
-              expr_vec(*) | expr_lit(@ast::spanned {
+              expr_vec(*) | expr_lit(@codemap::spanned {
                 node: lit_str(_), span: _})
               if m == m_imm => expr_vstore(e, expr_vstore_uniq),
               _ => expr_unary(uniq(m), e)
@@ -1453,11 +1450,12 @@ pub impl Parser {
         return self.mk_expr(lo, hi, ex);
     }
 
-
+    // parse an expression of binops
     fn parse_binops() -> @expr {
-        return self.parse_more_binops(self.parse_prefix_expr(), 0);
+        self.parse_more_binops(self.parse_prefix_expr(), 0)
     }
 
+    // parse an expression of binops of at least min_prec precedence
     fn parse_more_binops(lhs: @expr, min_prec: uint) ->
         @expr {
         if self.expr_is_complete(lhs) { return lhs; }
@@ -1465,65 +1463,73 @@ pub impl Parser {
         if peeked == token::BINOP(token::OR) &&
             (self.restriction == RESTRICT_NO_BAR_OP ||
              self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) {
-            return lhs;
-        }
-        if peeked == token::OROR &&
+            lhs
+        } else if peeked == token::OROR &&
             self.restriction == RESTRICT_NO_BAR_OR_DOUBLEBAR_OP {
-            return lhs;
-        }
-        let cur_opt   = token_to_binop(peeked);
-        match cur_opt {
-          Some(cur_op) => {
-            let cur_prec = operator_prec(cur_op);
-            if cur_prec > min_prec {
-                self.bump();
-                let expr = self.parse_prefix_expr();
-                let rhs = self.parse_more_binops(expr, cur_prec);
-                self.get_id(); // see ast_util::op_expr_callee_id
-                let bin = self.mk_expr(lhs.span.lo, rhs.span.hi,
-                                        expr_binary(cur_op, lhs, rhs));
-                return self.parse_more_binops(bin, min_prec);
+            lhs
+        } else {
+            let cur_opt = token_to_binop(peeked);
+            match cur_opt {
+                Some(cur_op) => {
+                    let cur_prec = operator_prec(cur_op);
+                    if cur_prec > min_prec {
+                        self.bump();
+                        let expr = self.parse_prefix_expr();
+                        let rhs = self.parse_more_binops(expr, cur_prec);
+                        self.get_id(); // see ast_util::op_expr_callee_id
+                        let bin = self.mk_expr(lhs.span.lo, rhs.span.hi,
+                                               expr_binary(cur_op, lhs, rhs));
+                        self.parse_more_binops(bin, min_prec)
+                    } else {
+                        lhs
+                    }
+                }
+                None => {
+                    if as_prec > min_prec && self.eat_keyword(~"as") {
+                        let rhs = self.parse_ty(true);
+                        let _as = self.mk_expr(lhs.span.lo,
+                                               rhs.span.hi,
+                                               expr_cast(lhs, rhs));
+                        self.parse_more_binops(_as, min_prec)
+                    } else {
+                        lhs
+                    }
+                }
             }
-          }
-          _ => ()
-        }
-        if as_prec > min_prec && self.eat_keyword(~"as") {
-            let rhs = self.parse_ty(true);
-            let _as =
-                self.mk_expr(lhs.span.lo, rhs.span.hi, expr_cast(lhs, rhs));
-            return self.parse_more_binops(_as, min_prec);
         }
-        return lhs;
     }
 
+    // parse an assignment expression....
+    // actually, this seems to be the main entry point for
+    // parsing an arbitrary expression.
     fn parse_assign_expr() -> @expr {
         let lo = self.span.lo;
         let lhs = self.parse_binops();
         match copy self.token {
-          token::EQ => {
-            self.bump();
-            let rhs = self.parse_expr();
-            return self.mk_expr(lo, rhs.span.hi, expr_assign(lhs, rhs));
+            token::EQ => {
+                self.bump();
+                let rhs = self.parse_expr();
+                self.mk_expr(lo, rhs.span.hi, expr_assign(lhs, rhs))
           }
           token::BINOPEQ(op) => {
-            self.bump();
-            let rhs = self.parse_expr();
-            let mut aop;
-            match op {
-              token::PLUS => aop = add,
-              token::MINUS => aop = subtract,
-              token::STAR => aop = mul,
-              token::SLASH => aop = div,
-              token::PERCENT => aop = rem,
-              token::CARET => aop = bitxor,
-              token::AND => aop = bitand,
-              token::OR => aop = bitor,
-              token::SHL => aop = shl,
-              token::SHR => aop = shr
-            }
-            self.get_id(); // see ast_util::op_expr_callee_id
-            return self.mk_expr(lo, rhs.span.hi,
-                                expr_assign_op(aop, lhs, rhs));
+              self.bump();
+              let rhs = self.parse_expr();
+              let mut aop;
+              match op {
+                  token::PLUS => aop = add,
+                  token::MINUS => aop = subtract,
+                  token::STAR => aop = mul,
+                  token::SLASH => aop = div,
+                  token::PERCENT => aop = rem,
+                  token::CARET => aop = bitxor,
+                  token::AND => aop = bitand,
+                  token::OR => aop = bitor,
+                  token::SHL => aop = shl,
+                  token::SHR => aop = shr
+              }
+              self.get_id(); // see ast_util::op_expr_callee_id
+              self.mk_expr(lo, rhs.span.hi,
+                           expr_assign_op(aop, lhs, rhs))
           }
           token::LARROW => {
               self.obsolete(copy self.span, ObsoleteBinaryMove);
@@ -1531,17 +1537,18 @@ pub impl Parser {
               self.bump(); // <-
               self.bump(); // rhs
               self.bump(); // ;
-              return self.mk_expr(lo, self.span.hi,
-                                  expr_break(None));
+              self.mk_expr(lo, self.span.hi,
+                           expr_break(None))
           }
           token::DARROW => {
             self.bump();
             let rhs = self.parse_expr();
-            return self.mk_expr(lo, rhs.span.hi, expr_swap(lhs, rhs));
+            self.mk_expr(lo, rhs.span.hi, expr_swap(lhs, rhs))
+          }
+          _ => {
+              lhs
           }
-          _ => {/* fall through */ }
         }
-        return lhs;
     }
 
     fn parse_if_expr() -> @expr {
@@ -1556,7 +1563,7 @@ pub impl Parser {
             hi = elexpr.span.hi;
         }
         let q = {cond: cond, then: thn, els: els, lo: lo, hi: hi};
-        return self.mk_expr(q.lo, q.hi, expr_if(q.cond, q.then, q.els));
+        self.mk_expr(q.lo, q.hi, expr_if(q.cond, q.then, q.els))
     }
 
     fn parse_fn_expr(proto: Proto) -> @expr {
@@ -1567,8 +1574,9 @@ pub impl Parser {
         let decl = self.parse_fn_decl(|p| p.parse_arg_or_capture_item());
 
         let body = self.parse_block();
-        return self.mk_expr(lo, body.span.hi,
-                            expr_fn(proto, decl, body, @()));
+
+        self.mk_expr(lo, body.span.hi,
+                            expr_fn(proto, decl, body, @()))
     }
 
     // `|args| { ... }` like in `do` expressions
@@ -1794,7 +1802,7 @@ pub impl Parser {
                 self.eat(token::COMMA);
             }
 
-            let blk = ast::spanned {
+            let blk = codemap::spanned {
                 node: ast::blk_ {
                     view_items: ~[],
                     stmts: ~[],
@@ -1812,10 +1820,12 @@ pub impl Parser {
         return self.mk_expr(lo, hi, expr_match(discriminant, arms));
     }
 
+    // parse an expression
     fn parse_expr() -> @expr {
         return self.parse_expr_res(UNRESTRICTED);
     }
 
+    // parse an expression, subject to the given restriction
     fn parse_expr_res(r: restriction) -> @expr {
         let old = self.restriction;
         self.restriction = r;
@@ -1943,7 +1953,9 @@ pub impl Parser {
             // HACK: parse @"..." as a literal of a vstore @str
             pat = match sub.node {
               pat_lit(e@@expr {
-                node: expr_lit(@ast::spanned {node: lit_str(_), span: _}), _
+                node: expr_lit(@codemap::spanned {
+                    node: lit_str(_),
+                    span: _}), _
               }) => {
                 let vst = @expr {
                     id: self.get_id(),
@@ -1963,7 +1975,9 @@ pub impl Parser {
             // HACK: parse ~"..." as a literal of a vstore ~str
             pat = match sub.node {
               pat_lit(e@@expr {
-                node: expr_lit(@ast::spanned {node: lit_str(_), span: _}), _
+                node: expr_lit(@codemap::spanned {
+                    node: lit_str(_),
+                    span: _}), _
               }) => {
                 let vst = @expr {
                     id: self.get_id(),
@@ -1985,7 +1999,7 @@ pub impl Parser {
               // HACK: parse &"..." as a literal of a borrowed str
               pat = match sub.node {
                   pat_lit(e@@expr {
-                      node: expr_lit(@ast::spanned {
+                      node: expr_lit(@codemap::spanned {
                             node: lit_str(_), span: _}), _
                   }) => {
                       let vst = @expr {
@@ -2011,7 +2025,9 @@ pub impl Parser {
             if self.token == token::RPAREN {
                 hi = self.span.hi;
                 self.bump();
-                let lit = @ast::spanned {node: lit_nil, span: mk_sp(lo, hi)};
+                let lit = @codemap::spanned {
+                    node: lit_nil,
+                    span: mk_sp(lo, hi)};
                 let expr = self.mk_expr(lo, hi, expr_lit(lit));
                 pat = pat_lit(expr);
             } else {
@@ -2381,7 +2397,7 @@ pub impl Parser {
                             match self.token {
                                 token::SEMI => {
                                     self.bump();
-                                    stmts.push(@ast::spanned {
+                                    stmts.push(@codemap::spanned {
                                         node: stmt_semi(e, stmt_id),
                                         .. *stmt});
                                 }
@@ -2406,7 +2422,7 @@ pub impl Parser {
                             match self.token {
                                 token::SEMI => {
                                     self.bump();
-                                    stmts.push(@ast::spanned {
+                                    stmts.push(@codemap::spanned {
                                         node: stmt_mac((*m), true),
                                         .. *stmt});
                                 }
@@ -2500,7 +2516,7 @@ pub impl Parser {
                           _ => None
                         }
                       }
-                      _ => fail
+                      _ => die!()
                     };
 
                     match maybe_bound {
@@ -2940,7 +2956,7 @@ pub impl Parser {
 
         let actual_dtor = do the_dtor.map |dtor| {
             let (d_body, d_attrs, d_s) = *dtor;
-            ast::spanned { node: ast::struct_dtor_ { id: self.get_id(),
+            codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(),
                                                      attrs: d_attrs,
                                                      self_id: self.get_id(),
                                                      body: d_body},
@@ -3445,7 +3461,7 @@ pub impl Parser {
         self.bump();
         let mut actual_dtor = do the_dtor.map |dtor| {
             let (d_body, d_attrs, d_s) = *dtor;
-            ast::spanned { node: ast::struct_dtor_ { id: self.get_id(),
+            codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(),
                                                      attrs: d_attrs,
                                                      self_id: self.get_id(),
                                                      body: d_body },
@@ -3737,7 +3753,7 @@ pub impl Parser {
               _ => self.fatal(~"expected open delimiter")
             };
             let m = ast::mac_invoc_tt(pth, tts);
-            let m: ast::mac = ast::spanned { node: m,
+            let m: ast::mac = codemap::spanned { node: m,
                                              span: mk_sp(self.span.lo,
                                                          self.span.hi) };
             let item_ = item_mac(m);
@@ -3892,7 +3908,7 @@ pub impl Parser {
             let metadata = self.parse_optional_meta();
             view_item_use(ident, metadata, self.get_id())
         } else {
-            fail;
+            die!();
         };
         self.expect(token::SEMI);
         @ast::view_item { node: node,
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 2093b5caebd..2770d823bf3 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -21,7 +21,7 @@ use core::char;
 use core::cmp;
 use core::str;
 use core::task;
-use std::map::HashMap;
+use std::oldmap::HashMap;
 
 #[auto_encode]
 #[auto_decode]
@@ -209,7 +209,7 @@ pub fn to_str(in: @ident_interner, t: Token) -> ~str {
                       nt_block(*) => ~"block",
                       nt_stmt(*) => ~"statement",
                       nt_pat(*) => ~"pattern",
-                      nt_expr(*) => fail ~"should have been handled above",
+                      nt_expr(*) => die!(~"should have been handled above"),
                       nt_ty(*) => ~"type",
                       nt_ident(*) => ~"identifier",
                       nt_path(*) => ~"path",
@@ -262,7 +262,7 @@ pub fn flip_delimiter(t: token::Token) -> token::Token {
       token::RPAREN => token::LPAREN,
       token::RBRACE => token::LBRACE,
       token::RBRACKET => token::LBRACKET,
-      _ => fail
+      _ => die!()
     }
 }
 
@@ -454,13 +454,13 @@ pub fn mk_fake_ident_interner() -> @ident_interner {
  */
 pub fn keyword_table() -> HashMap<~str, ()> {
     let keywords = HashMap();
-    for temporary_keyword_table().each_key |word| {
+    for temporary_keyword_table().each_key_ref |&word| {
         keywords.insert(word, ());
     }
-    for strict_keyword_table().each_key |word| {
+    for strict_keyword_table().each_key_ref |&word| {
         keywords.insert(word, ());
     }
-    for reserved_keyword_table().each_key |word| {
+    for reserved_keyword_table().each_key_ref |&word| {
         keywords.insert(word, ());
     }
     keywords
@@ -487,7 +487,7 @@ pub fn strict_keyword_table() -> HashMap<~str, ()> {
         ~"const", ~"copy",
         ~"do", ~"drop",
         ~"else", ~"enum", ~"extern",
-        ~"fail", ~"false", ~"fn", ~"for",
+        ~"false", ~"fn", ~"for",
         ~"if", ~"impl",
         ~"let", ~"log", ~"loop",
         ~"match", ~"mod", ~"move", ~"mut",
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index d3487fa845f..34ba4526c47 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -119,7 +119,7 @@ pub fn tok_str(++t: token) -> ~str {
     }
 }
 
-pub fn buf_str(toks: ~[mut token], szs: ~[mut int], left: uint, right: uint,
+pub fn buf_str(toks: ~[token], szs: ~[int], left: uint, right: uint,
                lim: uint) -> ~str {
     let n = vec::len(toks);
     assert (n == vec::len(szs));
@@ -148,17 +148,17 @@ pub fn mk_printer(out: io::Writer, linewidth: uint) -> printer {
     // fall behind.
     let n: uint = 3 * linewidth;
     debug!("mk_printer %u", linewidth);
-    let token: ~[mut token] = vec::cast_to_mut(vec::from_elem(n, EOF));
-    let size: ~[mut int] = vec::cast_to_mut(vec::from_elem(n, 0));
-    let scan_stack: ~[mut uint] = vec::cast_to_mut(vec::from_elem(n, 0u));
+    let mut token: ~[token] = vec::from_elem(n, EOF);
+    let mut size: ~[int] = vec::from_elem(n, 0);
+    let mut scan_stack: ~[uint] = vec::from_elem(n, 0u);
     printer_(@{out: out,
                buf_len: n,
                mut margin: linewidth as int,
                mut space: linewidth as int,
                mut left: 0,
                mut right: 0,
-               token: move token,
-               size: move size,
+               mut token: move token,
+               mut size: move size,
                mut left_total: 0,
                mut right_total: 0,
                mut scan_stack: move scan_stack,
@@ -254,8 +254,8 @@ pub type printer_ = {
     mut space: int, // number of spaces left on line
     mut left: uint, // index of left side of input stream
     mut right: uint, // index of right side of input stream
-    token: ~[mut token], // ring-buffr stream goes through
-    size: ~[mut int], // ring-buffer of calculated sizes
+    mut token: ~[token], // ring-buffr stream goes through
+    mut size: ~[int], // ring-buffer of calculated sizes
     mut left_total: int, // running size of stream "...left"
     mut right_total: int, // running size of stream "...right"
     // pseudo-stack, really a ring too. Holds the
@@ -264,7 +264,7 @@ pub type printer_ = {
     // BEGIN (if there is any) on top of it. Stuff is flushed off the
     // bottom as it becomes irrelevant due to the primary ring-buffer
     // advancing.
-    mut scan_stack: ~[mut uint],
+    mut scan_stack: ~[uint],
     mut scan_stack_empty: bool, // top==bottom disambiguator
     mut top: uint, // index of top of scan_stack
     mut bottom: uint, // index of bottom of scan_stack
@@ -532,7 +532,7 @@ pub impl printer {
           }
           EOF => {
             // EOF should never get here.
-            fail;
+            die!();
           }
         }
     }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 6661f5e810a..5079766239b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -422,10 +422,10 @@ pub fn print_type_ex(s: ps, &&ty: @ast::Ty, print_colons: bool) {
         word(s.s, ~"]");
       }
       ast::ty_mac(_) => {
-          fail ~"print_type doesn't know how to print a ty_mac";
+          die!(~"print_type doesn't know how to print a ty_mac");
       }
       ast::ty_infer => {
-          fail ~"print_type shouldn't see a ty_infer";
+          die!(~"print_type shouldn't see a ty_infer");
       }
 
     }
@@ -575,7 +575,7 @@ pub fn print_item(s: ps, &&item: @ast::item) {
         }
         bclose(s, item.span);
       }
-      ast::item_mac(ast::spanned { node: ast::mac_invoc_tt(pth, ref tts),
+      ast::item_mac(codemap::spanned { node: ast::mac_invoc_tt(pth, ref tts),
                                    _}) => {
         print_visibility(s, item.vis);
         print_path(s, pth, false);
@@ -617,7 +617,7 @@ pub fn print_enum_def(s: ps, enum_definition: ast::enum_def,
         word_space(s, ~"=");
         match enum_definition.variants[0].node.kind {
             ast::tuple_variant_kind(args) => print_type(s, args[0].ty),
-            _ => fail ~"newtype syntax with struct?"
+            _ => die!(~"newtype syntax with struct?")
         }
         word(s.s, ~";");
         end(s);
@@ -686,7 +686,7 @@ pub fn print_struct(s: ps,
             }
 
             match field.node.kind {
-                ast::named_field(*) => fail ~"unexpected named field",
+                ast::named_field(*) => die!(~"unexpected named field"),
                 ast::unnamed_field => {
                     maybe_print_comment(s, field.span.lo);
                     print_type(s, field.node.ty);
@@ -709,7 +709,7 @@ pub fn print_struct(s: ps,
 
         for struct_def.fields.each |field| {
             match field.node.kind {
-                ast::unnamed_field => fail ~"unexpected unnamed field",
+                ast::unnamed_field => die!(~"unexpected unnamed field"),
                 ast::named_field(ident, mutability, visibility) => {
                     hardbreak_if_not_bol(s);
                     maybe_print_comment(s, field.span.lo);
@@ -995,7 +995,7 @@ pub fn print_if(s: ps, test: @ast::expr, blk: ast::blk,
               }
               // BLEAH, constraints would be great here
               _ => {
-                  fail ~"print_if saw if with weird alternative";
+                  die!(~"print_if saw if with weird alternative");
               }
             }
           }
@@ -1296,7 +1296,7 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) {
                         }
                         end(s); // close enclosing cbox
                     }
-                    None => fail
+                    None => die!()
                 }
             } else {
                 // the block will close the pattern's ibox
@@ -1393,13 +1393,6 @@ pub fn print_expr(s: ps, &&expr: @ast::expr) {
         word(s.s, ~"]");
       }
       ast::expr_path(path) => print_path(s, path, true),
-      ast::expr_fail(maybe_fail_val) => {
-        word(s.s, ~"fail");
-        match maybe_fail_val {
-          Some(expr) => { word(s.s, ~" "); print_expr(s, expr); }
-          _ => ()
-        }
-      }
       ast::expr_break(opt_ident) => {
         word(s.s, ~"break");
         space(s.s);
@@ -2013,24 +2006,24 @@ pub fn print_literal(s: ps, &&lit: @ast::lit) {
       ast::lit_int(i, t) => {
         if i < 0_i64 {
             word(s.s,
-                 ~"-" + u64::to_str(-i as u64, 10u)
+                 ~"-" + u64::to_str_radix(-i as u64, 10u)
                  + ast_util::int_ty_to_str(t));
         } else {
             word(s.s,
-                 u64::to_str(i as u64, 10u)
+                 u64::to_str_radix(i as u64, 10u)
                  + ast_util::int_ty_to_str(t));
         }
       }
       ast::lit_uint(u, t) => {
         word(s.s,
-             u64::to_str(u, 10u)
+             u64::to_str_radix(u, 10u)
              + ast_util::uint_ty_to_str(t));
       }
       ast::lit_int_unsuffixed(i) => {
         if i < 0_i64 {
-            word(s.s, ~"-" + u64::to_str(-i as u64, 10u));
+            word(s.s, ~"-" + u64::to_str_radix(-i as u64, 10u));
         } else {
-            word(s.s, u64::to_str(i as u64, 10u));
+            word(s.s, u64::to_str_radix(i as u64, 10u));
         }
       }
       ast::lit_float(f, t) => {
@@ -2241,10 +2234,11 @@ pub mod test {
     use parse;
     use super::*;
     //use util;
+    use util::testing::check_equal;
 
     fn string_check<T : Eq> (given : &T, expected: &T) {
         if !(given == expected) {
-            fail (fmt!("given %?, expected %?",given,expected));
+            die!(fmt!("given %?, expected %?",given,expected));
         }
     }
 
@@ -2257,11 +2251,11 @@ pub mod test {
             inputs: ~[],
             output: @ast::Ty {id: 0,
                               node: ast::ty_nil,
-                              span: ast_util::dummy_sp()},
+                              span: codemap::dummy_sp()},
             cf: ast::return_val
         };
-        assert fun_to_str(decl, abba_ident, ~[],mock_interner)
-            == ~"fn abba()";
+        check_equal (&fun_to_str(decl, abba_ident, ~[],mock_interner),
+                     &~"fn abba()");
     }
 
     #[test]
@@ -2269,7 +2263,7 @@ pub mod test {
         let mock_interner = parse::token::mk_fake_ident_interner();
         let ident = mock_interner.intern(@~"principal_skinner");
 
-        let var = ast_util::respan(ast_util::dummy_sp(), ast::variant_ {
+        let var = codemap::respan(codemap::dummy_sp(), ast::variant_ {
             name: ident,
             attrs: ~[],
             // making this up as I go.... ?
@@ -2280,7 +2274,7 @@ pub mod test {
         });
 
         let varstr = variant_to_str(var,mock_interner);
-        string_check(&varstr,&~"pub principal_skinner");
+        check_equal(&varstr,&~"pub principal_skinner");
     }
 }
 
diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc
index dc5964e6a12..a6d50b9cf09 100644
--- a/src/libsyntax/syntax.rc
+++ b/src/libsyntax/syntax.rc
@@ -46,10 +46,11 @@ pub mod ast_map;
 pub mod visit;
 pub mod fold;
 pub mod util {
-    #[path = "interner.rs"]
     pub mod interner;
+    pub mod testing;
 }
 
+
 #[path = "parse/mod.rs"]
 pub mod parse;
 
@@ -86,3 +87,4 @@ pub mod ext {
 
     pub mod trace_macros;
 }
+
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 23db470391a..19b938ccd68 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -15,13 +15,13 @@
 use core::prelude::*;
 
 use core::dvec::DVec;
-use std::map::HashMap;
-use std::map;
+use std::oldmap::HashMap;
+use std::oldmap;
 
 pub type hash_interner<T> = {map: HashMap<T, uint>, vect: DVec<T>};
 
 pub fn mk<T:Eq IterBytes Hash Const Copy>() -> Interner<T> {
-    let m = map::HashMap::<T, uint>();
+    let m = oldmap::HashMap::<T, uint>();
     let hi: hash_interner<T> =
         {map: m, vect: DVec()};
     move ((move hi) as Interner::<T>)
diff --git a/src/libsyntax/util/testing.rs b/src/libsyntax/util/testing.rs
new file mode 100644
index 00000000000..39d3b003e66
--- /dev/null
+++ b/src/libsyntax/util/testing.rs
@@ -0,0 +1,24 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// support for test cases.
+use core::cmp;
+
+pub pure fn check_equal_ptr<T : cmp::Eq> (given : &T, expected: &T) {
+    if !((given == expected) && (expected == given )) {
+        die!(fmt!("given %?, expected %?",given,expected));
+    }
+}
+
+pub pure fn check_equal<T : cmp::Eq> (given : T, expected: T) {
+    if !((given == expected) && (expected == given )) {
+        die!(fmt!("given %?, expected %?",given,expected));
+    }
+}
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a174ea47740..eea1a6906e4 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -485,7 +485,6 @@ pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         (v.visit_expr)(b, e, v);
       }
       expr_path(p) => visit_path(p, e, v),
-      expr_fail(eo) => visit_expr_opt(eo, e, v),
       expr_break(_) => (),
       expr_again(_) => (),
       expr_ret(eo) => visit_expr_opt(eo, e, v),