about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/gc.rs1
-rw-r--r--src/libcore/hashmap.rs2
-rw-r--r--src/libcore/num.rs5
-rw-r--r--src/libcore/pipes.rs3
-rw-r--r--src/libcore/prelude.rs2
-rw-r--r--src/libcore/private/weak_task.rs2
-rw-r--r--src/libcore/task/mod.rs2
-rw-r--r--src/libcore/task/spawn.rs4
-rw-r--r--src/librustc/metadata/encoder.rs1
-rw-r--r--src/librustc/metadata/tydecode.rs23
-rw-r--r--src/librustc/metadata/tyencode.rs4
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs7
-rw-r--r--src/librustc/middle/borrowck/gather_loans.rs6
-rw-r--r--src/librustc/middle/borrowck/loan.rs15
-rw-r--r--src/librustc/middle/borrowck/mod.rs28
-rw-r--r--src/librustc/middle/borrowck/preserve.rs29
-rw-r--r--src/librustc/middle/mem_categorization.rs220
-rw-r--r--src/librustc/middle/region.rs19
-rw-r--r--src/librustc/middle/trans/_match.rs3
-rw-r--r--src/librustc/middle/trans/base.rs10
-rw-r--r--src/librustc/middle/trans/common.rs9
-rw-r--r--src/librustc/middle/trans/datum.rs4
-rw-r--r--src/librustc/middle/trans/expr.rs3
-rw-r--r--src/librustc/middle/trans/foreign.rs6
-rw-r--r--src/librustc/middle/trans/machine.rs13
-rw-r--r--src/librustc/middle/trans/meth.rs7
-rw-r--r--src/librustc/middle/ty.rs131
-rw-r--r--src/librustc/middle/typeck/astconv.rs9
-rw-r--r--src/librustc/middle/typeck/check/method.rs48
-rw-r--r--src/librustc/middle/typeck/check/mod.rs42
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs8
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs3
-rw-r--r--src/librustc/middle/typeck/coherence.rs129
-rw-r--r--src/librustc/middle/typeck/collect.rs33
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs14
-rw-r--r--src/librustc/middle/typeck/infer/mod.rs2
-rw-r--r--src/librustc/util/ppaux.rs9
-rw-r--r--src/librustdoc/astsrv.rs6
-rw-r--r--src/librustdoc/attr_pass.rs18
-rw-r--r--src/librustdoc/config.rs14
-rw-r--r--src/librustdoc/desc_to_brief_pass.rs10
-rw-r--r--src/librustdoc/doc.rs283
-rw-r--r--src/librustdoc/extract.rs33
-rw-r--r--src/librustdoc/fold.rs30
-rw-r--r--src/librustdoc/markdown_index_pass.rs10
-rw-r--r--src/librustdoc/page_pass.rs6
-rw-r--r--src/librustdoc/path_pass.rs6
-rw-r--r--src/librustdoc/prune_hidden_pass.rs2
-rw-r--r--src/librustdoc/prune_private_pass.rs2
-rw-r--r--src/librustdoc/sectionalize_pass.rs14
-rw-r--r--src/librustdoc/sort_pass.rs2
-rw-r--r--src/librustdoc/text_pass.rs14
-rw-r--r--src/librustdoc/tystr_pass.rs18
-rw-r--r--src/libstd/bigint.rs49
-rw-r--r--src/libstd/deque.rs58
-rw-r--r--src/libstd/ebml.rs1
-rw-r--r--src/libstd/json.rs1
-rw-r--r--src/libstd/map.rs6
-rw-r--r--src/libstd/smallintmap.rs8
-rw-r--r--src/libsyntax/ast_map.rs2
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/codemap.rs2
-rw-r--r--src/libsyntax/diagnostic.rs2
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs2
-rw-r--r--src/libsyntax/ext/pipes/mod.rs1
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs5
-rw-r--r--src/libsyntax/ext/pipes/proto.rs2
-rw-r--r--src/libsyntax/ext/quote.rs2
-rw-r--r--src/libsyntax/ext/source_util.rs2
-rw-r--r--src/libsyntax/parse/comments.rs2
-rw-r--r--src/libsyntax/parse/lexer.rs2
-rw-r--r--src/test/auxiliary/issue_2242_b.rs19
-rw-r--r--src/test/compile-fail/drop-on-non-struct.rs1
-rw-r--r--src/test/compile-fail/map-types.rs9
-rw-r--r--src/test/run-pass/auto-encode.rs11
-rw-r--r--src/test/run-pass/class-impl-very-parameterized-trait.rs2
-rw-r--r--src/test/run-pass/issue-2242-d.rs26
77 files changed, 704 insertions, 837 deletions
diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs
index bb2e7d788fd..4e69947ac67 100644
--- a/src/libcore/gc.rs
+++ b/src/libcore/gc.rs
@@ -42,6 +42,7 @@ with destructors.
 #[allow(structural_records)];
 
 use cast;
+use container::{Container, Mutable, Map, Set};
 use io;
 use libc::{size_t, uintptr_t};
 use option::{None, Option, Some};
diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs
index 27b5ddadff9..df98e469bbc 100644
--- a/src/libcore/hashmap.rs
+++ b/src/libcore/hashmap.rs
@@ -16,7 +16,6 @@
 
 use cmp::Eq;
 use hash::Hash;
-use prelude::*;
 use to_bytes::IterBytes;
 
 /// Open addressing with linear probing.
@@ -464,6 +463,7 @@ pub mod linear {
 
 #[test]
 pub mod test {
+    use container::{Container, Mutable, Map, Set};
     use option::{None, Some};
     use hashmap::linear::LinearMap;
     use hashmap::linear;
diff --git a/src/libcore/num.rs b/src/libcore/num.rs
index 4c2daa458a4..6eb22e53a24 100644
--- a/src/libcore/num.rs
+++ b/src/libcore/num.rs
@@ -23,6 +23,11 @@ pub trait Num {
     static pure fn from_int(n: int) -> self;
 }
 
+pub trait IntConvertible {
+    pure fn to_int(&self) -> int;
+    static pure fn from_int(n: int) -> self;
+}
+
 pub trait Zero {
     static pure fn zero() -> self;
 }
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index 5029fc89b34..33826d10c3c 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -96,10 +96,9 @@ use either::{Either, Left, Right};
 use kinds::Owned;
 use libc;
 use option;
-use option::unwrap;
+use option::{None, Option, Some, unwrap};
 use pipes;
 use ptr;
-use prelude::*;
 use private;
 use task;
 use vec;
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index 72aa828ff12..d3813d1ae85 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -35,6 +35,8 @@ pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
 pub use vec::{OwnedVector, OwnedCopyableVector};
 pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
 pub use iter::{CopyableOrderedIter, CopyableNonstrictIter, Times};
+pub use container::{Container, Mutable, Map, Set};
+pub use pipes::{GenericChan, GenericPort};
 
 pub use num::Num;
 pub use ptr::Ptr;
diff --git a/src/libcore/private/weak_task.rs b/src/libcore/private/weak_task.rs
index 25a03ff960f..573a3e54b44 100644
--- a/src/libcore/private/weak_task.rs
+++ b/src/libcore/private/weak_task.rs
@@ -22,7 +22,7 @@ use option::{Some, None, swap_unwrap};
 use private::at_exit::at_exit;
 use private::global::global_data_clone_create;
 use private::finally::Finally;
-use pipes::{Port, Chan, SharedChan, stream};
+use pipes::{Port, Chan, SharedChan, GenericSmartChan, stream};
 use task::{Task, task, spawn};
 use task::rt::{task_id, get_task_id};
 use hashmap::linear::LinearMap;
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
index aa82309c78a..9ddafee6938 100644
--- a/src/libcore/task/mod.rs
+++ b/src/libcore/task/mod.rs
@@ -45,7 +45,7 @@ use iter;
 use libc;
 use option;
 use result::Result;
-use pipes::{stream, Chan, Port, SharedChan};
+use pipes::{stream, Chan, GenericChan, GenericPort, Port, SharedChan};
 use pipes;
 use prelude::*;
 use ptr;
diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs
index a5ab4af40be..0a2f6634214 100644
--- a/src/libcore/task/spawn.rs
+++ b/src/libcore/task/spawn.rs
@@ -74,8 +74,10 @@
 #[warn(deprecated_mode)];
 
 use cast;
+use container::Map;
+use oldcomm;
 use option;
-use pipes::{stream, Chan, Port};
+use pipes::{Chan, GenericChan, GenericPort, Port};
 use pipes;
 use prelude::*;
 use private;
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 79ce755137e..399184ea8a5 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -37,6 +37,7 @@ use core::to_bytes::IterBytes;
 use core::uint;
 use core::vec;
 use std::map::HashMap;
+use std::serialize::Encodable;
 use std::{ebml, map};
 use std;
 use syntax::ast::*;
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 590dd9f7ea7..787a1d3c906 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -17,7 +17,8 @@
 use core::prelude::*;
 
 use middle::ty;
-use middle::ty::{FnTyBase, FnMeta, FnSig};
+use middle::ty::{FnTyBase, FnMeta, FnSig, arg, creader_cache_key, field};
+use middle::ty::{substs};
 
 use core::io;
 use core::str;
@@ -174,9 +175,11 @@ fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs {
     while peek(st) != ']' { params.push(parse_ty(st, conv)); }
     st.pos = st.pos + 1u;
 
-    return {self_r: self_r,
-         self_ty: self_ty,
-         tps: params};
+    return substs {
+        self_r: self_r,
+        self_ty: self_ty,
+        tps: params
+    };
 }
 
 fn parse_bound_region(st: @pstate) -> ty::bound_region {
@@ -308,7 +311,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
         let mut fields: ~[ty::field] = ~[];
         while peek(st) != ']' {
             let name = st.tcx.sess.ident_of(parse_str(st, '='));
-            fields.push({ident: name, mt: parse_mt(st, conv)});
+            fields.push(ty::field { ident: name, mt: parse_mt(st, conv) });
         }
         st.pos = st.pos + 1u;
         return ty::mk_rec(st.tcx, fields);
@@ -333,12 +336,13 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
         assert (next(st) == ':');
         let len = parse_hex(st);
         assert (next(st) == '#');
-        match st.tcx.rcache.find({cnum: st.crate, pos: pos, len: len}) {
+        let key = creader_cache_key { cnum: st.crate, pos: pos, len: len };
+        match st.tcx.rcache.find(key) {
           Some(tt) => return tt,
           None => {
             let ps = @{pos: pos ,.. copy *st};
             let tt = parse_ty(ps, conv);
-            st.tcx.rcache.insert({cnum: st.crate, pos: pos, len: len}, tt);
+            st.tcx.rcache.insert(key, tt);
             return tt;
           }
         }
@@ -421,8 +425,7 @@ fn parse_onceness(c: char) -> ast::Onceness {
 }
 
 fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
-    {mode: parse_mode(st),
-     ty: parse_ty(st, conv)}
+    ty::arg { mode: parse_mode(st), ty: parse_ty(st, conv) }
 }
 
 fn parse_mode(st: @pstate) -> ast::mode {
@@ -446,7 +449,7 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy {
     let mut inputs: ~[ty::arg] = ~[];
     while peek(st) != ']' {
         let mode = parse_mode(st);
-        inputs.push({mode: mode, ty: parse_ty(st, conv)});
+        inputs.push(ty::arg { mode: mode, ty: parse_ty(st, conv) });
     }
     st.pos += 1u; // eat the ']'
     let ret_ty = parse_ty(st, conv);
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index d318f00ad67..04e833d812b 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -13,8 +13,8 @@
 
 use core::prelude::*;
 
+use middle::ty::{Vid, param_ty};
 use middle::ty;
-use middle::ty::Vid;
 
 use core::io::WriterUtil;
 use core::io;
@@ -301,7 +301,7 @@ fn enc_sty(w: io::Writer, cx: @ctxt, +st: ty::sty) {
       ty::ty_infer(_) => {
         cx.diag.handler().bug(~"Cannot encode inference variable types");
       }
-      ty::ty_param({idx: id, def_id: did}) => {
+      ty::ty_param(param_ty {idx: id, def_id: did}) => {
         w.write_char('p');
         w.write_str((cx.ds)(did));
         w.write_char('|');
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index ff5854322f4..bdb889b68f1 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -20,7 +20,7 @@
 use core::prelude::*;
 
 use middle::borrowck::{Loan, bckerr, borrowck_ctxt, cmt, inherent_mutability};
-use middle::borrowck::{req_maps, save_and_restore};
+use middle::borrowck::{req_maps, root_map_key, save_and_restore};
 use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref};
 use middle::mem_categorization::{cat_local, cat_rvalue, cat_self};
 use middle::mem_categorization::{cat_special, gc_ptr, loan_path, lp_arg};
@@ -396,7 +396,10 @@ impl check_loan_ctxt {
 
                 match ptr_kind {
                     gc_ptr(ast::m_mutbl) => {
-                        let key = { id: base.id, derefs: deref_count };
+                        let key = root_map_key {
+                            id: base.id,
+                            derefs: deref_count
+                        };
                         self.bccx.write_guard_map.insert(key, ());
                     }
                     _ => {}
diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs
index 0fff0c66a38..6f913f99e11 100644
--- a/src/librustc/middle/borrowck/gather_loans.rs
+++ b/src/librustc/middle/borrowck/gather_loans.rs
@@ -19,7 +19,8 @@
 use core::prelude::*;
 
 use middle::borrowck::preserve::{preserve_condition, pc_ok, pc_if_pure};
-use middle::borrowck::{Loan, bckres, borrowck_ctxt, err_mutbl, req_maps};
+use middle::borrowck::{Loan, bckerr, bckres, borrowck_ctxt, err_mutbl};
+use middle::borrowck::{req_maps};
 use middle::mem_categorization::{cat_binding, cat_discr, cmt, comp_variant};
 use middle::mem_categorization::{mem_categorization_ctxt};
 use middle::mem_categorization::{opt_deref_kind};
@@ -452,8 +453,7 @@ impl gather_loan_ctxt {
             debug!("required is const or they are the same");
             Ok(pc_ok)
         } else {
-            let e = {cmt: cmt,
-                     code: err_mutbl(req_mutbl)};
+            let e = bckerr { cmt: cmt, code: err_mutbl(req_mutbl) };
             if req_mutbl == m_imm {
                 // if this is an @mut box, then it's generally OK to borrow as
                 // &imm; this will result in a write guard
diff --git a/src/librustc/middle/borrowck/loan.rs b/src/librustc/middle/borrowck/loan.rs
index d3dc75aad7f..48cc0502f6c 100644
--- a/src/librustc/middle/borrowck/loan.rs
+++ b/src/librustc/middle/borrowck/loan.rs
@@ -43,7 +43,7 @@ XXX --- much more needed, don't have time to write this all up now
 
 use core::prelude::*;
 
-use middle::borrowck::{Loan, bckres, borrowck_ctxt, cmt, err_mutbl};
+use middle::borrowck::{Loan, bckerr, bckres, borrowck_ctxt, cmt, err_mutbl};
 use middle::borrowck::{err_out_of_scope};
 use middle::mem_categorization::{cat_arg, cat_binding, cat_discr, cat_comp};
 use middle::mem_categorization::{cat_deref, cat_discr, cat_local, cat_self};
@@ -309,8 +309,10 @@ impl LoanContext {
                     // We do not allow non-mutable data to be loaned
                     // out as mutable under any circumstances.
                     if cmt.mutbl != m_mutbl {
-                        return Err({cmt:cmt,
-                                    code:err_mutbl(req_mutbl)});
+                        return Err(bckerr {
+                            cmt:cmt,
+                            code:err_mutbl(req_mutbl)
+                        });
                     }
                 }
                 m_const | m_imm => {
@@ -332,9 +334,10 @@ impl LoanContext {
         } else {
             // The loan being requested lives longer than the data
             // being loaned out!
-            return Err({cmt:cmt,
-                        code:err_out_of_scope(scope_ub,
-                                              self.scope_region)});
+            return Err(bckerr {
+                cmt:cmt,
+                code:err_out_of_scope(scope_ub, self.scope_region)
+            });
         }
     }
 }
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index a01c04a8abf..2afdcc9d47d 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -344,7 +344,11 @@ type root_map = HashMap<root_map_key, RootInfo>;
 // if you have an expression `x.f` and x has type ~@T, we could add an
 // entry {id:x, derefs:0} to refer to `x` itself, `{id:x, derefs:1}`
 // to refer to the deref of the unique pointer, and so on.
-type root_map_key = {id: ast::node_id, derefs: uint};
+#[deriving_eq]
+struct root_map_key {
+    id: ast::node_id,
+    derefs: uint
+}
 
 // set of ids of local vars / formal arguments that are modified / moved.
 // this is used in trans for optimization purposes.
@@ -411,13 +415,10 @@ impl bckerr_code : cmp::Eq {
 
 // Combination of an error code and the categorization of the expression
 // that caused it
-type bckerr = {cmt: cmt, code: bckerr_code};
-
-impl bckerr : cmp::Eq {
-    pure fn eq(&self, other: &bckerr) -> bool {
-        (*self).cmt == (*other).cmt && (*self).code == (*other).code
-    }
-    pure fn ne(&self, other: &bckerr) -> bool { !(*self).eq(other) }
+#[deriving_eq]
+struct bckerr {
+    cmt: cmt,
+    code: bckerr_code
 }
 
 // shorthand for something that fails with `bckerr` or succeeds with `T`
@@ -446,15 +447,6 @@ fn save_and_restore<T:Copy,U>(save_and_restore_t: &mut T, f: fn() -> U) -> U {
 
 /// Creates and returns a new root_map
 
-impl root_map_key : cmp::Eq {
-    pure fn eq(&self, other: &root_map_key) -> bool {
-        (*self).id == (*other).id && (*self).derefs == (*other).derefs
-    }
-    pure fn ne(&self, other: &root_map_key) -> bool {
-        ! ((*self) == (*other))
-    }
-}
-
 impl root_map_key : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f);
@@ -501,7 +493,7 @@ impl borrowck_ctxt {
     }
 
     fn cat_discr(cmt: cmt, match_id: ast::node_id) -> cmt {
-        return @{cat:cat_discr(cmt, match_id),.. *cmt};
+        return @cmt_ { cat: cat_discr(cmt, match_id),.. *cmt };
     }
 
     fn mc_ctxt() -> mem_categorization_ctxt {
diff --git a/src/librustc/middle/borrowck/preserve.rs b/src/librustc/middle/borrowck/preserve.rs
index 5916588a9a2..5edfd294d84 100644
--- a/src/librustc/middle/borrowck/preserve.rs
+++ b/src/librustc/middle/borrowck/preserve.rs
@@ -18,7 +18,7 @@ use core::prelude::*;
 use middle::borrowck::{RootInfo, bckerr, bckerr_code, bckres, borrowck_ctxt};
 use middle::borrowck::{cmt, err_mut_uniq, err_mut_variant};
 use middle::borrowck::{err_out_of_root_scope, err_out_of_scope};
-use middle::borrowck::{err_root_not_permitted};
+use middle::borrowck::{err_root_not_permitted, root_map_key};
 use middle::mem_categorization::{cat_arg, cat_binding, cat_comp, cat_deref};
 use middle::mem_categorization::{cat_discr, cat_local, cat_self, cat_special};
 use middle::mem_categorization::{cat_stack_upvar, comp_field, comp_index};
@@ -291,7 +291,7 @@ priv impl &preserve_ctxt {
           Ok(pc_ok) => {
             match cmt_base.mutbl {
               m_mutbl | m_const => {
-                Ok(pc_if_pure({cmt:cmt, code:code}))
+                Ok(pc_if_pure(bckerr { cmt: cmt, code: code }))
               }
               m_imm => {
                 Ok(pc_ok)
@@ -318,8 +318,10 @@ priv impl &preserve_ctxt {
         if self.bccx.is_subregion_of(self.scope_region, scope_ub) {
             Ok(pc_ok)
         } else {
-            Err({cmt:cmt, code:err_out_of_scope(scope_ub,
-                                                self.scope_region)})
+            Err(bckerr {
+                cmt:cmt,
+                code:err_out_of_scope(scope_ub, self.scope_region)
+            })
         }
     }
 
@@ -345,7 +347,7 @@ priv impl &preserve_ctxt {
             // would be sort of pointless to avoid rooting the inner
             // box by rooting an outer box, as it would just keep more
             // memory live than necessary, so we set root_ub to none.
-            return Err({cmt:cmt, code:err_root_not_permitted});
+            return Err(bckerr { cmt: cmt, code: err_root_not_permitted });
         }
 
         let root_region = ty::re_scope(self.root_ub);
@@ -359,7 +361,7 @@ priv impl &preserve_ctxt {
                    derefs, scope_id, self.root_ub);
             if self.bccx.is_subregion_of(self.scope_region, root_region) {
                 debug!("Elected to root");
-                let rk = {id: base.id, derefs: derefs};
+                let rk = root_map_key { id: base.id, derefs: derefs };
                 // This code could potentially lead cause boxes to be frozen
                 // for longer than necessarily at runtime. It prevents an
                 // ICE in trans; the fundamental problem is that it's hard
@@ -389,17 +391,20 @@ priv impl &preserve_ctxt {
                 return Ok(pc_ok);
             } else {
                 debug!("Unable to root");
-                return Err({cmt:cmt,
-                            code:err_out_of_root_scope(root_region,
-                                                       self.scope_region)});
+                return Err(bckerr {
+                    cmt: cmt,
+                    code: err_out_of_root_scope(root_region,
+                                                self.scope_region)
+                });
             }
           }
 
           // we won't be able to root long enough
           _ => {
-              return Err({cmt:cmt,
-                          code:err_out_of_root_scope(root_region,
-                                                     self.scope_region)});
+              return Err(bckerr {
+                cmt:cmt,
+                code:err_out_of_root_scope(root_region, self.scope_region)
+              });
           }
 
         }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 7c1e96e5c0e..9ea03440ad6 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -113,27 +113,18 @@ enum special_kind {
 // which the value is stored.
 //
 // note: cmt stands for "categorized mutable type".
-type cmt_ = {id: ast::node_id,        // id of expr/pat producing this value
-             span: span,              // span of same expr/pat
-             cat: categorization,     // categorization of expr
-             lp: Option<@loan_path>,  // loan path for expr, if any
-             mutbl: ast::mutability,  // mutability of expr as lvalue
-             ty: ty::t};              // type of the expr
+#[deriving_eq]
+struct cmt_ {
+    id: ast::node_id,        // id of expr/pat producing this value
+    span: span,              // span of same expr/pat
+    cat: categorization,     // categorization of expr
+    lp: Option<@loan_path>,  // loan path for expr, if any
+    mutbl: ast::mutability,  // mutability of expr as lvalue
+    ty: ty::t                // type of the expr
+}
 
 type cmt = @cmt_;
 
-impl cmt_ : cmp::Eq {
-    pure fn eq(&self, other: &cmt_) -> bool {
-        (*self).id == (*other).id &&
-        (*self).span == (*other).span &&
-        (*self).cat == (*other).cat &&
-        (*self).lp == (*other).lp &&
-        (*self).mutbl == (*other).mutbl &&
-        (*self).ty == (*other).ty
-    }
-    pure fn ne(&self, other: &cmt_) -> bool { !(*self).eq(other) }
-}
-
 // a loan path is like a category, but it exists only when the data is
 // interior to the stack frame.  loan paths are used as the key to a
 // map indicating what is borrowed at any point in time.
@@ -423,9 +414,14 @@ impl &mem_categorization_ctxt {
           ast::def_ty_param(*) | ast::def_struct(*) |
           ast::def_typaram_binder(*) | ast::def_region(_) |
           ast::def_label(_) | ast::def_self_ty(*) => {
-            @{id:id, span:span,
-              cat:cat_special(sk_static_item), lp:None,
-              mutbl:m_imm, ty:expr_ty}
+            @cmt_ {
+                id:id,
+                span:span,
+                cat:cat_special(sk_static_item),
+                lp:None,
+                mutbl:m_imm,
+                ty:expr_ty
+            }
           }
 
           ast::def_arg(vid, mode, mutbl) => {
@@ -451,9 +447,14 @@ impl &mem_categorization_ctxt {
                 None
               }
             };
-            @{id:id, span:span,
-              cat:cat_arg(vid), lp:lp,
-              mutbl:m, ty:expr_ty}
+            @cmt_ {
+                id:id,
+                span:span,
+                cat:cat_arg(vid),
+                lp:lp,
+                mutbl:m,
+                ty:expr_ty
+            }
           }
 
           ast::def_self(self_id, is_implicit) => {
@@ -466,9 +467,14 @@ impl &mem_categorization_ctxt {
                 loan_path = Some(@lp_self);
             };
 
-            @{id:id, span:span,
-              cat:cat, lp:loan_path,
-              mutbl:m_imm, ty:expr_ty}
+            @cmt_ {
+                id:id,
+                span:span,
+                cat:cat,
+                lp:loan_path,
+                mutbl:m_imm,
+                ty:expr_ty
+            }
           }
 
           ast::def_upvar(_, inner, fn_node_id, _) => {
@@ -477,15 +483,25 @@ impl &mem_categorization_ctxt {
             match proto {
                 ast::ProtoBorrowed => {
                     let upcmt = self.cat_def(id, span, expr_ty, *inner);
-                    @{id:id, span:span,
-                      cat:cat_stack_upvar(upcmt), lp:upcmt.lp,
-                      mutbl:upcmt.mutbl, ty:upcmt.ty}
+                    @cmt_ {
+                        id:id,
+                        span:span,
+                        cat:cat_stack_upvar(upcmt),
+                        lp:upcmt.lp,
+                        mutbl:upcmt.mutbl,
+                        ty:upcmt.ty
+                    }
                 }
                 ast::ProtoUniq | ast::ProtoBox => {
                     // FIXME #2152 allow mutation of moved upvars
-                    @{id:id, span:span,
-                      cat:cat_special(sk_heap_upvar), lp:None,
-                      mutbl:m_imm, ty:expr_ty}
+                    @cmt_ {
+                        id:id,
+                        span:span,
+                        cat:cat_special(sk_heap_upvar),
+                        lp:None,
+                        mutbl:m_imm,
+                        ty:expr_ty
+                    }
                 }
                 ast::ProtoBare => {
                     self.tcx.sess.span_bug(
@@ -497,16 +513,26 @@ impl &mem_categorization_ctxt {
 
           ast::def_local(vid, mutbl) => {
             let m = if mutbl {m_mutbl} else {m_imm};
-            @{id:id, span:span,
-              cat:cat_local(vid), lp:Some(@lp_local(vid)),
-              mutbl:m, ty:expr_ty}
+            @cmt_ {
+                id:id,
+                span:span,
+                cat:cat_local(vid),
+                lp:Some(@lp_local(vid)),
+                mutbl:m,
+                ty:expr_ty
+            }
           }
 
           ast::def_binding(vid, _) => {
             // by-value/by-ref bindings are local variables
-            @{id:id, span:span,
-              cat:cat_local(vid), lp:Some(@lp_local(vid)),
-              mutbl:m_imm, ty:expr_ty}
+            @cmt_ {
+                id:id,
+                span:span,
+                cat:cat_local(vid),
+                lp:Some(@lp_local(vid)),
+                mutbl:m_imm,
+                ty:expr_ty
+            }
           }
         }
     }
@@ -514,17 +540,25 @@ impl &mem_categorization_ctxt {
     fn cat_variant<N: ast_node>(arg: N,
                                 enum_did: ast::def_id,
                                 cmt: cmt) -> cmt {
-        @{id: arg.id(), span: arg.span(),
-          cat: cat_comp(cmt, comp_variant(enum_did)),
-          lp: cmt.lp.map(|l| @lp_comp(*l, comp_variant(enum_did)) ),
-          mutbl: cmt.mutbl, // imm iff in an immutable context
-          ty: self.tcx.ty(arg)}
+        @cmt_ {
+            id: arg.id(),
+            span: arg.span(),
+            cat: cat_comp(cmt, comp_variant(enum_did)),
+            lp: cmt.lp.map(|l| @lp_comp(*l, comp_variant(enum_did)) ),
+            mutbl: cmt.mutbl, // imm iff in an immutable context
+            ty: self.tcx.ty(arg)
+        }
     }
 
     fn cat_rvalue<N: ast_node>(elt: N, expr_ty: ty::t) -> cmt {
-        @{id:elt.id(), span:elt.span(),
-          cat:cat_rvalue, lp:None,
-          mutbl:m_imm, ty:expr_ty}
+        @cmt_ {
+            id:elt.id(),
+            span:elt.span(),
+            cat:cat_rvalue,
+            lp:None,
+            mutbl:m_imm,
+            ty:expr_ty
+        }
     }
 
     /// inherited mutability: used in cases where the mutability of a
@@ -559,9 +593,14 @@ impl &mem_categorization_ctxt {
         let m = self.inherited_mutability(base_cmt.mutbl, f_mutbl);
         let f_comp = comp_field(f_name, f_mutbl);
         let lp = base_cmt.lp.map(|lp| @lp_comp(*lp, f_comp) );
-        @{id: node.id(), span: node.span(),
-          cat: cat_comp(base_cmt, f_comp), lp:lp,
-          mutbl: m, ty: self.tcx.ty(node)}
+        @cmt_ {
+            id: node.id(),
+            span: node.span(),
+            cat: cat_comp(base_cmt, f_comp),
+            lp:lp,
+            mutbl: m,
+            ty: self.tcx.ty(node)
+        }
     }
 
     fn cat_deref_fn<N:ast_node>(node: N,
@@ -628,17 +667,27 @@ impl &mem_categorization_ctxt {
                     }
                 };
 
-                @{id:node.id(), span:node.span(),
-                  cat:cat_deref(base_cmt, deref_cnt, ptr), lp:lp,
-                  mutbl:m, ty:mt.ty}
+                @cmt_ {
+                    id:node.id(),
+                    span:node.span(),
+                    cat:cat_deref(base_cmt, deref_cnt, ptr),
+                    lp:lp,
+                    mutbl:m,
+                    ty:mt.ty
+                }
             }
 
             deref_comp(comp) => {
                 let lp = base_cmt.lp.map(|l| @lp_comp(*l, comp) );
                 let m = self.inherited_mutability(base_cmt.mutbl, mt.mutbl);
-                @{id:node.id(), span:node.span(),
-                  cat:cat_comp(base_cmt, comp), lp:lp,
-                  mutbl:m, ty:mt.ty}
+                @cmt_ {
+                    id:node.id(),
+                    span:node.span(),
+                    cat:cat_comp(base_cmt, comp),
+                    lp:lp,
+                    mutbl:m,
+                    ty:mt.ty
+                }
             }
         }
     }
@@ -675,9 +724,14 @@ impl &mem_categorization_ctxt {
             };
 
             // (c) the deref is explicit in the resulting cmt
-            let deref_cmt = @{id:elt.id(), span:elt.span(),
-              cat:cat_deref(base_cmt, 0u, ptr), lp:deref_lp,
-              mutbl:m, ty:mt.ty};
+            let deref_cmt = @cmt_ {
+                id:elt.id(),
+                span:elt.span(),
+                cat:cat_deref(base_cmt, 0u, ptr),
+                lp:deref_lp,
+                mutbl:m,
+                ty:mt.ty
+            };
 
             comp(elt, deref_cmt, base_cmt.ty, m, mt.ty)
           }
@@ -695,32 +749,48 @@ impl &mem_categorization_ctxt {
         {
             let comp = comp_index(vect, mutbl);
             let index_lp = of_cmt.lp.map(|lp| @lp_comp(*lp, comp) );
-            @{id:elt.id(), span:elt.span(),
-              cat:cat_comp(of_cmt, comp), lp:index_lp,
-              mutbl:mutbl, ty:ty}
+            @cmt_ {
+                id:elt.id(),
+                span:elt.span(),
+                cat:cat_comp(of_cmt, comp),
+                lp:index_lp,
+                mutbl:mutbl,
+                ty:ty
+            }
         }
     }
 
     fn cat_tuple_elt<N: ast_node>(elt: N, cmt: cmt) -> cmt {
-        @{id: elt.id(), span: elt.span(),
-          cat: cat_comp(cmt, comp_tuple),
-          lp: cmt.lp.map(|l| @lp_comp(*l, comp_tuple) ),
-          mutbl: cmt.mutbl, // imm iff in an immutable context
-          ty: self.tcx.ty(elt)}
+        @cmt_ {
+            id: elt.id(),
+            span: elt.span(),
+            cat: cat_comp(cmt, comp_tuple),
+            lp: cmt.lp.map(|l| @lp_comp(*l, comp_tuple) ),
+            mutbl: cmt.mutbl, // imm iff in an immutable context
+            ty: self.tcx.ty(elt)
+        }
     }
 
     fn cat_anon_struct_field<N: ast_node>(elt: N, cmt: cmt) -> cmt {
-        @{id: elt.id(), span: elt.span(),
-          cat: cat_comp(cmt, comp_anon_field),
-          lp: cmt.lp.map(|l| @lp_comp(*l, comp_anon_field)),
-          mutbl: cmt.mutbl, // imm iff in an immutable context
-          ty: self.tcx.ty(elt)}
+        @cmt_ {
+            id: elt.id(),
+            span: elt.span(),
+            cat: cat_comp(cmt, comp_anon_field),
+            lp: cmt.lp.map(|l| @lp_comp(*l, comp_anon_field)),
+            mutbl: cmt.mutbl, // imm iff in an immutable context
+            ty: self.tcx.ty(elt)
+        }
     }
 
     fn cat_method_ref(expr: @ast::expr, expr_ty: ty::t) -> cmt {
-        @{id:expr.id, span:expr.span,
-          cat:cat_special(sk_method), lp:None,
-          mutbl:m_imm, ty:expr_ty}
+        @cmt_ {
+            id:expr.id,
+            span:expr.span,
+            cat:cat_special(sk_method),
+            lp:None,
+            mutbl:m_imm,
+            ty:expr_ty
+        }
     }
 
     fn cat_pattern(cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index dd355f6df70..ac3a16b07a0 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -397,17 +397,15 @@ fn resolve_crate(sess: Session, def_map: resolve::DefMap,
 // dependencies until a fixed point is reached.
 
 type region_paramd_items = HashMap<ast::node_id, region_variance>;
-type region_dep = {ambient_variance: region_variance, id: ast::node_id};
-type dep_map = HashMap<ast::node_id, @DVec<region_dep>>;
 
-impl region_dep : cmp::Eq {
-    pure fn eq(&self, other: &region_dep) -> bool {
-        (*self).ambient_variance == (*other).ambient_variance &&
-        (*self).id == (*other).id
-    }
-    pure fn ne(&self, other: &region_dep) -> bool { !(*self).eq(other) }
+#[deriving_eq]
+struct region_dep {
+    ambient_variance: region_variance,
+    id: ast::node_id
 }
 
+type dep_map = HashMap<ast::node_id, @DVec<region_dep>>;
+
 type determine_rp_ctxt_ = {
     sess: Session,
     ast_map: ast_map::map,
@@ -511,7 +509,10 @@ impl determine_rp_ctxt {
                 vec
             }
         };
-        let dep = {ambient_variance: self.ambient_variance, id: self.item_id};
+        let dep = region_dep {
+            ambient_variance: self.ambient_variance,
+            id: self.item_id
+        };
         if !vec.contains(&dep) { vec.push(dep); }
     }
 
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index db266464860..084f0ba421e 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -910,7 +910,8 @@ fn root_pats_as_necessary(bcx: block,
     for vec::each(m) |br| {
         let pat_id = br.pats[col].id;
 
-        match bcx.ccx().maps.root_map.find({id:pat_id, derefs:0u}) {
+        let key = root_map_key {id: pat_id, derefs: 0u };
+        match bcx.ccx().maps.root_map.find(key) {
             None => (),
             Some(root_info) => {
                 // Note: the scope_id will always be the id of the match.  See
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 3bf1547a7d9..f4814b4657b 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -61,6 +61,7 @@ use middle::trans::reachable;
 use middle::trans::shape::*;
 use middle::trans::tvec;
 use middle::trans::type_of::*;
+use middle::ty::arg;
 use util::common::indenter;
 use util::ppaux::{ty_to_str, ty_to_short_str};
 use util::ppaux;
@@ -2198,9 +2199,12 @@ fn create_main_wrapper(ccx: @crate_ctxt, _sp: span, main_llfn: ValueRef) {
     fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef) -> ValueRef {
         let unit_ty = ty::mk_estr(ccx.tcx, ty::vstore_uniq);
         let vecarg_ty: ty::arg =
-            {mode: ast::expl(ast::by_val),
-             ty: ty::mk_evec(ccx.tcx, ty::mt {ty: unit_ty, mutbl: ast::m_imm},
-                             ty::vstore_uniq)};
+            arg {
+                mode: ast::expl(ast::by_val),
+                ty: ty::mk_evec(ccx.tcx,
+                    ty::mt {ty: unit_ty, mutbl: ast::m_imm},
+                    ty::vstore_uniq)
+            };
         let nt = ty::mk_nil(ccx.tcx);
         let llfty = type_of_fn(ccx, ~[vecarg_ty], nt);
         let llfdecl = decl_fn(ccx.llmod, ~"_rust_main",
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 0128876a898..3babfbd8285 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -39,6 +39,7 @@ use middle::trans::reachable;
 use middle::trans::shape;
 use middle::trans::type_of;
 use middle::trans::type_use;
+use middle::ty::substs;
 use middle::ty;
 use middle::typeck;
 use util::ppaux::{expr_repr, ty_to_str};
@@ -1459,9 +1460,11 @@ fn find_vtable(tcx: ty::ctxt, ps: &param_substs,
 }
 
 fn dummy_substs(+tps: ~[ty::t]) -> ty::substs {
-    {self_r: Some(ty::re_bound(ty::br_self)),
-     self_ty: None,
-     tps: tps}
+    substs {
+        self_r: Some(ty::re_bound(ty::br_self)),
+        self_ty: None,
+        tps: tps
+    }
 }
 
 fn struct_field(index: uint) -> [uint * 3] {
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index 8c024b364c3..94145be2a1e 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -98,7 +98,7 @@
 use core::prelude::*;
 
 use lib::llvm::ValueRef;
-use middle::borrowck::RootInfo;
+use middle::borrowck::{RootInfo, root_map_key};
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::common::*;
@@ -652,7 +652,7 @@ impl Datum {
         // root the autoderef'd value, if necessary:
         //
         // (Note: root'd values are always boxes)
-        let key = {id:expr_id, derefs:derefs};
+        let key = root_map_key { id: expr_id, derefs: derefs };
         let bcx = match ccx.maps.root_map.find(key) {
             None => bcx,
             Some(root_info) => self.root(bcx, root_info)
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index ea9ddc2e5d0..24d8e94abbd 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -114,6 +114,7 @@ lvalues are *never* stored by value.
 use core::prelude::*;
 
 use lib::llvm::ValueRef;
+use middle::borrowck::root_map_key;
 use middle::resolve;
 use middle::trans::base::*;
 use middle::trans::callee::{AutorefArg, DoAutorefArg, DontAutorefArg};
@@ -757,7 +758,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
     // If the lvalue must remain rooted, create a scratch datum, copy
     // the lvalue in there, and then arrange for it to be cleaned up
     // at the end of the scope with id `scope_id`:
-    let root_key = {id:expr.id, derefs:0u};
+    let root_key = root_map_key { id: expr.id, derefs: 0u };
     for bcx.ccx().maps.root_map.find(root_key).each |&root_info| {
         bcx = unrooted_datum.root(bcx, root_info);
     }
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index ac641222b3c..317a64ea528 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -31,7 +31,7 @@ use middle::trans::machine;
 use middle::trans::shape;
 use middle::trans::type_of::*;
 use middle::trans::type_of;
-use middle::ty::{FnTyBase, FnMeta, FnSig};
+use middle::ty::{FnTyBase, FnMeta, FnSig, arg};
 use util::ppaux::ty_to_str;
 
 use core::libc::c_uint;
@@ -546,8 +546,8 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
                               onceness: ast::Many,
                               region: ty::re_bound(ty::br_anon(0)),
                               bounds: @~[]},
-                sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
-                                       ty: star_u8}],
+                sig: FnSig {inputs: ~[arg {mode: ast::expl(ast::by_val),
+                                           ty: star_u8}],
                             output: ty::mk_nil(bcx.tcx())}
             });
             let datum = Datum {val: get_param(decl, first_real_arg),
diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs
index 5c0498d5a14..7af3b7a0683 100644
--- a/src/librustc/middle/trans/machine.rs
+++ b/src/librustc/middle/trans/machine.rs
@@ -13,6 +13,7 @@
 
 use middle::trans::common::*;
 use middle::trans::type_of;
+use middle::ty::field;
 use middle::ty;
 
 use syntax::parse::token::special_idents;
@@ -44,13 +45,17 @@ pub fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t {
           ty::ty_struct(did, ref substs) => {
             let simpl_fields = (if ty::ty_dtor(tcx, did).is_present() {
                 // remember the drop flag
-                  ~[{ident: special_idents::dtor,
-                     mt: ty::mt {ty: ty::mk_u8(tcx), mutbl: ast::m_mutbl}}] }
+                  ~[field {
+                    ident: special_idents::dtor,
+                    mt: ty::mt {ty: ty::mk_u8(tcx), mutbl: ast::m_mutbl}
+                   }] }
                 else { ~[] }) +
                 do ty::lookup_struct_fields(tcx, did).map |f| {
                  let t = ty::lookup_field_type(tcx, did, f.id, substs);
-                 {ident: f.ident,
-                  mt: ty::mt {ty: simplify_type(tcx, t), mutbl: ast::m_const}}
+                 field {
+                    ident: f.ident,
+                    mt: ty::mt {ty: simplify_type(tcx, t), mutbl: ast::m_const
+                 }}
             };
             ty::mk_rec(tcx, simpl_fields)
           }
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 7eccf97f76c..a90c25abf3d 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -28,6 +28,7 @@ use middle::trans::glue;
 use middle::trans::inline;
 use middle::trans::monomorphize;
 use middle::trans::type_of::*;
+use middle::ty::arg;
 use middle::typeck;
 use util::ppaux::{ty_to_str, tys_to_str};
 
@@ -154,8 +155,10 @@ fn trans_self_arg(bcx: block,
     let mut temp_cleanups = ~[];
 
     // Compute the mode and type of self.
-    let self_arg = {mode: mentry.self_arg.mode,
-                    ty: monomorphize_type(bcx, mentry.self_arg.ty)};
+    let self_arg = arg {
+        mode: mentry.self_arg.mode,
+        ty: monomorphize_type(bcx, mentry.self_arg.ty)
+    };
 
     let result = trans_arg_expr(bcx, self_arg, base,
                                 &mut temp_cleanups, None, DontAutorefArg);
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index a839de967ca..002e04ca475 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -242,14 +242,23 @@ export AutoRefKind, AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn;
 export iter_bound_traits_and_supertraits;
 export count_traits_and_supertraits;
 export IntVarValue, IntType, UintType;
+export creader_cache_key;
 
 // Data types
 
 // Note: after typeck, you should use resolved_mode() to convert this mode
 // into an rmode, which will take into account the results of mode inference.
-type arg = {mode: ast::mode, ty: t};
+#[deriving_eq]
+struct arg {
+    mode: ast::mode,
+    ty: t
+}
 
-type field = {ident: ast::ident, mt: mt};
+#[deriving_eq]
+struct field {
+    ident: ast::ident,
+    mt: mt
+}
 
 type param_bounds = @~[param_bound];
 
@@ -292,35 +301,38 @@ pub enum ValueMode {
 
 // Contains information needed to resolve types and (in the future) look up
 // the types of AST nodes.
-type creader_cache_key = {cnum: int, pos: uint, len: uint};
-type creader_cache = HashMap<creader_cache_key, t>;
-
-impl creader_cache_key : cmp::Eq {
-    pure fn eq(&self, other: &creader_cache_key) -> bool {
-        (*self).cnum == (*other).cnum &&
-            (*self).pos == (*other).pos &&
-            (*self).len == (*other).len
-    }
-    pure fn ne(&self, other: &creader_cache_key) -> bool {
-        !((*self) == (*other))
-    }
+#[deriving_eq]
+struct creader_cache_key {
+    cnum: int,
+    pos: uint,
+    len: uint
 }
 
+type creader_cache = HashMap<creader_cache_key, t>;
+
 impl creader_cache_key : to_bytes::IterBytes {
     pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f);
     }
 }
 
-type intern_key = {sty: *sty, o_def_id: Option<ast::def_id>};
+struct intern_key {
+    sty: *sty,
+    o_def_id: Option<ast::def_id>
+}
 
+// NB: Do not replace this with #[deriving_eq]. The automatically-derived
+// implementation will not recurse through sty and you will get stack
+// exhaustion.
 impl intern_key : cmp::Eq {
     pure fn eq(&self, other: &intern_key) -> bool {
         unsafe {
             *self.sty == *other.sty && self.o_def_id == other.o_def_id
         }
     }
-    pure fn ne(&self, other: &intern_key) -> bool { !(*self).eq(other) }
+    pure fn ne(&self, other: &intern_key) -> bool {
+        !self.eq(other)
+    }
 }
 
 impl intern_key : to_bytes::IterBytes {
@@ -570,13 +582,10 @@ impl<M: to_bytes::IterBytes> FnTyBase<M> : to_bytes::IterBytes {
 
 type FnTy = FnTyBase<FnMeta>;
 
-type param_ty = {idx: uint, def_id: def_id};
-
-impl param_ty : cmp::Eq {
-    pure fn eq(&self, other: &param_ty) -> bool {
-        (*self).idx == (*other).idx && (*self).def_id == (*other).def_id
-    }
-    pure fn ne(&self, other: &param_ty) -> bool { !(*self).eq(other) }
+#[deriving_eq]
+struct param_ty {
+    idx: uint,
+    def_id: def_id
 }
 
 impl param_ty : to_bytes::IterBytes {
@@ -662,11 +671,12 @@ type opt_region = Option<Region>;
  * - `self_ty` is the type to which `self` should be remapped, if any.  The
  *   `self` type is rather funny in that it can only appear on traits and is
  *   always substituted away to the implementing type for a trait. */
-type substs = {
+#[deriving_eq]
+struct substs {
     self_r: opt_region,
     self_ty: Option<ty::t>,
     tps: ~[t]
-};
+}
 
 // NB: If you change this, you'll probably want to change the corresponding
 // AST structure in libsyntax/ast.rs as well.
@@ -1051,7 +1061,7 @@ fn mk_t(cx: ctxt, +st: sty) -> t { mk_t_with_id(cx, st, None) }
 // Interns a type/name combination, stores the resulting box in cx.interner,
 // and returns the box as cast to an unsafe ptr (see comments for t above).
 fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option<ast::def_id>) -> t {
-    let key = {sty: to_unsafe_ptr(&st), o_def_id: o_def_id};
+    let key = intern_key { sty: to_unsafe_ptr(&st), o_def_id: o_def_id };
     match cx.interner.find(key) {
       Some(t) => unsafe { return cast::reinterpret_cast(&t); },
       _ => ()
@@ -1110,7 +1120,7 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option<ast::def_id>) -> t {
 
     let t = @{sty: move st, id: cx.next_id, flags: flags, o_def_id: o_def_id};
 
-    let key = {sty: to_unsafe_ptr(&t.sty), o_def_id: o_def_id};
+    let key = intern_key {sty: to_unsafe_ptr(&t.sty), o_def_id: o_def_id};
     cx.interner.insert(move key, t);
 
     cx.next_id += 1u;
@@ -1243,7 +1253,7 @@ fn mk_infer(cx: ctxt, +it: InferTy) -> t { mk_t(cx, ty_infer(it)) }
 fn mk_self(cx: ctxt) -> t { mk_t(cx, ty_self) }
 
 fn mk_param(cx: ctxt, n: uint, k: def_id) -> t {
-    mk_t(cx, ty_param({idx: n, def_id: k}))
+    mk_t(cx, ty_param(param_ty { idx: n, def_id: k }))
 }
 
 fn mk_type(cx: ctxt) -> t { mk_t(cx, ty_type) }
@@ -1359,7 +1369,7 @@ fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: fn(t) -> t) -> t {
 
 fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig {
     let args = do sig.inputs.map |arg| {
-        { mode: arg.mode, ty: fldop(arg.ty) }
+        arg { mode: arg.mode, ty: fldop(arg.ty) }
     };
 
     FnSig {
@@ -1370,9 +1380,9 @@ fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig {
 
 fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
     fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs {
-        {self_r: substs.self_r,
-         self_ty: substs.self_ty.map(|t| fldop(*t)),
-         tps: substs.tps.map(|t| fldop(*t))}
+        substs {self_r: substs.self_r,
+                self_ty: substs.self_ty.map(|t| fldop(*t)),
+                tps: substs.tps.map(|t| fldop(*t))}
     }
 
     match /*bad*/copy *sty {
@@ -1400,8 +1410,8 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
         ty_rec(fields) => {
             let new_fields = do vec::map(fields) |fl| {
                 let new_ty = fldop(fl.mt.ty);
-                let new_mt = mt {ty: new_ty, mutbl: fl.mt.mutbl};
-                {ident: fl.ident, mt: new_mt}
+                let new_mt = mt { ty: new_ty, mutbl: fl.mt.mutbl };
+                field { ident: fl.ident, mt: new_mt }
             };
             ty_rec(new_fields)
         }
@@ -1458,11 +1468,13 @@ fn fold_regions_and_ty(
     fn fold_substs(
         substs: &substs,
         fldr: fn(r: Region) -> Region,
-        fldt: fn(t: t) -> t) -> substs
-    {
-        {self_r: substs.self_r.map(|r| fldr(*r)),
-         self_ty: substs.self_ty.map(|t| fldt(*t)),
-         tps: substs.tps.map(|t| fldt(*t))}
+        fldt: fn(t: t) -> t)
+     -> substs {
+        substs {
+            self_r: substs.self_r.map(|r| fldr(*r)),
+            self_ty: substs.self_ty.map(|t| fldt(*t)),
+            tps: substs.tps.map(|t| fldt(*t))
+        }
     }
 
     let tb = ty::get(ty);
@@ -1678,7 +1690,7 @@ fn subst(cx: ctxt,
 // Performs substitutions on a set of substitutions (result = sup(sub)) to
 // yield a new set of substitutions. This is used in trait inheritance.
 fn subst_substs(cx: ctxt, sup: &substs, sub: &substs) -> substs {
-    {
+    substs {
         self_r: sup.self_r,
         self_ty: sup.self_ty.map(|typ| subst(cx, sub, *typ)),
         tps: sup.tps.map(|typ| subst(cx, sub, *typ))
@@ -4159,7 +4171,7 @@ fn struct_item_fields(cx:ctxt,
     do lookup_struct_fields(cx, did).map |f| {
        // consider all instance vars mut, because the
        // constructor may mutate all vars
-       {
+       field {
            ident: f.ident,
             mt: mt {
                 ty: lookup_field_type(cx, did, f.id, substs),
@@ -4288,9 +4300,11 @@ fn normalize_ty(cx: ctxt, t: t) -> t {
                 Some(_) =>
                     // Use re_static since trans doesn't care about regions
                     mk_enum(cx, did,
-                     {self_r: Some(ty::re_static),
-                      self_ty: None,
-                      tps: /*bad*/copy (*r).tps}),
+                     substs {
+                        self_r: Some(ty::re_static),
+                        self_ty: None,
+                        tps: /*bad*/copy (*r).tps
+                     }),
                 None =>
                     t
             },
@@ -4299,9 +4313,9 @@ fn normalize_ty(cx: ctxt, t: t) -> t {
             match (*r).self_r {
               Some(_) =>
                 // Ditto.
-                mk_struct(cx, did, {self_r: Some(ty::re_static),
-                                    self_ty: None,
-                                    tps: /*bad*/copy (*r).tps}),
+                mk_struct(cx, did, substs {self_r: Some(ty::re_static),
+                                           self_ty: None,
+                                           tps: /*bad*/copy (*r).tps}),
               None =>
                 t
             },
@@ -4421,20 +4435,6 @@ impl mt : cmp::Eq {
     pure fn ne(&self, other: &mt) -> bool { !(*self).eq(other) }
 }
 
-impl arg : cmp::Eq {
-    pure fn eq(&self, other: &arg) -> bool {
-        (*self).mode == (*other).mode && (*self).ty == (*other).ty
-    }
-    pure fn ne(&self, other: &arg) -> bool { !(*self).eq(other) }
-}
-
-impl field : cmp::Eq {
-    pure fn eq(&self, other: &field) -> bool {
-        (*self).ident == (*other).ident && (*self).mt == (*other).mt
-    }
-    pure fn ne(&self, other: &field) -> bool { !(*self).eq(other) }
-}
-
 impl vstore : cmp::Eq {
     pure fn eq(&self, other: &vstore) -> bool {
         match (*self) {
@@ -4543,15 +4543,6 @@ impl bound_region : cmp::Eq {
     pure fn ne(&self, other: &bound_region) -> bool { !(*self).eq(other) }
 }
 
-impl substs : cmp::Eq {
-    pure fn eq(&self, other: &substs) -> bool {
-        (*self).self_r == (*other).self_r &&
-        (*self).self_ty == (*other).self_ty &&
-        (*self).tps == (*other).tps
-    }
-    pure fn ne(&self, other: &substs) -> bool { !(*self).eq(other) }
-}
-
 impl sty : cmp::Eq {
     pure fn eq(&self, other: &sty) -> bool {
         match (/*bad*/copy *self) {
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 7e1c5f54134..e845904956d 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -55,7 +55,8 @@
 use core::prelude::*;
 
 use middle::pat_util::pat_id_map;
-use middle::ty::{FnTyBase, FnMeta, FnSig, ty_param_substs_and_ty};
+use middle::ty::{FnTyBase, FnMeta, FnSig, arg, field, substs};
+use middle::ty::{ty_param_substs_and_ty};
 use middle::ty;
 use middle::typeck::check::fn_ctxt;
 use middle::typeck::collect;
@@ -151,7 +152,7 @@ fn ast_path_to_substs_and_ty<AC: ast_conv, RS: region_scope Copy Durable>(
     }
     let tps = path.types.map(|a_t| ast_ty_to_ty(self, rscope, *a_t));
 
-    let substs = {self_r:self_r, self_ty:None, tps:tps};
+    let substs = substs {self_r:self_r, self_ty:None, tps:tps};
     let ty = ty::subst(tcx, &substs, decl_ty);
     {substs: substs, ty: ty}
 }
@@ -315,7 +316,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope Copy Durable>(
       ast::ty_rec(ref fields) => {
         let flds = do (*fields).map |f| {
             let tm = ast_mt_to_mt(self, rscope, f.node.mt);
-            {ident: f.node.ident, mt: tm}
+            field {ident: f.node.ident, mt: tm}
         };
         ty::mk_rec(tcx, flds)
       }
@@ -447,7 +448,7 @@ fn ty_of_arg<AC: ast_conv, RS: region_scope Copy Durable>(
         }
     };
 
-    {mode: mode, ty: ty}
+    arg {mode: mode, ty: ty}
 }
 
 type expected_tys = Option<{inputs: ~[ty::arg],
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 86f58edd6c8..543adbd53aa 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -295,7 +295,11 @@ impl LookupContext {
                     let self_did = self.fcx.self_info.expect(
                         ~"self_impl_def_id is undefined (`self` may not \
                           be in scope here").def_id;
-                    let substs = {self_r: None, self_ty: None, tps: ~[]};
+                    let substs = substs {
+                        self_r: None,
+                        self_ty: None,
+                        tps: ~[]
+                    };
                     self.push_inherent_candidates_from_self(
                         self_ty, self_did, &substs);
                 }
@@ -392,7 +396,10 @@ impl LookupContext {
             // impl or class (where the self type is not permitted),
             // or from a trait type (in which case methods that refer
             // to self are not permitted).
-            let init_substs = {self_ty: Some(rcvr_ty), ..init_substs};
+            let init_substs = substs {
+                self_ty: Some(rcvr_ty),
+                ..init_substs
+            };
 
             worklist.push((init_trait_ty, init_substs));
 
@@ -416,7 +423,10 @@ impl LookupContext {
                         &init_substs);
 
                     // Again replacing the self type
-                    let new_substs = {self_ty: Some(rcvr_ty), ..new_substs};
+                    let new_substs = substs {
+                        self_ty: Some(rcvr_ty),
+                        ..new_substs
+                    };
 
                     worklist.push((supertrait.tpt.ty, new_substs));
                 }
@@ -506,7 +516,10 @@ impl LookupContext {
         // `trait_ty` for `self` here, because it allows the compiler
         // to soldier on.  An error will be reported should this
         // candidate be selected if the method refers to `self`.
-        let rcvr_substs = {self_ty: Some(self_ty), ../*bad*/copy *substs};
+        let rcvr_substs = substs {
+            self_ty: Some(self_ty),
+            ../*bad*/copy *substs
+        };
 
         let (rcvr_ty, rcvr_substs) =
             self.create_rcvr_ty_and_substs_for_method(method.self_ty,
@@ -537,7 +550,10 @@ impl LookupContext {
         }
         let method = &methods[index];
 
-        let rcvr_substs = { self_ty: Some(self_ty), ../*bad*/copy *substs };
+        let rcvr_substs = substs {
+            self_ty: Some(self_ty),
+            ../*bad*/copy *substs
+        };
         let (rcvr_ty, rcvr_substs) =
             self.create_rcvr_ty_and_substs_for_method(
                 method.self_ty,
@@ -628,7 +644,11 @@ impl LookupContext {
                     candidate");
 
             // XXX: Needs to support generics.
-            let dummy_substs = { self_r: None, self_ty: None, tps: ~[] };
+            let dummy_substs = substs {
+                self_r: None,
+                self_ty: None,
+                tps: ~[]
+            };
             let (impl_ty, impl_substs) =
                 self.create_rcvr_ty_and_substs_for_method(
                     provided_method_info.method_info.self_type,
@@ -673,11 +693,13 @@ impl LookupContext {
                     move self_substs
                 }
                 sty_region(_) => {
-                    {self_r:
-                         Some(self.infcx().next_region_var(
-                             self.expr.span,
-                             self.expr.id)),
-                     ..self_substs}
+                    substs {
+                        self_r:
+                             Some(self.infcx().next_region_var(
+                                 self.expr.span,
+                                 self.expr.id)),
+                        ..self_substs
+                    }
                 }
             }
         };
@@ -1058,7 +1080,7 @@ impl LookupContext {
 
         // Construct the full set of type parameters for the method,
         // which is equal to the class tps + the method tps.
-        let all_substs = {
+        let all_substs = substs {
             tps: vec::append(/*bad*/copy candidate.rcvr_substs.tps,
                              m_substs),
             ../*bad*/copy candidate.rcvr_substs
@@ -1066,7 +1088,7 @@ impl LookupContext {
 
         self.fcx.write_ty_substs(self.callee_id, fty, all_substs);
         method_map_entry {
-            self_arg: {
+            self_arg: arg {
                 mode: ast::expl(candidate.self_mode),
                 ty: candidate.rcvr_ty,
             },
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index cf13fcb86e8..3d5f6e9d303 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -84,7 +84,7 @@ use middle::pat_util::pat_id_map;
 use middle::pat_util;
 use middle::ty::{TyVid, Vid, FnTyBase, FnMeta, FnSig, VariantInfo_, field};
 use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
-use middle::ty::{re_bound, br_cap_avoid};
+use middle::ty::{re_bound, br_cap_avoid, substs, arg, param_ty};
 use middle::ty;
 use middle::typeck::astconv::{ast_conv, ast_path_to_ty};
 use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty};
@@ -1059,9 +1059,11 @@ pub fn impl_self_ty(vcx: &VtableContext,
               {n_tps: ts.len(),
                region_param: region_param,
                raw_ty: ty::mk_struct(tcx, local_def(class_id),
-                      {self_r: rscope::bound_self_region(region_param),
-                       self_ty: None,
-                       tps: ty::ty_params_to_tys(tcx, /*bad*/copy *ts)})}
+                      substs {
+                        self_r: rscope::bound_self_region(region_param),
+                        self_ty: None,
+                        tps: ty::ty_params_to_tys(tcx, /*bad*/copy *ts)
+                      })}
           }
           _ => { tcx.sess.bug(~"impl_self_ty: unbound item or item that \
                doesn't have a self_ty"); }
@@ -1081,7 +1083,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
     };
     let tps = vcx.infcx.next_ty_vars(n_tps);
 
-    let substs = {self_r: self_r, self_ty: None, tps: tps};
+    let substs = substs { self_r: self_r, self_ty: None, tps: tps };
     let substd_ty = ty::subst(tcx, &substs, raw_ty);
     {substs: substs, ty: substd_ty}
 }
@@ -1814,7 +1816,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                     let self_region =
                         bound_self_region(region_parameterized);
 
-                    raw_type = ty::mk_struct(tcx, class_id, {
+                    raw_type = ty::mk_struct(tcx, class_id, substs {
                         self_r: self_region,
                         self_ty: None,
                         tps: ty::ty_params_to_tys(
@@ -1840,7 +1842,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                                             span,
                                             ty::re_scope(id));
         let type_parameters = fcx.infcx().next_ty_vars(type_parameter_count);
-        let substitutions = {
+        let substitutions = substs {
             self_r: self_region,
             self_ty: None,
             tps: type_parameters
@@ -1897,7 +1899,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                     let self_region =
                         bound_self_region(region_parameterized);
 
-                    raw_type = ty::mk_enum(tcx, enum_id, {
+                    raw_type = ty::mk_enum(tcx, enum_id, substs {
                         self_r: self_region,
                         self_ty: None,
                         tps: ty::ty_params_to_tys(
@@ -1923,7 +1925,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                                             span,
                                             ty::re_scope(id));
         let type_parameters = fcx.infcx().next_ty_vars(type_parameter_count);
-        let substitutions = {
+        let substitutions = substs {
             self_r: self_region,
             self_ty: None,
             tps: type_parameters
@@ -2434,7 +2436,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
             let expr_mt = ty::mt {ty: expr_t, mutbl: f.node.mutbl};
             // for the most precise error message,
             // should be f.node.expr.span, not f.span
-            respan(f.node.expr.span, {ident: f.node.ident, mt: expr_mt})
+            respan(f.node.expr.span, field {ident: f.node.ident, mt: expr_mt})
         });
         match base {
           None => {
@@ -2951,7 +2953,7 @@ fn instantiate_path(fcx: @fn_ctxt,
         pth.types.map(|aty| fcx.to_ty(*aty))
     };
 
-    let substs = {self_r: self_r, self_ty: None, tps: tps};
+    let substs = substs { self_r: self_r, self_ty: None, tps: tps };
     fcx.write_ty_substs(node_id, tpt.ty, substs);
 
     debug!("<<<");
@@ -3050,7 +3052,7 @@ fn check_bounds_are_used(ccx: @crate_ctxt,
         |_r| {},
         |t| {
             match ty::get(t).sty {
-              ty::ty_param({idx, _}) => {
+              ty::ty_param(param_ty {idx, _}) => {
                   debug!("Found use of ty param #%u", idx);
                   tps_used[idx] = true;
               }
@@ -3073,7 +3075,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
         ty::mk_param(ccx.tcx, n, local_def(0))
     }
     fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
-        {mode: ast::expl(m), ty: ty}
+        arg {mode: ast::expl(m), ty: ty}
     }
     let tcx = ccx.tcx;
     let (n_tps, inputs, output) = match ccx.tcx.sess.str_of(it.ident) {
@@ -3136,12 +3138,14 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
                           onceness: ast::Once,
                           region: ty::re_bound(ty::br_anon(0)),
                           bounds: @~[]},
-            sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
-                                   ty: ty::mk_imm_ptr(
-                                       ccx.tcx,
-                                       ty::mk_mach_uint(ccx.tcx, ast::ty_u8))
-                                  }],
-                        output: ty::mk_nil(ccx.tcx)}
+            sig: FnSig {
+                inputs: ~[arg {
+                    mode: ast::expl(ast::by_val),
+                    ty: ty::mk_imm_ptr(
+                        ccx.tcx,
+                        ty::mk_mach_uint(ccx.tcx, ast::ty_u8))
+                }],
+                output: ty::mk_nil(ccx.tcx)}
         });
         (0u, ~[arg(ast::by_ref, fty)], ty::mk_nil(tcx))
       }
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 9d309d4996b..9f6cc6835b7 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -11,6 +11,7 @@
 use core::prelude::*;
 
 use middle::resolve;
+use middle::ty::{param_ty, substs};
 use middle::ty;
 use middle::typeck::check::{fn_ctxt, impl_self_ty};
 use middle::typeck::check::{structurally_resolved_type};
@@ -103,7 +104,10 @@ fn lookup_vtables(vcx: &VtableContext,
                    ppaux::ty_to_str(tcx, trait_ty),
                    ty::substs_to_str(tcx, substs));
 
-            let new_substs = {self_ty: Some(*ty), ../*bad*/copy *substs};
+            let new_substs = substs {
+                self_ty: Some(*ty),
+                ../*bad*/copy *substs
+            };
             let trait_ty = ty::subst(tcx, &new_substs, trait_ty);
 
             debug!("after subst: %?",
@@ -189,7 +193,7 @@ fn lookup_vtable(vcx: &VtableContext,
     };
 
     match ty::get(ty).sty {
-        ty::ty_param({idx: n, def_id: did}) => {
+        ty::ty_param(param_ty {idx: n, def_id: did}) => {
             let mut n_bound = 0;
             let bounds = tcx.ty_param_bounds.get(did.node);
             for ty::iter_bound_traits_and_supertraits(
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index e5dc91b7f17..c5374af2dd0 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -15,6 +15,7 @@
 use core::prelude::*;
 
 use middle::pat_util;
+use middle::ty::arg;
 use middle::ty;
 use middle::typeck::check::{fn_ctxt, self_info};
 use middle::typeck::infer::{force_all, resolve_all, resolve_region};
@@ -65,7 +66,7 @@ fn resolve_method_map_entry(fcx: @fn_ctxt, sp: span, id: ast::node_id)
                 fcx.ccx.method_map.insert(
                     id,
                     method_map_entry {
-                        self_arg: {mode: mme.self_arg.mode, ty: *t},
+                        self_arg: arg {mode: mme.self_arg.mode, ty: *t},
                         .. *mme
                     }
                 );
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index b0c98cfa2b1..4cd2eaaf003 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -25,8 +25,8 @@ use metadata::decoder::{dl_def, dl_field, dl_impl};
 use middle::resolve::{Impl, MethodInfo};
 use middle::ty::{ProvidedMethodSource, ProvidedMethodInfo, bound_copy, get};
 use middle::ty::{kind_can_be_copied, lookup_item_type, param_bounds, subst};
-use middle::ty::{t, ty_bool, ty_bot, ty_box, ty_enum, ty_err, ty_estr};
-use middle::ty::{ty_evec, ty_float, ty_fn, ty_infer, ty_int, ty_nil};
+use middle::ty::{substs, t, ty_bool, ty_bot, ty_box, ty_enum, ty_err};
+use middle::ty::{ty_estr, ty_evec, ty_float, ty_fn, ty_infer, ty_int, ty_nil};
 use middle::ty::{ty_opaque_box, ty_param, ty_param_bounds_and_ty, ty_ptr};
 use middle::ty::{ty_rec, ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
 use middle::ty::{ty_type, ty_uint, ty_uniq};
@@ -34,6 +34,7 @@ use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec, type_kind_ext};
 use middle::ty::{type_is_ty_var};
 use middle::ty;
 use middle::typeck::crate_ctxt;
+use middle::typeck::infer::combine::Combine;
 use middle::typeck::infer::{InferCtxt, can_mk_subty};
 use middle::typeck::infer::{new_infer_ctxt, resolve_ivar};
 use middle::typeck::infer::{resolve_nested_tvar, resolve_type};
@@ -286,8 +287,8 @@ impl CoherenceChecker {
         }
 
         // Add the implementation to the mapping from implementation to base
-        // type def ID, if there is a base type for this implementation.
-
+        // type def ID, if there is a base type for this implementation and
+        // the implementation does not have any associated traits.
         match get_base_type_def_id(self.inference_context,
                                    item.span,
                                    self_type.ty) {
@@ -296,16 +297,19 @@ impl CoherenceChecker {
             }
             Some(base_type_def_id) => {
                 // XXX: Gather up default methods?
-                let implementation;
-                match implementation_opt {
-                    None => {
-                        implementation = self.create_impl_from_item(item);
-                    }
-                    Some(copy existing_implementation) => {
-                        implementation = existing_implementation;
+                if associated_traits.len() == 0 {
+                    let implementation;
+                    match implementation_opt {
+                        None => {
+                            implementation = self.create_impl_from_item(item);
+                        }
+                        Some(copy existing_implementation) => {
+                            implementation = existing_implementation;
+                        }
                     }
+                    self.add_inherent_method(base_type_def_id,
+                                             implementation);
                 }
-                self.add_inherent_method(base_type_def_id, implementation);
 
                 self.base_type_def_ids.insert(local_def(item.id),
                                               base_type_def_id);
@@ -510,7 +514,7 @@ impl CoherenceChecker {
         let type_parameters =
             self.inference_context.next_ty_vars(bounds_count);
 
-        let substitutions = {
+        let substitutions = substs {
             self_r: self_region,
             self_ty: None,
             tps: type_parameters
@@ -520,7 +524,8 @@ impl CoherenceChecker {
                              polytype.ty);
 
         // Get our type parameters back.
-        let { self_r: _, self_ty: _, tps: type_parameters } = substitutions;
+        let substs { self_r: _, self_ty: _, tps: type_parameters } =
+            substitutions;
 
         UniversalQuantificationResult {
             monotype: monotype,
@@ -597,6 +602,7 @@ impl CoherenceChecker {
                         visit_mod(module_, item.span, item.id, (), visitor);
                     }
                     item_impl(_, opt_trait, _, _) => {
+                        let mut ok = false;
                         match self.base_type_def_ids.find(
                             local_def(item.id)) {
 
@@ -611,57 +617,50 @@ impl CoherenceChecker {
                                     // Record that this implementation is OK.
                                     self.privileged_implementations.insert
                                         (item.id, ());
-                                } else {
-                                    // This implementation is not in scope of
-                                    // its base type. This still might be OK
-                                    // if the traits are defined in the same
-                                    // crate.
-
-                                  match opt_trait {
-                                    None => {
-                                        // There is no trait to implement, so
-                                        // this is an error.
-
-                                        let session =
-                                            self.crate_context.tcx.sess;
-                                        session.span_err(item.span,
-                                                         ~"cannot implement \
-                                                          inherent methods \
-                                                          for a type outside \
-                                                          the crate the type \
-                                                          was defined in; \
-                                                          define and \
-                                                          implement a trait \
-                                                          or new type \
-                                                          instead");
-                                    }
-                                    _ => ()
-                                  }
-
-                                  do opt_trait.iter() |trait_ref| {
-                                        // This is OK if and only if the
-                                        // trait was defined in this
-                                        // crate.
-
-                                        let trait_def_id =
-                                            self.trait_ref_to_trait_def_id(
-                                                *trait_ref);
-
-                                        if trait_def_id.crate != local_crate {
-                                            let session =
-                                                self.crate_context.tcx.sess;
-                                            session.span_err(item.span,
-                                                             ~"cannot \
-                                                               provide an \
-                                                               extension \
-                                                               implementa\
-                                                                  tion \
-                                                               for a trait \
-                                                               not defined \
-                                                               in this \
-                                                               crate");
-                                        }
-                                    }
+                                    ok = true;
+                                }
+                            }
+                        }
+
+                        if !ok {
+                            // This implementation is not in scope of its base
+                            // type. This still might be OK if the trait is
+                            // defined in the same crate.
+
+                            match opt_trait {
+                                None => {
+                                    // There is no trait to implement, so
+                                    // this is an error.
+
+                                    let session = self.crate_context.tcx.sess;
+                                    session.span_err(item.span,
+                                                     ~"cannot implement \
+                                                      inherent methods for a \
+                                                      type outside the crate \
+                                                      the type was defined \
+                                                      in; define and \
+                                                      implement a trait or \
+                                                      new type instead");
+                                }
+                                _ => ()
+                          }
+
+                          do opt_trait.iter() |trait_ref| {
+                                // This is OK if and only if the trait was
+                                // defined in this crate.
+
+                                let trait_def_id =
+                                    self.trait_ref_to_trait_def_id(
+                                        *trait_ref);
+
+                                if trait_def_id.crate != local_crate {
+                                    let session = self.crate_context.tcx.sess;
+                                    session.span_err(item.span,
+                                                     ~"cannot provide an \
+                                                       extension \
+                                                       implementation for a \
+                                                       trait not defined in \
+                                                       this crate");
                                 }
                             }
                         }
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index ba34846ca97..ce0c7a94c7c 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -33,8 +33,8 @@ are represented as `ty_param()` instances.
 use core::prelude::*;
 
 use metadata::csearch;
-use middle::ty::{FnMeta, FnSig, FnTyBase, InstantiatedTraitRef};
-use middle::ty::{ty_param_substs_and_ty};
+use middle::ty::{FnMeta, FnSig, FnTyBase, InstantiatedTraitRef, arg};
+use middle::ty::{substs, ty_param_substs_and_ty};
 use middle::ty;
 use middle::typeck::astconv::{ast_conv, ty_of_fn_decl, ty_of_arg};
 use middle::typeck::astconv::{ast_ty_to_ty};
@@ -75,7 +75,11 @@ fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
                 for m.items.each |intrinsic_item| {
                     let def_id = ast::def_id { crate: ast::local_crate,
                                                node: intrinsic_item.id };
-                    let substs = {self_r: None, self_ty: None, tps: ~[]};
+                    let substs = substs {
+                        self_r: None,
+                        self_ty: None,
+                        tps: ~[]
+                    };
 
                     match intrinsic_item.node {
                       ast::item_trait(*) => {
@@ -164,7 +168,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
                 let rs = type_rscope(rp);
                 let args = args.map(|va| {
                     let arg_ty = ccx.to_ty(rs, va.ty);
-                    {mode: ast::expl(ast::by_copy), ty: arg_ty}
+                    arg { mode: ast::expl(ast::by_copy), ty: arg_ty }
                 });
                 result_ty = Some(ty::mk_fn(tcx, FnTyBase {
                     meta: FnMeta {purity: ast::pure_fn,
@@ -195,8 +199,9 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
                     variant.node.id);
                 // Compute the ctor arg types from the struct fields
                 let struct_fields = do struct_def.fields.map |struct_field| {
-                    {mode: ast::expl(ast::by_val),
-                     ty: ty::node_id_to_type(ccx.tcx, (*struct_field).node.id)
+                    arg {
+                        mode: ast::expl(ast::by_val),
+                        ty: ty::node_id_to_type(ccx.tcx, struct_field.node.id)
                     }
                 };
                 result_ty = Some(ty::mk_fn(tcx, FnTyBase {
@@ -265,8 +270,11 @@ fn ensure_trait_methods(ccx: @crate_ctxt, id: ast::node_id, trait_ty: ty::t) {
             ty::mk_param(ccx.tcx, i + 1, dummy_defid)
         };
 
-        let substs = { self_r: None, self_ty: Some(self_param),
-                       tps: non_shifted_trait_tps + shifted_method_tps };
+        let substs = substs {
+            self_r: None,
+            self_ty: Some(self_param),
+            tps: non_shifted_trait_tps + shifted_method_tps
+        };
         let ty = ty::subst(ccx.tcx,
                            &substs,
                            ty::mk_fn(ccx.tcx, /*bad*/copy m.fty));
@@ -462,7 +470,7 @@ fn compare_impl_method(tcx: ty::ctxt,
         };
         let trait_tps = trait_substs.tps.map(
             |t| replace_bound_self(tcx, *t, dummy_self_r));
-        let substs = {
+        let substs = substs {
             self_r: Some(dummy_self_r),
             self_ty: Some(self_ty),
             tps: vec::append(trait_tps, dummy_tps)
@@ -705,7 +713,7 @@ fn convert_struct(ccx: @crate_ctxt,
                     },
                     sig: FnSig {
                         inputs: do struct_def.fields.map |field| {
-                            {
+                            arg {
                                 mode: ast::expl(ast::by_copy),
                                 ty: ccx.tcx.tcache.get
                                         (local_def(field.node.id)).ty
@@ -1002,5 +1010,8 @@ fn mk_substs(ccx: @crate_ctxt,
           -> {bounds: @~[ty::param_bounds], substs: ty::substs} {
     let {bounds, params} = mk_ty_params(ccx, atps);
     let self_r = rscope::bound_self_region(rp);
-    {bounds: bounds, substs: {self_r: self_r, self_ty: None, tps: params}}
+    {
+        bounds: bounds,
+        substs: substs { self_r: self_r, self_ty: None, tps: params }
+    }
 }
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index e9946ae7c13..d1c57a21a3b 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -57,7 +57,7 @@
 use core::prelude::*;
 
 use middle::ty::{FloatVar, FnTyBase, FnMeta, FnSig, IntVar, TyVar};
-use middle::ty::{IntType, UintType};
+use middle::ty::{IntType, UintType, arg, substs};
 use middle::ty;
 use middle::typeck::infer::glb::Glb;
 use middle::typeck::infer::lub::Lub;
@@ -233,7 +233,11 @@ fn super_substs<C:Combine>(
             do relate_region_param(self, did,
                                    a.self_r, b.self_r).chain |self_r|
             {
-                Ok({self_r: self_r, self_ty: self_ty, tps: /*bad*/copy tps})
+                Ok(substs {
+                    self_r: self_r,
+                    self_ty: self_ty,
+                    tps: /*bad*/copy tps
+                })
             }
         }
     }
@@ -295,7 +299,7 @@ fn super_flds<C:Combine>(
 
     if a.ident == b.ident {
         self.mts(a.mt, b.mt)
-            .chain(|mt| Ok({ident: a.ident, mt: mt}) )
+            .chain(|mt| Ok(ty::field {ident: a.ident, mt: mt}) )
             .chain_err(|e| Err(ty::terr_in_field(@e, a.ident)) )
     } else {
         Err(ty::terr_record_fields(
@@ -317,7 +321,7 @@ fn super_args<C:Combine>(
 
     do self.modes(a.mode, b.mode).chain |m| {
         do self.contratys(a.ty, b.ty).chain |t| {
-            Ok({mode: m, ty: t})
+            Ok(arg {mode: m, ty: t})
         }
     }
 }
@@ -587,4 +591,4 @@ fn super_tys<C:Combine>(
         if_ok!(self.infcx().simple_var_t(vid_is_expected, vid, val));
         Ok(ty::mk_mach_float(tcx, val))
     }
-}
\ No newline at end of file
+}
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index cac5fa5feb1..cab40ce21b1 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -255,7 +255,7 @@ use middle::ty::IntVarValue;
 use middle::ty;
 use middle::typeck::check::regionmanip::{replace_bound_regions_in_fn_sig};
 use middle::typeck::infer::coercion::Coerce;
-use middle::typeck::infer::combine::{CombineFields, eq_tys};
+use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys};
 use middle::typeck::infer::glb::Glb;
 use middle::typeck::infer::lub::Lub;
 use middle::typeck::infer::region_inference::{RegionVarBindings};
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index ac079f8f044..fb9e0f36c2f 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -17,7 +17,7 @@ use middle::ty::{bound_copy, bound_const, bound_durable, bound_owned,
 use middle::ty::{bound_region, br_anon, br_named, br_self, br_cap_avoid,
                  br_fresh};
 use middle::ty::{ctxt, field, method};
-use middle::ty::{mt, t, param_bound};
+use middle::ty::{mt, t, param_bound, param_ty};
 use middle::ty::{re_bound, re_free, re_scope, re_infer, re_static, Region};
 use middle::ty::{ReSkolemized, ReVar};
 use middle::ty::{ty_bool, ty_bot, ty_box, ty_struct, ty_enum};
@@ -292,9 +292,8 @@ fn fn_sig_to_str(cx: ctxt, typ: &ty::FnSig) -> ~str {
 }
 
 fn ty_to_str(cx: ctxt, typ: t) -> ~str {
-    fn fn_input_to_str(cx: ctxt, input: {mode: ast::mode, ty: t}) ->
-       ~str {
-        let {mode, ty} = input;
+    fn fn_input_to_str(cx: ctxt, input: ty::arg) -> ~str {
+        let ty::arg {mode: mode, ty: ty} = input;
         let modestr = match canon_mode(cx, mode) {
           ast::infer(_) => ~"",
           ast::expl(m) => {
@@ -423,7 +422,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
       }
       ty_infer(infer_ty) => infer_ty.to_str(),
       ty_err => ~"[type error]",
-      ty_param({idx: id, _}) => {
+      ty_param(param_ty {idx: id, _}) => {
         ~"'" + str::from_bytes(~[('a' as u8) + (id as u8)])
       }
       ty_self => ~"self",
diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs
index 99cf301f182..bc332615eaa 100644
--- a/src/librustdoc/astsrv.rs
+++ b/src/librustdoc/astsrv.rs
@@ -155,9 +155,9 @@ fn build_error_handlers(
     codemap: @codemap::CodeMap
 ) -> ErrorHandlers {
 
-    type DiagnosticHandler = {
+    struct DiagnosticHandler {
         inner: diagnostic::handler,
-    };
+    }
 
     impl DiagnosticHandler: diagnostic::handler {
         fn fatal(msg: &str) -> ! { self.inner.fatal(msg) }
@@ -182,7 +182,7 @@ fn build_error_handlers(
         diagnostic::emit(cmsp, msg, lvl);
     };
     let inner_handler = diagnostic::mk_handler(Some(emitter));
-    let handler = {
+    let handler = DiagnosticHandler {
         inner: inner_handler,
     };
     let span_handler = diagnostic::mk_span_handler(
diff --git a/src/librustdoc/attr_pass.rs b/src/librustdoc/attr_pass.rs
index 1ab3ce2d6f3..39a893a4076 100644
--- a/src/librustdoc/attr_pass.rs
+++ b/src/librustdoc/attr_pass.rs
@@ -69,9 +69,9 @@ fn fold_crate(
         attr_parser::parse_crate(attrs)
     };
 
-    {
-        topmod: doc::ModDoc_({
-            item: {
+    doc::CrateDoc {
+        topmod: doc::ModDoc_(doc::ModDoc_ {
+            item: doc::ItemDoc {
                 name: option::get_or_default(attrs.name, doc.topmod.name()),
                 .. doc.topmod.item
             },
@@ -103,7 +103,7 @@ fn fold_item(
         parse_item_attrs(srv, doc.id, attr_parser::parse_desc)
     };
 
-    {
+    doc::ItemDoc {
         desc: desc,
         .. doc
     }
@@ -162,7 +162,7 @@ fn fold_enum(
     let doc_id = doc.id();
     let doc = fold::default_seq_fold_enum(fold, doc);
 
-    {
+    doc::EnumDoc {
         variants: do par::map(doc.variants) |variant| {
             let variant = *variant;
             let desc = do astsrv::exec(srv) |ctxt| {
@@ -182,7 +182,7 @@ fn fold_enum(
                 }
             };
 
-            {
+            doc::VariantDoc {
                 desc: desc,
                 .. variant
             }
@@ -211,7 +211,7 @@ fn fold_trait(
     let srv = fold.ctxt;
     let doc = fold::default_seq_fold_trait(fold, doc);
 
-    {
+    doc::TraitDoc {
         methods: merge_method_attrs(srv, doc.id(), doc.methods),
         .. doc
     }
@@ -256,7 +256,7 @@ fn merge_method_attrs(
         assert doc.name == attrs.first();
         let desc = attrs.second();
 
-        {
+        doc::MethodDoc {
             desc: desc,
             ..*doc
         }
@@ -287,7 +287,7 @@ fn fold_impl(
     let srv = fold.ctxt;
     let doc = fold::default_seq_fold_impl(fold, doc);
 
-    {
+    doc::ImplDoc {
         methods: merge_method_attrs(srv, doc.id(), doc.methods),
         .. doc
     }
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index ebd5c047df3..0ad048d49bb 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -50,13 +50,13 @@ impl OutputStyle : cmp::Eq {
 }
 
 /// The configuration for a rustdoc session
-pub type Config = {
+pub struct Config {
     input_crate: Path,
     output_dir: Path,
     output_format: OutputFormat,
     output_style: OutputStyle,
     pandoc_cmd: Option<~str>
-};
+}
 
 pub impl Config: Clone {
     fn clone(&self) -> Config { copy *self }
@@ -95,7 +95,7 @@ pub fn usage() {
 }
 
 pub fn default_config(input_crate: &Path) -> Config {
-    {
+    Config {
         input_crate: *input_crate,
         output_dir: Path("."),
         output_format: PandocHtml,
@@ -155,7 +155,7 @@ fn config_from_opts(
     let result = do result::chain(result) |config| {
         let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
         let output_dir = output_dir.map(|s| Path(*s));
-        result::Ok({
+        result::Ok(Config {
             output_dir: output_dir.get_or_default(config.output_dir),
             .. config
         })
@@ -168,7 +168,7 @@ fn config_from_opts(
             do result::chain(parse_output_format(*output_format))
                 |output_format| {
 
-                result::Ok({
+                result::Ok(Config {
                     output_format: output_format,
                     .. config
                 })
@@ -182,7 +182,7 @@ fn config_from_opts(
             |output_style| {
             do result::chain(parse_output_style(*output_style))
                 |output_style| {
-                result::Ok({
+                result::Ok(Config {
                     output_style: output_style,
                     .. config
                 })
@@ -195,7 +195,7 @@ fn config_from_opts(
         let pandoc_cmd = maybe_find_pandoc(
             &config, pandoc_cmd, move program_output.take());
         do result::chain(pandoc_cmd) |pandoc_cmd| {
-            result::Ok({
+            result::Ok(Config {
                 pandoc_cmd: pandoc_cmd,
                 .. config
             })
diff --git a/src/librustdoc/desc_to_brief_pass.rs b/src/librustdoc/desc_to_brief_pass.rs
index f53e0058b63..93f4be10a5c 100644
--- a/src/librustdoc/desc_to_brief_pass.rs
+++ b/src/librustdoc/desc_to_brief_pass.rs
@@ -51,7 +51,7 @@ pub fn run(
 fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc {
     let doc = fold::default_seq_fold_item(fold, doc);
 
-    {
+    doc::ItemDoc {
         brief: extract(doc.desc),
         .. doc
     }
@@ -60,8 +60,8 @@ fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc {
 fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc {
     let doc =fold::default_seq_fold_trait(fold, doc);
 
-    {
-        methods: par::map(doc.methods, |doc| {
+    doc::TraitDoc {
+        methods: par::map(doc.methods, |doc| doc::MethodDoc {
             brief: extract(doc.desc),
             .. *doc
         }),
@@ -72,8 +72,8 @@ fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc {
 fn fold_impl(fold: &fold::Fold<()>, +doc: doc::ImplDoc) -> doc::ImplDoc {
     let doc =fold::default_seq_fold_impl(fold, doc);
 
-    {
-        methods: par::map(doc.methods, |doc| {
+    doc::ImplDoc {
+        methods: par::map(doc.methods, |doc| doc::MethodDoc {
             brief: extract(doc.desc),
             .. *doc
         }),
diff --git a/src/librustdoc/doc.rs b/src/librustdoc/doc.rs
index 18742720b90..247694fb26a 100644
--- a/src/librustdoc/doc.rs
+++ b/src/librustdoc/doc.rs
@@ -21,94 +21,47 @@ use core::vec;
 
 pub type AstId = int;
 
-pub type Doc_ = {
+#[deriving_eq]
+pub struct Doc_ {
     pages: ~[Page]
-};
-
-impl Doc_ : cmp::Eq {
-    pure fn eq(&self, other: &Doc_) -> bool {
-        (*self).pages == (*other).pages
-    }
-    pure fn ne(&self, other: &Doc_) -> bool { !(*self).eq(other) }
 }
 
+#[deriving_eq]
 pub enum Doc {
     Doc_(Doc_)
 }
 
-impl Doc : cmp::Eq {
-    pure fn eq(&self, other: &Doc) -> bool { *(*self) == *(*other) }
-    pure fn ne(&self, other: &Doc) -> bool { *(*self) != *(*other) }
-}
-
+#[deriving_eq]
 pub enum Page {
     CratePage(CrateDoc),
     ItemPage(ItemTag)
 }
 
-impl Page : cmp::Eq {
-    pure fn eq(&self, other: &Page) -> bool {
-        match (*self) {
-            CratePage(e0a) => {
-                match (*other) {
-                    CratePage(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            ItemPage(e0a) => {
-                match (*other) {
-                    ItemPage(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-        }
-    }
-    pure fn ne(&self, other: &Page) -> bool { !(*self).eq(other) }
-}
-
+#[deriving_eq]
 pub enum Implementation {
     Required,
     Provided,
 }
 
-impl Implementation : cmp::Eq {
-    pure fn eq(&self, other: &Implementation) -> bool {
-        ((*self) as uint) == ((*other) as uint)
-    }
-    pure fn ne(&self, other: &Implementation) -> bool { !(*self).eq(other) }
-}
-
-
 /**
  * Most rustdocs can be parsed into 'sections' according to their markdown
  * headers
  */
-pub type Section = {
+#[deriving_eq]
+pub struct Section {
     header: ~str,
     body: ~str
-};
-
-impl Section : cmp::Eq {
-    pure fn eq(&self, other: &Section) -> bool {
-        (*self).header == (*other).header && (*self).body == (*other).body
-    }
-    pure fn ne(&self, other: &Section) -> bool { !(*self).eq(other) }
 }
 
 // FIXME (#2596): We currently give topmod the name of the crate.  There
 // would probably be fewer special cases if the crate had its own name
 // and topmod's name was the empty string.
-pub type CrateDoc = {
-    topmod: ModDoc,
-};
-
-impl CrateDoc : cmp::Eq {
-    pure fn eq(&self, other: &CrateDoc) -> bool {
-        (*self).topmod == (*other).topmod
-    }
-    pure fn ne(&self, other: &CrateDoc) -> bool { !(*self).eq(other) }
+#[deriving_eq]
+pub struct CrateDoc {
+    topmod: ModDoc
 }
 
+#[deriving_eq]
 pub enum ItemTag {
     ModTag(ModDoc),
     NmodTag(NmodDoc),
@@ -121,69 +74,8 @@ pub enum ItemTag {
     StructTag(StructDoc)
 }
 
-impl ItemTag : cmp::Eq {
-    pure fn eq(&self, other: &ItemTag) -> bool {
-        match (*self) {
-            ModTag(e0a) => {
-                match (*other) {
-                    ModTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            NmodTag(e0a) => {
-                match (*other) {
-                    NmodTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            ConstTag(e0a) => {
-                match (*other) {
-                    ConstTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            FnTag(e0a) => {
-                match (*other) {
-                    FnTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            EnumTag(e0a) => {
-                match (*other) {
-                    EnumTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            TraitTag(e0a) => {
-                match (*other) {
-                    TraitTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            ImplTag(e0a) => {
-                match (*other) {
-                    ImplTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            TyTag(e0a) => {
-                match (*other) {
-                    TyTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-            StructTag(e0a) => {
-                match (*other) {
-                    StructTag(e0b) => e0a == e0b,
-                    _ => false
-                }
-            }
-        }
-    }
-    pure fn ne(&self, other: &ItemTag) -> bool { !(*self).eq(other) }
-}
-
-pub type ItemDoc = {
+#[deriving_eq]
+pub struct ItemDoc {
     id: AstId,
     name: ~str,
     path: ~[~str],
@@ -192,179 +84,86 @@ pub type ItemDoc = {
     sections: ~[Section],
     // Indicates that this node is a reexport of a different item
     reexport: bool
-};
-
-impl ItemDoc : cmp::Eq {
-    pure fn eq(&self, other: &ItemDoc) -> bool {
-        (*self).id == (*other).id &&
-        (*self).name == (*other).name &&
-        (*self).path == (*other).path &&
-        (*self).brief == (*other).brief &&
-        (*self).desc == (*other).desc &&
-        (*self).sections == (*other).sections &&
-        (*self).reexport == (*other).reexport
-    }
-    pure fn ne(&self, other: &ItemDoc) -> bool { !(*self).eq(other) }
 }
 
-pub type SimpleItemDoc = {
+#[deriving_eq]
+pub struct SimpleItemDoc {
     item: ItemDoc,
     sig: Option<~str>
-};
-
-impl SimpleItemDoc : cmp::Eq {
-    pure fn eq(&self, other: &SimpleItemDoc) -> bool {
-        (*self).item == (*other).item && (*self).sig == (*other).sig
-    }
-    pure fn ne(&self, other: &SimpleItemDoc) -> bool { !(*self).eq(other) }
 }
 
-pub type ModDoc_ = {
+#[deriving_eq]
+pub struct ModDoc_ {
     item: ItemDoc,
     items: ~[ItemTag],
     index: Option<Index>
-};
-
-impl ModDoc_ : cmp::Eq {
-    pure fn eq(&self, other: &ModDoc_) -> bool {
-        (*self).item == (*other).item &&
-        (*self).items == (*other).items &&
-        (*self).index == (*other).index
-    }
-    pure fn ne(&self, other: &ModDoc_) -> bool { !(*self).eq(other) }
 }
 
+#[deriving_eq]
 pub enum ModDoc {
     ModDoc_(ModDoc_)
 }
 
-impl ModDoc : cmp::Eq {
-    pure fn eq(&self, other: &ModDoc) -> bool { *(*self) == *(*other) }
-    pure fn ne(&self, other: &ModDoc) -> bool { *(*self) != *(*other) }
-}
-
-pub type NmodDoc = {
+#[deriving_eq]
+pub struct NmodDoc {
     item: ItemDoc,
     fns: ~[FnDoc],
     index: Option<Index>
-};
-
-impl NmodDoc : cmp::Eq {
-    pure fn eq(&self, other: &NmodDoc) -> bool {
-        (*self).item == (*other).item &&
-        (*self).fns == (*other).fns &&
-        (*self).index == (*other).index
-    }
-    pure fn ne(&self, other: &NmodDoc) -> bool { !(*self).eq(other) }
 }
 
 pub type ConstDoc = SimpleItemDoc;
 
 pub type FnDoc = SimpleItemDoc;
 
-pub type EnumDoc = {
+#[deriving_eq]
+pub struct EnumDoc {
     item: ItemDoc,
     variants: ~[VariantDoc]
-};
-
-impl EnumDoc : cmp::Eq {
-    pure fn eq(&self, other: &EnumDoc) -> bool {
-        (*self).item == (*other).item && (*self).variants == (*other).variants
-    }
-    pure fn ne(&self, other: &EnumDoc) -> bool { !(*self).eq(other) }
 }
 
-pub type VariantDoc = {
+#[deriving_eq]
+pub struct VariantDoc {
     name: ~str,
     desc: Option<~str>,
     sig: Option<~str>
-};
-
-impl VariantDoc : cmp::Eq {
-    pure fn eq(&self, other: &VariantDoc) -> bool {
-        (*self).name == (*other).name &&
-        (*self).desc == (*other).desc &&
-        (*self).sig == (*other).sig
-    }
-    pure fn ne(&self, other: &VariantDoc) -> bool { !(*self).eq(other) }
 }
 
-pub type TraitDoc = {
+#[deriving_eq]
+pub struct TraitDoc {
     item: ItemDoc,
     methods: ~[MethodDoc]
-};
-
-impl TraitDoc : cmp::Eq {
-    pure fn eq(&self, other: &TraitDoc) -> bool {
-        (*self).item == (*other).item && (*self).methods == (*other).methods
-    }
-    pure fn ne(&self, other: &TraitDoc) -> bool { !(*self).eq(other) }
 }
 
-pub type MethodDoc = {
+#[deriving_eq]
+pub struct MethodDoc {
     name: ~str,
     brief: Option<~str>,
     desc: Option<~str>,
     sections: ~[Section],
     sig: Option<~str>,
     implementation: Implementation,
-};
-
-impl MethodDoc : cmp::Eq {
-    pure fn eq(&self, other: &MethodDoc) -> bool {
-        (*self).name == (*other).name &&
-        (*self).brief == (*other).brief &&
-        (*self).desc == (*other).desc &&
-        (*self).sections == (*other).sections &&
-        (*self).sig == (*other).sig &&
-        (*self).implementation == (*other).implementation
-    }
-    pure fn ne(&self, other: &MethodDoc) -> bool { !(*self).eq(other) }
 }
 
-pub type ImplDoc = {
+#[deriving_eq]
+pub struct ImplDoc {
     item: ItemDoc,
     trait_types: ~[~str],
     self_ty: Option<~str>,
     methods: ~[MethodDoc]
-};
-
-impl ImplDoc : cmp::Eq {
-    pure fn eq(&self, other: &ImplDoc) -> bool {
-        (*self).item == (*other).item &&
-        (*self).trait_types == (*other).trait_types &&
-        (*self).self_ty == (*other).self_ty &&
-        (*self).methods == (*other).methods
-    }
-    pure fn ne(&self, other: &ImplDoc) -> bool { !(*self).eq(other) }
 }
 
 pub type TyDoc = SimpleItemDoc;
 
-pub type StructDoc = {
+#[deriving_eq]
+pub struct StructDoc {
     item: ItemDoc,
     fields: ~[~str],
     sig: Option<~str>
-};
-
-impl StructDoc : cmp::Eq {
-    pure fn eq(&self, other: &StructDoc) -> bool {
-        return (*self).item == other.item
-            && (*self).fields == other.fields
-            && (*self).sig == other.sig;
-    }
-    pure fn ne(&self, other: &StructDoc) -> bool { !(*self).eq(other) }
 }
 
-pub type Index = {
+#[deriving_eq]
+pub struct Index {
     entries: ~[IndexEntry]
-};
-
-impl Index : cmp::Eq {
-    pure fn eq(&self, other: &Index) -> bool {
-        (*self).entries == (*other).entries
-    }
-    pure fn ne(&self, other: &Index) -> bool { !(*self).eq(other) }
 }
 
 /**
@@ -377,21 +176,12 @@ impl Index : cmp::Eq {
  * * brief - The brief description
  * * link - A format-specific string representing the link target
  */
-pub type IndexEntry = {
+#[deriving_eq]
+pub struct IndexEntry {
     kind: ~str,
     name: ~str,
     brief: Option<~str>,
     link: ~str
-};
-
-impl IndexEntry : cmp::Eq {
-    pure fn eq(&self, other: &IndexEntry) -> bool {
-        (*self).kind == (*other).kind &&
-        (*self).name == (*other).name &&
-        (*self).brief == (*other).brief &&
-        (*self).link == (*other).link
-    }
-    pure fn ne(&self, other: &IndexEntry) -> bool { !(*self).eq(other) }
 }
 
 impl Doc {
@@ -411,7 +201,6 @@ impl Doc {
 
 /// Some helper methods on ModDoc, mostly for testing
 impl ModDoc {
-
     fn mods() -> ~[ModDoc] {
         do vec::filter_map(self.items) |itemtag| {
             match *itemtag {
diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs
index 444949cfb7f..93226cb5ed8 100644
--- a/src/librustdoc/extract.rs
+++ b/src/librustdoc/extract.rs
@@ -57,9 +57,9 @@ pub fn extract(
     crate: @ast::crate,
     +default_name: ~str
 ) -> doc::Doc {
-    doc::Doc_({
+    doc::Doc_(doc::Doc_ {
         pages: ~[
-            doc::CratePage({
+            doc::CratePage(doc::CrateDoc {
                 topmod: top_moddoc_from_crate(crate, default_name),
             })
         ]
@@ -75,7 +75,7 @@ fn top_moddoc_from_crate(
 }
 
 fn mk_itemdoc(id: ast::node_id, +name: ~str) -> doc::ItemDoc {
-    {
+    doc::ItemDoc {
         id: id,
         name: name,
         path: ~[],
@@ -90,7 +90,7 @@ fn moddoc_from_mod(
     +itemdoc: doc::ItemDoc,
     module_: ast::_mod
 ) -> doc::ModDoc {
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         item: itemdoc,
         items: do vec::filter_map(module_.items) |item| {
             let ItemDoc = mk_itemdoc(item.id, to_str(item.ident));
@@ -161,7 +161,7 @@ fn nmoddoc_from_mod(
           ast::foreign_item_const(*) => {} // XXX: Not implemented.
         }
     }
-    {
+    doc:: NmodDoc {
         item: itemdoc,
         fns: fns,
         index: None
@@ -169,14 +169,14 @@ fn nmoddoc_from_mod(
 }
 
 fn fndoc_from_fn(+itemdoc: doc::ItemDoc) -> doc::FnDoc {
-    {
+    doc::SimpleItemDoc {
         item: itemdoc,
         sig: None
     }
 }
 
 fn constdoc_from_const(+itemdoc: doc::ItemDoc) -> doc::ConstDoc {
-    {
+    doc::SimpleItemDoc {
         item: itemdoc,
         sig: None
     }
@@ -193,7 +193,7 @@ fn enumdoc_from_enum(
     +itemdoc: doc::ItemDoc,
     +variants: ~[ast::variant]
 ) -> doc::EnumDoc {
-    {
+    doc::EnumDoc {
         item: itemdoc,
         variants: variantdocs_from_variants(variants)
     }
@@ -206,8 +206,7 @@ fn variantdocs_from_variants(
 }
 
 fn variantdoc_from_variant(variant: &ast::variant) -> doc::VariantDoc {
-
-    {
+    doc::VariantDoc {
         name: to_str(variant.node.name),
         desc: None,
         sig: None
@@ -231,12 +230,12 @@ fn traitdoc_from_trait(
     +itemdoc: doc::ItemDoc,
     +methods: ~[ast::trait_method]
 ) -> doc::TraitDoc {
-    {
+    doc::TraitDoc {
         item: itemdoc,
         methods: do vec::map(methods) |method| {
             match *method {
               ast::required(ty_m) => {
-                {
+                doc::MethodDoc {
                     name: to_str(ty_m.ident),
                     brief: None,
                     desc: None,
@@ -246,7 +245,7 @@ fn traitdoc_from_trait(
                 }
               }
               ast::provided(m) => {
-                {
+                doc::MethodDoc {
                     name: to_str(m.ident),
                     brief: None,
                     desc: None,
@@ -276,12 +275,12 @@ fn impldoc_from_impl(
     +itemdoc: doc::ItemDoc,
     methods: ~[@ast::method]
 ) -> doc::ImplDoc {
-    {
+    doc::ImplDoc {
         item: itemdoc,
         trait_types: ~[],
         self_ty: None,
         methods: do vec::map(methods) |method| {
-            {
+            doc::MethodDoc {
                 name: to_str(method.ident),
                 brief: None,
                 desc: None,
@@ -302,7 +301,7 @@ fn should_extract_impl_methods() {
 fn tydoc_from_ty(
     +itemdoc: doc::ItemDoc
 ) -> doc::TyDoc {
-    {
+    doc::SimpleItemDoc {
         item: itemdoc,
         sig: None
     }
@@ -318,7 +317,7 @@ fn structdoc_from_struct(
     +itemdoc: doc::ItemDoc,
     struct_def: @ast::struct_def
 ) -> doc::StructDoc {
-    {
+    doc::StructDoc {
         item: itemdoc,
         fields: do struct_def.fields.map |field| {
             match field.node.kind {
diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs
index 29c53e0af25..f352ed7f7e7 100644
--- a/src/librustdoc/fold.rs
+++ b/src/librustdoc/fold.rs
@@ -158,7 +158,7 @@ pub fn default_par_fold<T:Owned Clone>(+ctxt: T) -> Fold<T> {
 }
 
 pub fn default_seq_fold_doc<T>(fold: &Fold<T>, +doc: doc::Doc) -> doc::Doc {
-    doc::Doc_({
+    doc::Doc_(doc::Doc_ {
         pages: do vec::map(doc.pages) |page| {
             match *page {
               doc::CratePage(doc) => {
@@ -177,7 +177,7 @@ pub fn default_seq_fold_crate<T>(
     fold: &Fold<T>,
     +doc: doc::CrateDoc
 ) -> doc::CrateDoc {
-    {
+    doc::CrateDoc {
         topmod: (fold.fold_mod)(fold, doc.topmod)
     }
 }
@@ -194,7 +194,7 @@ pub fn default_any_fold_mod<T:Owned Clone>(
     +doc: doc::ModDoc
 ) -> doc::ModDoc {
     let fold_copy = fold.clone();
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         item: (fold.fold_item)(fold, doc.item),
         items: par::map(doc.items, |ItemTag, move fold_copy| {
             fold_ItemTag(&fold_copy, *ItemTag)
@@ -207,7 +207,7 @@ pub fn default_seq_fold_mod<T>(
     fold: &Fold<T>,
     +doc: doc::ModDoc
 ) -> doc::ModDoc {
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         item: (fold.fold_item)(fold, doc.item),
         items: vec::map(doc.items, |ItemTag| {
             fold_ItemTag(fold, *ItemTag)
@@ -221,7 +221,7 @@ pub fn default_par_fold_mod<T:Owned Clone>(
     +doc: doc::ModDoc
 ) -> doc::ModDoc {
     let fold_copy = fold.clone();
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         item: (fold.fold_item)(fold, doc.item),
         items: par::map(doc.items, |ItemTag, move fold_copy| {
             fold_ItemTag(&fold_copy, *ItemTag)
@@ -235,7 +235,7 @@ pub fn default_any_fold_nmod<T:Owned Clone>(
     +doc: doc::NmodDoc
 ) -> doc::NmodDoc {
     let fold_copy = fold.clone();
-    {
+    doc::NmodDoc {
         item: (fold.fold_item)(fold, doc.item),
         fns: par::map(doc.fns, |FnDoc, move fold_copy| {
             (fold_copy.fold_fn)(&fold_copy, *FnDoc)
@@ -248,7 +248,7 @@ pub fn default_seq_fold_nmod<T>(
     fold: &Fold<T>,
     +doc: doc::NmodDoc
 ) -> doc::NmodDoc {
-    {
+    doc::NmodDoc {
         item: (fold.fold_item)(fold, doc.item),
         fns: vec::map(doc.fns, |FnDoc| {
             (fold.fold_fn)(fold, *FnDoc)
@@ -262,7 +262,7 @@ pub fn default_par_fold_nmod<T:Owned Clone>(
     +doc: doc::NmodDoc
 ) -> doc::NmodDoc {
     let fold_copy = fold.clone();
-    {
+    doc::NmodDoc {
         item: (fold.fold_item)(fold, doc.item),
         fns: par::map(doc.fns, |FnDoc, move fold_copy| {
             (fold_copy.fold_fn)(&fold_copy, *FnDoc)
@@ -307,7 +307,7 @@ pub fn default_seq_fold_fn<T>(
     fold: &Fold<T>,
     +doc: doc::FnDoc
 ) -> doc::FnDoc {
-    {
+    doc::SimpleItemDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
@@ -317,7 +317,7 @@ pub fn default_seq_fold_const<T>(
     fold: &Fold<T>,
     +doc: doc::ConstDoc
 ) -> doc::ConstDoc {
-    {
+    doc::SimpleItemDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
@@ -327,7 +327,7 @@ pub fn default_seq_fold_enum<T>(
     fold: &Fold<T>,
     +doc: doc::EnumDoc
 ) -> doc::EnumDoc {
-    {
+    doc::EnumDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
@@ -337,7 +337,7 @@ pub fn default_seq_fold_trait<T>(
     fold: &Fold<T>,
     +doc: doc::TraitDoc
 ) -> doc::TraitDoc {
-    {
+    doc::TraitDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
@@ -347,7 +347,7 @@ pub fn default_seq_fold_impl<T>(
     fold: &Fold<T>,
     +doc: doc::ImplDoc
 ) -> doc::ImplDoc {
-    {
+    doc::ImplDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
@@ -357,7 +357,7 @@ pub fn default_seq_fold_type<T>(
     fold: &Fold<T>,
     +doc: doc::TyDoc
 ) -> doc::TyDoc {
-    {
+    doc::SimpleItemDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
@@ -367,7 +367,7 @@ pub fn default_seq_fold_struct<T>(
     fold: &Fold<T>,
     +doc: doc::StructDoc
 ) -> doc::StructDoc {
-    {
+    doc::StructDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
diff --git a/src/librustdoc/markdown_index_pass.rs b/src/librustdoc/markdown_index_pass.rs
index 1f4e1be62fc..b0b4278a91e 100644
--- a/src/librustdoc/markdown_index_pass.rs
+++ b/src/librustdoc/markdown_index_pass.rs
@@ -54,7 +54,7 @@ fn fold_mod(
 
     let doc = fold::default_any_fold_mod(fold, doc);
 
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         index: Some(build_mod_index(doc, fold.ctxt)),
         .. *doc
     })
@@ -67,7 +67,7 @@ fn fold_nmod(
 
     let doc = fold::default_any_fold_nmod(fold, doc);
 
-    {
+    doc::NmodDoc {
         index: Some(build_nmod_index(doc, fold.ctxt)),
         .. doc
     }
@@ -77,7 +77,7 @@ fn build_mod_index(
     +doc: doc::ModDoc,
     +config: config::Config
 ) -> doc::Index {
-    {
+    doc::Index {
         entries: par::map(doc.items, |doc| {
             item_to_entry(*doc, config)
         })
@@ -88,7 +88,7 @@ fn build_nmod_index(
     +doc: doc::NmodDoc,
     +config: config::Config
 ) -> doc::Index {
-    {
+    doc::Index {
         entries: par::map(doc.fns, |doc| {
             item_to_entry(doc::FnTag(*doc), config)
         })
@@ -109,7 +109,7 @@ fn item_to_entry(
       }
     };
 
-    {
+    doc::IndexEntry {
         kind: markdown_pass::header_kind(doc),
         name: markdown_pass::header_name(doc),
         brief: doc.brief(),
diff --git a/src/librustdoc/page_pass.rs b/src/librustdoc/page_pass.rs
index 2629d45635e..d121d7e8478 100644
--- a/src/librustdoc/page_pass.rs
+++ b/src/librustdoc/page_pass.rs
@@ -76,7 +76,7 @@ fn make_doc_from_pages(page_port: PagePort) -> doc::Doc {
             break;
         }
     }
-    doc::Doc_({
+    doc::Doc_(doc::Doc_ {
         pages: pages
     })
 }
@@ -100,7 +100,7 @@ fn fold_crate(
 
     let doc = fold::default_seq_fold_crate(fold, doc);
 
-    let page = doc::CratePage({
+    let page = doc::CratePage(doc::CrateDoc {
         topmod: strip_mod(doc.topmod),
         .. doc
     });
@@ -128,7 +128,7 @@ fn fold_mod(
 }
 
 fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc {
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         items: do doc.items.filtered |item| {
             match *item {
               doc::ModTag(_) => false,
diff --git a/src/librustdoc/path_pass.rs b/src/librustdoc/path_pass.rs
index 48ed1878771..bc69ea7ed5a 100644
--- a/src/librustdoc/path_pass.rs
+++ b/src/librustdoc/path_pass.rs
@@ -54,7 +54,7 @@ fn run(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc {
 }
 
 fn fold_item(fold: &fold::Fold<Ctxt>, +doc: doc::ItemDoc) -> doc::ItemDoc {
-    {
+    doc::ItemDoc {
         path: fold.ctxt.path,
         .. doc
     }
@@ -68,7 +68,7 @@ fn fold_mod(fold: &fold::Fold<Ctxt>, +doc: doc::ModDoc) -> doc::ModDoc {
     let doc = fold::default_any_fold_mod(fold, doc);
     if !is_topmod { fold.ctxt.path.pop(); }
 
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         item: (fold.fold_item)(fold, doc.item),
         .. *doc
     })
@@ -79,7 +79,7 @@ fn fold_nmod(fold: &fold::Fold<Ctxt>, +doc: doc::NmodDoc) -> doc::NmodDoc {
     let doc = fold::default_seq_fold_nmod(fold, doc);
     fold.ctxt.path.pop();
 
-    {
+    doc::NmodDoc {
         item: (fold.fold_item)(fold, doc.item),
         .. doc
     }
diff --git a/src/librustdoc/prune_hidden_pass.rs b/src/librustdoc/prune_hidden_pass.rs
index 3a924e3bddf..c3d31d4a5b0 100644
--- a/src/librustdoc/prune_hidden_pass.rs
+++ b/src/librustdoc/prune_hidden_pass.rs
@@ -42,7 +42,7 @@ fn fold_mod(
 ) -> doc::ModDoc {
     let doc = fold::default_any_fold_mod(fold, doc);
 
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         items: do doc.items.filtered |ItemTag| {
             !is_hidden(fold.ctxt, ItemTag.item())
         },
diff --git a/src/librustdoc/prune_private_pass.rs b/src/librustdoc/prune_private_pass.rs
index 3b11437aceb..a18530a7460 100644
--- a/src/librustdoc/prune_private_pass.rs
+++ b/src/librustdoc/prune_private_pass.rs
@@ -48,7 +48,7 @@ fn fold_mod(
 ) -> doc::ModDoc {
     let doc = fold::default_any_fold_mod(fold, doc);
 
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         items: doc.items.filtered(|ItemTag| {
             is_visible(fold.ctxt, ItemTag.item())
         }),
diff --git a/src/librustdoc/sectionalize_pass.rs b/src/librustdoc/sectionalize_pass.rs
index eeadd82371f..706aecf49b9 100644
--- a/src/librustdoc/sectionalize_pass.rs
+++ b/src/librustdoc/sectionalize_pass.rs
@@ -46,7 +46,7 @@ fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc {
     let doc = fold::default_seq_fold_item(fold, doc);
     let (desc, sections) = sectionalize(doc.desc);
 
-    {
+    doc::ItemDoc {
         desc: desc,
         sections: sections,
         .. doc
@@ -56,11 +56,11 @@ fn fold_item(fold: &fold::Fold<()>, +doc: doc::ItemDoc) -> doc::ItemDoc {
 fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc {
     let doc = fold::default_seq_fold_trait(fold, doc);
 
-    {
+    doc::TraitDoc {
         methods: do par::map(doc.methods) |method| {
             let (desc, sections) = sectionalize(method.desc);
 
-            {
+            doc::MethodDoc {
                 desc: desc,
                 sections: sections,
                 .. *method
@@ -73,11 +73,11 @@ fn fold_trait(fold: &fold::Fold<()>, +doc: doc::TraitDoc) -> doc::TraitDoc {
 fn fold_impl(fold: &fold::Fold<()>, +doc: doc::ImplDoc) -> doc::ImplDoc {
     let doc = fold::default_seq_fold_impl(fold, doc);
 
-    {
+    doc::ImplDoc {
         methods: do par::map(doc.methods) |method| {
             let (desc, sections) = sectionalize(method.desc);
 
-            {
+            doc::MethodDoc {
                 desc: desc,
                 sections: sections,
                 .. *method
@@ -121,7 +121,7 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
             if current_section.is_some() {
                 sections += ~[current_section.get()];
             }
-            current_section = Some({
+            current_section = Some(doc::Section {
                 header: header,
                 body: ~""
             });
@@ -129,7 +129,7 @@ fn sectionalize(desc: Option<~str>) -> (Option<~str>, ~[doc::Section]) {
           None => {
             match copy current_section {
               Some(section) => {
-                current_section = Some({
+                current_section = Some(doc::Section {
                     body: section.body + ~"\n" + *line,
                     .. section
                 });
diff --git a/src/librustdoc/sort_pass.rs b/src/librustdoc/sort_pass.rs
index b3ecb8173fe..42759be68ad 100644
--- a/src/librustdoc/sort_pass.rs
+++ b/src/librustdoc/sort_pass.rs
@@ -55,7 +55,7 @@ fn fold_mod(
     +doc: doc::ModDoc
 ) -> doc::ModDoc {
     let doc = fold::default_any_fold_mod(fold, doc);
-    doc::ModDoc_({
+    doc::ModDoc_(doc::ModDoc_ {
         items: sort::merge_sort(doc.items, fold.ctxt.op),
         .. *doc
     })
diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs
index 5627bfead9f..fb55641b764 100644
--- a/src/librustdoc/text_pass.rs
+++ b/src/librustdoc/text_pass.rs
@@ -62,7 +62,7 @@ fn fold_item(
 ) -> doc::ItemDoc {
     let doc = fold::default_seq_fold_item(fold, doc);
 
-    {
+    doc::ItemDoc {
         brief: maybe_apply_op(fold.ctxt, doc.brief),
         desc: maybe_apply_op(fold.ctxt, doc.desc),
         sections: apply_to_sections(fold.ctxt, doc.sections),
@@ -74,7 +74,7 @@ fn apply_to_sections(
     op: NominalOp<Op>,
     sections: ~[doc::Section]
 ) -> ~[doc::Section] {
-    par::map(sections, |section, copy op| {
+    par::map(sections, |section, copy op| doc::Section {
         header: (op.op)(section.header),
         body: (op.op)(section.body)
     })
@@ -86,9 +86,9 @@ fn fold_enum(
     let doc = fold::default_seq_fold_enum(fold, doc);
     let fold_copy = copy *fold;
 
-    {
+    doc::EnumDoc {
         variants: do par::map(doc.variants) |variant, copy fold_copy| {
-            {
+            doc::VariantDoc {
                 desc: maybe_apply_op(fold_copy.ctxt, variant.desc),
                 .. *variant
             }
@@ -103,7 +103,7 @@ fn fold_trait(
 ) -> doc::TraitDoc {
     let doc = fold::default_seq_fold_trait(fold, doc);
 
-    {
+    doc::TraitDoc {
         methods: apply_to_methods(fold.ctxt, doc.methods),
         .. doc
     }
@@ -114,7 +114,7 @@ fn apply_to_methods(
     docs: ~[doc::MethodDoc]
 ) -> ~[doc::MethodDoc] {
     do par::map(docs) |doc, copy op| {
-        {
+        doc::MethodDoc {
             brief: maybe_apply_op(op, doc.brief),
             desc: maybe_apply_op(op, doc.desc),
             sections: apply_to_sections(op, doc.sections),
@@ -129,7 +129,7 @@ fn fold_impl(
 ) -> doc::ImplDoc {
     let doc = fold::default_seq_fold_impl(fold, doc);
 
-    {
+    doc::ImplDoc {
         methods: apply_to_methods(fold.ctxt, doc.methods),
         .. doc
     }
diff --git a/src/librustdoc/tystr_pass.rs b/src/librustdoc/tystr_pass.rs
index 5d92ed14c18..3b9991d1827 100644
--- a/src/librustdoc/tystr_pass.rs
+++ b/src/librustdoc/tystr_pass.rs
@@ -59,7 +59,7 @@ fn fold_fn(
 
     let srv = fold.ctxt;
 
-    {
+    doc::SimpleItemDoc {
         sig: get_fn_sig(srv, doc.id()),
         .. doc
     }
@@ -101,7 +101,7 @@ fn fold_const(
 ) -> doc::ConstDoc {
     let srv = fold.ctxt;
 
-    {
+    doc::SimpleItemDoc {
         sig: Some(do astsrv::exec(srv) |ctxt| {
             match ctxt.ast_map.get(doc.id()) {
               ast_map::node_item(@ast::item {
@@ -129,7 +129,7 @@ fn fold_enum(
     let doc_id = doc.id();
     let srv = fold.ctxt;
 
-    {
+    doc::EnumDoc {
         variants: do par::map(doc.variants) |variant| {
             let variant = *variant;
             let sig = do astsrv::exec(srv) |ctxt| {
@@ -148,7 +148,7 @@ fn fold_enum(
                 }
             };
 
-            {
+            doc::VariantDoc {
                 sig: Some(sig),
                 .. variant
             }
@@ -167,7 +167,7 @@ fn fold_trait(
     fold: &fold::Fold<astsrv::Srv>,
     +doc: doc::TraitDoc
 ) -> doc::TraitDoc {
-    {
+    doc::TraitDoc {
         methods: merge_methods(fold.ctxt, doc.id(), doc.methods),
         .. doc
     }
@@ -179,7 +179,7 @@ fn merge_methods(
     docs: ~[doc::MethodDoc]
 ) -> ~[doc::MethodDoc] {
     do par::map(docs) |doc| {
-        {
+        doc::MethodDoc {
             sig: get_method_sig(srv, item_id, doc.name),
             .. *doc
         }
@@ -276,7 +276,7 @@ fn fold_impl(
         }
     };
 
-    {
+    doc::ImplDoc {
         trait_types: trait_types,
         self_ty: self_ty,
         methods: merge_methods(fold.ctxt, doc.id(), doc.methods),
@@ -316,7 +316,7 @@ fn fold_type(
 
     let srv = fold.ctxt;
 
-    {
+    doc::SimpleItemDoc {
         sig: do astsrv::exec(srv) |ctxt| {
             match ctxt.ast_map.get(doc.id()) {
               ast_map::node_item(@ast::item {
@@ -349,7 +349,7 @@ fn fold_struct(
 ) -> doc::StructDoc {
     let srv = fold.ctxt;
 
-    {
+    doc::StructDoc {
         sig: do astsrv::exec(srv) |ctxt| {
             match ctxt.ast_map.get(doc.id()) {
                 ast_map::node_item(item, _) => {
diff --git a/src/libstd/bigint.rs b/src/libstd/bigint.rs
index fc783429126..4283a7e402b 100644
--- a/src/libstd/bigint.rs
+++ b/src/libstd/bigint.rs
@@ -17,7 +17,7 @@ A BigInt is a combination of BigUint and Sign.
 */
 
 use core::cmp::{Eq, Ord};
-use core::num::{Num, Zero, One};
+use core::num::{IntConvertible, Zero, One};
 use core::*;
 
 /**
@@ -121,7 +121,7 @@ impl BigUint : One {
     static pub pure fn one() -> BigUint { BigUint::new(~[1]) }
 }
 
-impl BigUint : Num {
+impl BigUint : Add<BigUint, BigUint> {
     pure fn add(&self, other: &BigUint) -> BigUint {
         let new_len = uint::max(self.data.len(), other.data.len());
 
@@ -138,7 +138,9 @@ impl BigUint : Num {
         if carry == 0 { return BigUint::new(sum) };
         return BigUint::new(sum + [carry]);
     }
+}
 
+impl BigUint : Sub<BigUint, BigUint> {
     pure fn sub(&self, other: &BigUint) -> BigUint {
         let new_len = uint::max(self.data.len(), other.data.len());
 
@@ -161,7 +163,9 @@ impl BigUint : Num {
         assert borrow == 0;     // <=> assert (self >= other);
         return BigUint::new(diff);
     }
+}
 
+impl BigUint : Mul<BigUint, BigUint> {
     pure fn mul(&self, other: &BigUint) -> BigUint {
         if self.is_zero() || other.is_zero() { return Zero::zero(); }
 
@@ -224,18 +228,27 @@ impl BigUint : Num {
             }
         }
     }
+}
 
+impl BigUint : Div<BigUint, BigUint> {
     pure fn div(&self, other: &BigUint) -> BigUint {
         let (d, _) = self.divmod(other);
         return d;
     }
+}
+
+impl BigUint : Modulo<BigUint, BigUint> {
     pure fn modulo(&self, other: &BigUint) -> BigUint {
         let (_, m) = self.divmod(other);
         return m;
     }
+}
 
+impl BigUint : Neg<BigUint> {
     pure fn neg(&self) -> BigUint { fail }
+}
 
+impl BigUint : IntConvertible {
     pure fn to_int(&self) -> int {
         uint::min(self.to_uint(), int::max_value as uint) as int
     }
@@ -625,7 +638,7 @@ impl BigInt : One {
     }
 }
 
-impl BigInt : Num {
+impl BigInt : Add<BigInt, BigInt> {
     pure fn add(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)      => copy *other,
@@ -637,6 +650,9 @@ impl BigInt : Num {
             (Minus, Minus) => -((-self) + (-*other))
         }
     }
+}
+
+impl BigInt : Sub<BigInt, BigInt> {
     pure fn sub(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)    => -other,
@@ -654,6 +670,9 @@ impl BigInt : Num {
             (Minus, Minus) => (-other) - (-*self)
         }
     }
+}
+
+impl BigInt : Mul<BigInt, BigInt> {
     pure fn mul(&self, other: &BigInt) -> BigInt {
         match (self.sign, other.sign) {
             (Zero, _)     | (_,     Zero)  => Zero::zero(),
@@ -665,18 +684,29 @@ impl BigInt : Num {
             }
         }
     }
+}
+
+impl BigInt : Div<BigInt, BigInt> {
     pure fn div(&self, other: &BigInt) -> BigInt {
         let (d, _) = self.divmod(other);
         return d;
     }
+}
+
+impl BigInt : Modulo<BigInt, BigInt> {
     pure fn modulo(&self, other: &BigInt) -> BigInt {
         let (_, m) = self.divmod(other);
         return m;
     }
+}
+
+impl BigInt : Neg<BigInt> {
     pure fn neg(&self) -> BigInt {
         BigInt::from_biguint(self.sign.neg(), copy self.data)
     }
+}
 
+impl BigInt : IntConvertible {
     pure fn to_int(&self) -> int {
         match self.sign {
             Plus  => uint::min(self.to_uint(), int::max_value as uint) as int,
@@ -834,7 +864,7 @@ pub impl BigInt {
 mod biguint_tests {
 
     use core::*;
-    use core::num::{Num, Zero, One};
+    use num::{IntConvertible, Zero, One};
     use super::{BigInt, BigUint, BigDigit};
 
     #[test]
@@ -974,7 +1004,7 @@ mod biguint_tests {
     fn test_convert_int() {
         fn check(v: ~[BigDigit], i: int) {
             let b = BigUint::new(v);
-            assert b == Num::from_int(i);
+            assert b == IntConvertible::from_int(i);
             assert b.to_int() == i;
         }
 
@@ -1244,7 +1274,7 @@ mod bigint_tests {
     use super::{BigInt, BigUint, BigDigit, Sign, Minus, Zero, Plus};
 
     use core::*;
-    use core::num::{Num, Zero, One};
+    use core::num::{IntConvertible, Zero, One};
 
     #[test]
     fn test_from_biguint() {
@@ -1303,7 +1333,7 @@ mod bigint_tests {
     #[test]
     fn test_convert_int() {
         fn check(b: BigInt, i: int) {
-            assert b == Num::from_int(i);
+            assert b == IntConvertible::from_int(i);
             assert b.to_int() == i;
         }
 
@@ -1563,7 +1593,8 @@ mod bigint_tests {
     #[test]
     fn test_to_str_radix() {
         fn check(n: int, ans: &str) {
-            assert ans == Num::from_int::<BigInt>(n).to_str_radix(10);
+            assert ans == IntConvertible::from_int::<BigInt>(
+                n).to_str_radix(10);
         }
         check(10, "10");
         check(1, "1");
@@ -1576,7 +1607,7 @@ mod bigint_tests {
     #[test]
     fn test_from_str_radix() {
         fn check(s: &str, ans: Option<int>) {
-            let ans = ans.map(|&n| Num::from_int(n));
+            let ans = ans.map(|&n| IntConvertible::from_int(n));
             assert BigInt::from_str_radix(s, 10) == ans;
         }
         check("10", Some(10));
diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs
index b4217dfb39d..2abd59523a1 100644
--- a/src/libstd/deque.rs
+++ b/src/libstd/deque.rs
@@ -249,69 +249,19 @@ mod tests {
         assert deq.get(3) == d;
     }
 
+    #[deriving_eq]
     enum Taggy { One(int), Two(int, int), Three(int, int, int), }
 
+    #[deriving_eq]
     enum Taggypar<T> {
         Onepar(int), Twopar(int, int), Threepar(int, int, int),
     }
 
+    #[deriving_eq]
     struct RecCy {
         x: int,
         y: int,
-        t: Taggy,
-    }
-
-    impl Taggy : Eq {
-        pure fn eq(&self, other: &Taggy) -> bool {
-            match (*self) {
-              One(a1) => match (*other) {
-                One(b1) => return a1 == b1,
-                _ => return false
-              },
-              Two(a1, a2) => match (*other) {
-                Two(b1, b2) => return a1 == b1 && a2 == b2,
-                _ => return false
-              },
-              Three(a1, a2, a3) => match (*other) {
-                Three(b1, b2, b3) => return a1 == b1 && a2 == b2 && a3 == b3,
-                _ => return false
-              }
-            }
-        }
-        pure fn ne(&self, other: &Taggy) -> bool { !(*self).eq(other) }
-    }
-
-    impl Taggypar<int> : Eq {
-        //let eq4: EqFn<Taggypar<int>> = |x,y| taggypareq::<int>(x, y);
-        pure fn eq(&self, other: &Taggypar<int>) -> bool {
-                  match (*self) {
-                    Onepar::<int>(a1) => match (*other) {
-                      Onepar::<int>(b1) => return a1 == b1,
-                      _ => return false
-                    },
-                    Twopar::<int>(a1, a2) => match (*other) {
-                      Twopar::<int>(b1, b2) => return a1 == b1 && a2 == b2,
-                      _ => return false
-                    },
-                    Threepar::<int>(a1, a2, a3) => match (*other) {
-                      Threepar::<int>(b1, b2, b3) => {
-                          return a1 == b1 && a2 == b2 && a3 == b3
-                      }
-                      _ => return false
-                    }
-                  }
-        }
-        pure fn ne(&self, other: &Taggypar<int>) -> bool {
-            !(*self).eq(other)
-        }
-    }
-
-    impl RecCy : Eq {
-        pure fn eq(&self, other: &RecCy) -> bool {
-          return (*self).x == (*other).x && (*self).y == (*other).y &&
-                 (*self).t == (*other).t;
-        }
-        pure fn ne(&self, other: &RecCy) -> bool { !(*self).eq(other) }
+        t: Taggy
     }
 
     #[test]
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index dc379cec21b..f93705c0c62 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -676,6 +676,7 @@ pub mod writer {
 mod tests {
     use ebml::reader;
     use ebml::writer;
+    use serialize::Encodable;
     use serialize;
 
     use core::io;
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 45d467095fb..1361d8647b5 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -15,6 +15,7 @@
 
 //! json serialization
 
+use serialize::Encodable;
 use serialize;
 use sort::Sort;
 
diff --git a/src/libstd/map.rs b/src/libstd/map.rs
index 3c890ef0654..f3016e9df21 100644
--- a/src/libstd/map.rs
+++ b/src/libstd/map.rs
@@ -28,7 +28,7 @@ pub type Set<K:Eq IterBytes Hash> = HashMap<K, ()>;
 
 pub type HashMap<K:Eq IterBytes Hash, V> = chained::T<K, V>;
 
-pub trait Map<K:Eq IterBytes Hash Copy, V: Copy> {
+pub trait StdMap<K:Eq IterBytes Hash Copy, V: Copy> {
     /// Return the number of elements in the map
     pure fn size() -> uint;
 
@@ -124,7 +124,7 @@ pub mod util {
 // FIXME (#2344): package this up and export it as a datatype usable for
 // external code that doesn't want to pay the cost of a box.
 pub mod chained {
-    use map::{Map, util};
+    use map::{StdMap, util};
 
     use core::io;
     use core::ops;
@@ -239,7 +239,7 @@ pub mod chained {
         }
     }
 
-    impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V>: Map<K, V> {
+    impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V>: StdMap<K, V> {
         pure fn size() -> uint { self.count }
 
         pure fn contains_key(k: K) -> bool {
diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs
index 5f16f7155b6..f17fce28ea9 100644
--- a/src/libstd/smallintmap.rs
+++ b/src/libstd/smallintmap.rs
@@ -15,7 +15,7 @@
 #[forbid(deprecated_mode)];
 
 use map;
-use map::Map;
+use map::StdMap;
 
 use core::dvec::DVec;
 use core::ops;
@@ -81,7 +81,7 @@ pub pure fn contains_key<T: Copy>(self: SmallIntMap<T>, key: uint) -> bool {
 }
 
 /// Implements the map::map interface for smallintmap
-impl<V: Copy> SmallIntMap<V>: map::Map<uint, V> {
+impl<V: Copy> SmallIntMap<V>: map::StdMap<uint, V> {
     pure fn size() -> uint {
         let mut sz = 0u;
         for self.v.each |item| {
@@ -165,8 +165,8 @@ impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> {
 }
 
 /// Cast the given smallintmap to a map::map
-pub fn as_map<V: Copy>(s: SmallIntMap<V>) -> map::Map<uint, V> {
-    s as map::Map::<uint, V>
+pub fn as_map<V: Copy>(s: SmallIntMap<V>) -> map::StdMap<uint, V> {
+    s as map::StdMap::<uint, V>
 }
 
 #[cfg(test)]
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index ddd0f846f9d..201d53c0c3f 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -12,7 +12,7 @@ use core::prelude::*;
 
 use ast::*;
 use ast;
-use ast_util::{path_to_ident, stmt_id};
+use ast_util::{inlined_item_utils, path_to_ident, stmt_id};
 use ast_util;
 use attr;
 use codemap;
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 23ea27e7c5c..7b134a8db24 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -376,7 +376,7 @@ pure fn struct_field_visibility(field: ast::struct_field) -> visibility {
     }
 }
 
-trait inlined_item_utils {
+pub trait inlined_item_utils {
     fn ident() -> ident;
     fn id() -> ast::node_id;
     fn accept<E>(e: E, v: visit::vt<E>);
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 7a7c2312f56..7e3cbd18f52 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -33,7 +33,7 @@ use core::uint;
 use core::vec;
 use std::serialize::{Encodable, Decodable, Encoder, Decoder};
 
-trait Pos {
+pub trait Pos {
     static pure fn from_uint(n: uint) -> self;
     pure fn to_uint(&self) -> uint;
 }
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 6112313cf48..4c0cc161fdd 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -10,7 +10,7 @@
 
 use core::prelude::*;
 
-use codemap::span;
+use codemap::{Pos, span};
 use codemap;
 
 use core::cmp;
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 343ce4b039b..8a5b8a127d0 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -66,7 +66,7 @@ impl @ast::path: append_types {
     }
 }
 
-trait ext_ctxt_ast_builder {
+pub trait ext_ctxt_ast_builder {
     fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
         -> ast::ty_param;
     fn arg(name: ident, ty: @ast::Ty) -> ast::arg;
diff --git a/src/libsyntax/ext/pipes/mod.rs b/src/libsyntax/ext/pipes/mod.rs
index 8eef065395e..f91ec1ea48f 100644
--- a/src/libsyntax/ext/pipes/mod.rs
+++ b/src/libsyntax/ext/pipes/mod.rs
@@ -49,6 +49,7 @@ use codemap::span;
 use ext::base;
 use ext::base::ext_ctxt;
 use ext::pipes::parse_proto::proto_parser;
+use ext::pipes::pipec::gen_init;
 use ext::pipes::proto::{visit, protocol};
 use parse::lexer::{new_tt_reader, reader};
 use parse::parser::Parser;
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index e53057cb312..774a5596258 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -13,7 +13,8 @@
 use ast::ident;
 use ast_util::dummy_sp;
 use ext::base::ext_ctxt;
-use ext::pipes::ast_builder::{append_types, path, path_global};
+use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path};
+use ext::pipes::ast_builder::{path_global};
 use ext::pipes::proto::*;
 use ext::quote::rt::*;
 use parse::*;
@@ -35,7 +36,7 @@ trait to_type_decls {
     fn to_endpoint_decls(cx: ext_ctxt, dir: direction) -> ~[@ast::item];
 }
 
-trait gen_init {
+pub trait gen_init {
     fn gen_init(cx: ext_ctxt) -> @ast::item;
     fn compile(cx: ext_ctxt) -> @ast::item;
     fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty;
diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs
index 26638cd8cd6..9d24b3db724 100644
--- a/src/libsyntax/ext/pipes/proto.rs
+++ b/src/libsyntax/ext/pipes/proto.rs
@@ -13,7 +13,7 @@ use core::prelude::*;
 use ast;
 use codemap::span;
 use ext::base::ext_ctxt;
-use ext::pipes::ast_builder::{path, append_types};
+use ext::pipes::ast_builder::{append_types, ext_ctxt_ast_builder, path};
 
 use core::cmp;
 use core::dvec::DVec;
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 3354d015476..7605e01fbf0 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -10,7 +10,7 @@
 
 use ast;
 use attr;
-use codemap::{span, BytePos};
+use codemap::{BytePos, Pos, span};
 use ext::base::ext_ctxt;
 use ext::base;
 use ext::build;
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 3ade0bf86b1..4ecbbdc9760 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use codemap;
-use codemap::{span, Loc, FileMap};
+use codemap::{FileMap, Loc, Pos, span};
 use ext::base::*;
 use ext::base;
 use ext::build::{mk_base_vec_e, mk_uint, mk_u8, mk_base_str};
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 66c3111b309..fbe258852e2 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -11,7 +11,7 @@
 use core::prelude::*;
 
 use ast;
-use codemap::{BytePos, CharPos, CodeMap, FileMap};
+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};
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 1574a037a46..5a0f40f3c12 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -12,7 +12,7 @@ use core::prelude::*;
 
 use ast;
 use ast_util;
-use codemap::{span, CodeMap, CharPos, BytePos};
+use codemap::{BytePos, CharPos, CodeMap, Pos, span};
 use codemap;
 use diagnostic::span_handler;
 use ext::tt::transcribe::{tt_next_token};
diff --git a/src/test/auxiliary/issue_2242_b.rs b/src/test/auxiliary/issue_2242_b.rs
deleted file mode 100644
index 73ec1f47230..00000000000
--- a/src/test/auxiliary/issue_2242_b.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.
-
-#[link(name = "b", vers = "0.1")];
-#[crate_type = "lib"];
-
-extern mod a;
-use a::to_strz;
-
-impl int: to_strz {
-    fn to_strz() -> ~str { fmt!("%?", self) }
-}
diff --git a/src/test/compile-fail/drop-on-non-struct.rs b/src/test/compile-fail/drop-on-non-struct.rs
index 95512a2da60..69880272350 100644
--- a/src/test/compile-fail/drop-on-non-struct.rs
+++ b/src/test/compile-fail/drop-on-non-struct.rs
@@ -11,6 +11,7 @@
 type Foo = @[u8];
 
 impl Foo : Drop {   //~ ERROR the Drop trait may only be implemented
+//~^ ERROR cannot provide an extension implementation
     fn finalize(&self) {
         io::println("kaboom");
     }
diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs
index 89377eb3d15..7161e854447 100644
--- a/src/test/compile-fail/map-types.rs
+++ b/src/test/compile-fail/map-types.rs
@@ -11,12 +11,13 @@
 extern mod std;
 use std::map;
 use std::map::HashMap;
-use std::map::Map;
+use std::map::StdMap;
 
 // Test that trait types printed in error msgs include the type arguments.
 
 fn main() {
-    let x: Map<~str,~str> = map::HashMap::<~str,~str>() as Map::<~str,~str>;
-    let y: Map<uint,~str> = x;
-    //~^ ERROR mismatched types: expected `@std::map::Map<uint,~str>`
+    let x: StdMap<~str,~str> = map::HashMap::<~str,~str>() as
+        StdMap::<~str,~str>;
+    let y: StdMap<uint,~str> = x;
+    //~^ ERROR mismatched types: expected `@std::map::StdMap<uint,~str>`
 }
diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs
index 6ea08d200e7..ec73704ca27 100644
--- a/src/test/run-pass/auto-encode.rs
+++ b/src/test/run-pass/auto-encode.rs
@@ -128,19 +128,16 @@ impl CLike : cmp::Eq {
 
 #[auto_encode]
 #[auto_decode]
+#[deriving_eq]
 struct Spanned<T> {
     lo: uint,
     hi: uint,
     node: T,
 }
 
-impl<T:cmp::Eq> Spanned<T> : cmp::Eq {
-    pure fn eq(&self, other: &Spanned<T>) -> bool {
-        self.lo == other.lo &&
-        self.hi == other.hi &&
-        self.node == other.node
-    }
-    pure fn ne(&self, other: &Spanned<T>) -> bool { !self.eq(other) }
+enum AnEnum {
+    AVariant,
+    AnotherVariant
 }
 
 #[auto_encode]
diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs
index b802b970892..6bc88188452 100644
--- a/src/test/run-pass/class-impl-very-parameterized-trait.rs
+++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs
@@ -51,7 +51,7 @@ impl<T: Copy> cat<T> {
   }
 }
 
-impl<T: Copy> cat<T> : Map<int, T> {
+impl<T: Copy> cat<T> : StdMap<int, T> {
   pure fn size() -> uint { self.meows as uint }
   fn insert(+k: int, +_v: T) -> bool {
     self.meows += k;
diff --git a/src/test/run-pass/issue-2242-d.rs b/src/test/run-pass/issue-2242-d.rs
deleted file mode 100644
index 006a33ebb65..00000000000
--- a/src/test/run-pass/issue-2242-d.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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.
-
-// xfail-fast (aux-build)
-// aux-build:issue_2242_a.rs
-// aux-build:issue_2242_b.rs
-// aux-build:issue_2242_c.rs
-
-extern mod a;
-extern mod b;
-extern mod c;
-
-use a::to_strz;
-
-fn main() {
-    io::println((~"foo").to_strz());
-    io::println(1.to_strz());
-    io::println(true.to_strz());
-}