about summary refs log tree commit diff
path: root/src/rustc/metadata
diff options
context:
space:
mode:
authorSimon BD <simon@server>2012-10-22 18:33:41 -0500
committerSimon BD <simon@server>2012-10-22 18:33:41 -0500
commitcc0f2c6bb26ba38d3487a396fa8625e938af6820 (patch)
tree6c2063df35144c5477b0adc9e49933d71224dc2a /src/rustc/metadata
parent9aec7a3e85c5b07923eab05d3ebe9d031bf258f3 (diff)
parent9ee5fff4f16cfc3390bd69abbb46b0a68521667c (diff)
downloadrust-cc0f2c6bb26ba38d3487a396fa8625e938af6820.tar.gz
rust-cc0f2c6bb26ba38d3487a396fa8625e938af6820.zip
Merge remote-tracking branch 'original/incoming' into incoming
Diffstat (limited to 'src/rustc/metadata')
-rw-r--r--src/rustc/metadata/common.rs4
-rw-r--r--src/rustc/metadata/creader.rs8
-rw-r--r--src/rustc/metadata/csearch.rs57
-rw-r--r--src/rustc/metadata/cstore.rs40
-rw-r--r--src/rustc/metadata/decoder.rs218
-rw-r--r--src/rustc/metadata/encoder.rs176
-rw-r--r--src/rustc/metadata/filesearch.rs12
-rw-r--r--src/rustc/metadata/loader.rs6
-rw-r--r--src/rustc/metadata/tydecode.rs2
-rw-r--r--src/rustc/metadata/tyencode.rs2
10 files changed, 356 insertions, 169 deletions
diff --git a/src/rustc/metadata/common.rs b/src/rustc/metadata/common.rs
index 1857abf2cf2..06f1dfdab1a 100644
--- a/src/rustc/metadata/common.rs
+++ b/src/rustc/metadata/common.rs
@@ -124,5 +124,9 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
     tag_table_legacy_boxed_trait = 0x63
 }
 
+const tag_item_trait_method_sort: uint = 0x70;
+
+const tag_item_impl_type_basename: uint = 0x71;
+
 type link_meta = {name: ~str, vers: ~str, extras_hash: ~str};
 
diff --git a/src/rustc/metadata/creader.rs b/src/rustc/metadata/creader.rs
index 3ed56a1953e..3080426e531 100644
--- a/src/rustc/metadata/creader.rs
+++ b/src/rustc/metadata/creader.rs
@@ -7,7 +7,7 @@ use syntax::visit;
 use syntax::codemap::span;
 use std::map::HashMap;
 use syntax::print::pprust;
-use filesearch::filesearch;
+use filesearch::FileSearch;
 use common::*;
 use dvec::DVec;
 use syntax::parse::token::ident_interner;
@@ -17,7 +17,7 @@ export read_crates;
 // Traverses an AST, reading all the information about use'd crates and extern
 // libraries necessary for later resolving, typechecking, linking, etc.
 fn read_crates(diag: span_handler, crate: ast::crate,
-               cstore: cstore::cstore, filesearch: filesearch,
+               cstore: cstore::CStore, filesearch: FileSearch,
                os: loader::os, static: bool, intr: @ident_interner) {
     let e = @{diag: diag,
               filesearch: filesearch,
@@ -88,8 +88,8 @@ fn warn_if_multiple_versions(e: env, diag: span_handler,
 }
 
 type env = @{diag: span_handler,
-             filesearch: filesearch,
-             cstore: cstore::cstore,
+             filesearch: FileSearch,
+             cstore: cstore::CStore,
              os: loader::os,
              static: bool,
              crate_cache: DVec<cache_entry>,
diff --git a/src/rustc/metadata/csearch.rs b/src/rustc/metadata/csearch.rs
index e29a4fd436b..141613c2240 100644
--- a/src/rustc/metadata/csearch.rs
+++ b/src/rustc/metadata/csearch.rs
@@ -1,6 +1,6 @@
 // Searching for information from the cstore
 
-use std::{ebml};
+use std::ebml;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::ast_map;
@@ -23,7 +23,10 @@ export get_region_param;
 export get_enum_variants;
 export get_impls_for_mod;
 export get_trait_methods;
+export get_provided_trait_methods;
 export get_method_names_if_trait;
+export get_type_name_if_impl;
+export get_static_methods_if_impl;
 export get_item_attrs;
 export each_path;
 export get_type;
@@ -31,19 +34,32 @@ export get_impl_traits;
 export get_impl_method;
 export get_item_path;
 export maybe_get_item_ast, found_ast, found, found_parent, not_found;
+export ProvidedTraitMethodInfo;
+export StaticMethodInfo;
 
-fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> ~str {
+struct ProvidedTraitMethodInfo {
+    ty: ty::method,
+    def_id: ast::def_id
+}
+
+struct StaticMethodInfo {
+    ident: ast::ident,
+    def_id: ast::def_id,
+    purity: ast::purity
+}
+
+fn get_symbol(cstore: cstore::CStore, def: ast::def_id) -> ~str {
     let cdata = cstore::get_crate_data(cstore, def.crate).data;
     return decoder::get_symbol(cdata, def.node);
 }
 
-fn get_type_param_count(cstore: cstore::cstore, def: ast::def_id) -> uint {
+fn get_type_param_count(cstore: cstore::CStore, def: ast::def_id) -> uint {
     let cdata = cstore::get_crate_data(cstore, def.crate).data;
     return decoder::get_type_param_count(cdata, def.node);
 }
 
 /// Iterates over all the paths in the given crate.
-fn each_path(cstore: cstore::cstore, cnum: ast::crate_num,
+fn each_path(cstore: cstore::CStore, cnum: ast::crate_num,
              f: fn(decoder::path_entry) -> bool) {
     let crate_data = cstore::get_crate_data(cstore, cnum);
     decoder::each_path(cstore.intr, crate_data, f);
@@ -84,7 +100,7 @@ fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id)
     return decoder::get_enum_variants(cstore.intr, cdata, def.node, tcx)
 }
 
-fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
+fn get_impls_for_mod(cstore: cstore::CStore, def: ast::def_id,
                      name: Option<ast::ident>)
     -> @~[@decoder::_impl] {
     let cdata = cstore::get_crate_data(cstore, def.crate);
@@ -99,14 +115,33 @@ fn get_trait_methods(tcx: ty::ctxt, def: ast::def_id) -> @~[ty::method] {
     decoder::get_trait_methods(cstore.intr, cdata, def.node, tcx)
 }
 
-fn get_method_names_if_trait(cstore: cstore::cstore, def: ast::def_id)
+fn get_provided_trait_methods(tcx: ty::ctxt, def: ast::def_id) ->
+        ~[ProvidedTraitMethodInfo] {
+    let cstore = tcx.cstore;
+    let cdata = cstore::get_crate_data(cstore, def.crate);
+    decoder::get_provided_trait_methods(cstore.intr, cdata, def.node, tcx)
+}
+
+fn get_method_names_if_trait(cstore: cstore::CStore, def: ast::def_id)
     -> Option<@DVec<(ast::ident, ast::self_ty_)>> {
 
     let cdata = cstore::get_crate_data(cstore, def.crate);
     return decoder::get_method_names_if_trait(cstore.intr, cdata, def.node);
 }
 
-fn get_item_attrs(cstore: cstore::cstore,
+fn get_type_name_if_impl(cstore: cstore::CStore, def: ast::def_id) ->
+        Option<ast::ident> {
+    let cdata = cstore::get_crate_data(cstore, def.crate);
+    decoder::get_type_name_if_impl(cstore.intr, cdata, def.node)
+}
+
+fn get_static_methods_if_impl(cstore: cstore::CStore, def: ast::def_id) ->
+        Option<~[StaticMethodInfo]> {
+    let cdata = cstore::get_crate_data(cstore, def.crate);
+    decoder::get_static_methods_if_impl(cstore.intr, cdata, def.node)
+}
+
+fn get_item_attrs(cstore: cstore::CStore,
                   def_id: ast::def_id,
                   f: fn(~[@ast::meta_item])) {
 
@@ -126,7 +161,7 @@ fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_bounds_and_ty {
     decoder::get_type(cdata, def.node, tcx)
 }
 
-fn get_region_param(cstore: metadata::cstore::cstore,
+fn get_region_param(cstore: metadata::cstore::CStore,
                     def: ast::def_id) -> Option<ty::region_variance> {
     let cdata = cstore::get_crate_data(cstore, def.crate);
     return decoder::get_region_param(cdata, def.node);
@@ -163,7 +198,7 @@ fn get_impl_traits(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::t] {
     decoder::get_impl_traits(cdata, def.node, tcx)
 }
 
-fn get_impl_method(cstore: cstore::cstore,
+fn get_impl_method(cstore: cstore::CStore,
                    def: ast::def_id, mname: ast::ident)
     -> ast::def_id {
     let cdata = cstore::get_crate_data(cstore, def.crate);
@@ -174,7 +209,7 @@ fn get_impl_method(cstore: cstore::cstore,
    for their methods (so that get_trait_methods can be reused to get
    class methods), classes require a slightly different version of
    get_impl_method. Sigh. */
-fn get_class_method(cstore: cstore::cstore,
+fn get_class_method(cstore: cstore::CStore,
                     def: ast::def_id, mname: ast::ident)
     -> ast::def_id {
     let cdata = cstore::get_crate_data(cstore, def.crate);
@@ -182,7 +217,7 @@ fn get_class_method(cstore: cstore::cstore,
 }
 
 /* If def names a class with a dtor, return it. Otherwise, return none. */
-fn class_dtor(cstore: cstore::cstore, def: ast::def_id)
+fn class_dtor(cstore: cstore::CStore, def: ast::def_id)
     -> Option<ast::def_id> {
     let cdata = cstore::get_crate_data(cstore, def.crate);
     decoder::class_dtor(cdata, def.node)
diff --git a/src/rustc/metadata/cstore.rs b/src/rustc/metadata/cstore.rs
index d59464d58c7..6db3982297e 100644
--- a/src/rustc/metadata/cstore.rs
+++ b/src/rustc/metadata/cstore.rs
@@ -6,7 +6,7 @@ use std::map::HashMap;
 use syntax::{ast, attr};
 use syntax::parse::token::ident_interner;
 
-export cstore;
+export CStore;
 export cnum_map;
 export crate_metadata;
 export mk_cstore;
@@ -49,7 +49,7 @@ type crate_metadata = @{name: ~str,
 // other modules to access the cstore's private data. This could also be
 // achieved with an obj, but at the expense of a vtable. Not sure if this is a
 // good pattern or not.
-enum cstore { private(cstore_private), }
+enum CStore { private(cstore_private), }
 
 type cstore_private =
     @{metas: map::HashMap<ast::crate_num, crate_metadata>,
@@ -64,11 +64,11 @@ type cstore_private =
 type use_crate_map = map::HashMap<ast::node_id, ast::crate_num>;
 
 // Internal method to retrieve the data from the cstore
-pure fn p(cstore: cstore) -> cstore_private {
+pure fn p(cstore: CStore) -> cstore_private {
     match cstore { private(p) => p }
 }
 
-fn mk_cstore(intr: @ident_interner) -> cstore {
+fn mk_cstore(intr: @ident_interner) -> CStore {
     let meta_cache = map::HashMap();
     let crate_map = map::HashMap();
     let mod_path_map = HashMap();
@@ -81,21 +81,21 @@ fn mk_cstore(intr: @ident_interner) -> cstore {
                      intr: intr});
 }
 
-fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata {
+fn get_crate_data(cstore: CStore, cnum: ast::crate_num) -> crate_metadata {
     return p(cstore).metas.get(cnum);
 }
 
-fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> ~str {
+fn get_crate_hash(cstore: CStore, cnum: ast::crate_num) -> ~str {
     let cdata = get_crate_data(cstore, cnum);
     return decoder::get_crate_hash(cdata.data);
 }
 
-fn get_crate_vers(cstore: cstore, cnum: ast::crate_num) -> ~str {
+fn get_crate_vers(cstore: CStore, cnum: ast::crate_num) -> ~str {
     let cdata = get_crate_data(cstore, cnum);
     return decoder::get_crate_vers(cdata.data);
 }
 
-fn set_crate_data(cstore: cstore, cnum: ast::crate_num,
+fn set_crate_data(cstore: CStore, cnum: ast::crate_num,
                   data: crate_metadata) {
     p(cstore).metas.insert(cnum, data);
     for vec::each(decoder::get_crate_module_paths(cstore.intr, data)) |dp| {
@@ -105,25 +105,25 @@ fn set_crate_data(cstore: cstore, cnum: ast::crate_num,
     }
 }
 
-fn have_crate_data(cstore: cstore, cnum: ast::crate_num) -> bool {
+fn have_crate_data(cstore: CStore, cnum: ast::crate_num) -> bool {
     return p(cstore).metas.contains_key(cnum);
 }
 
-fn iter_crate_data(cstore: cstore, i: fn(ast::crate_num, crate_metadata)) {
+fn iter_crate_data(cstore: CStore, i: fn(ast::crate_num, crate_metadata)) {
     for p(cstore).metas.each |k,v| { i(k, v);};
 }
 
-fn add_used_crate_file(cstore: cstore, lib: &Path) {
+fn add_used_crate_file(cstore: CStore, lib: &Path) {
     if !vec::contains(p(cstore).used_crate_files, lib) {
         p(cstore).used_crate_files.push(copy *lib);
     }
 }
 
-fn get_used_crate_files(cstore: cstore) -> ~[Path] {
+fn get_used_crate_files(cstore: CStore) -> ~[Path] {
     return p(cstore).used_crate_files;
 }
 
-fn add_used_library(cstore: cstore, lib: ~str) -> bool {
+fn add_used_library(cstore: CStore, lib: ~str) -> bool {
     assert lib != ~"";
 
     if vec::contains(p(cstore).used_libraries, &lib) { return false; }
@@ -131,31 +131,31 @@ fn add_used_library(cstore: cstore, lib: ~str) -> bool {
     return true;
 }
 
-fn get_used_libraries(cstore: cstore) -> ~[~str] {
+fn get_used_libraries(cstore: CStore) -> ~[~str] {
     return p(cstore).used_libraries;
 }
 
-fn add_used_link_args(cstore: cstore, args: ~str) {
+fn add_used_link_args(cstore: CStore, args: ~str) {
     p(cstore).used_link_args.push_all(str::split_char(args, ' '));
 }
 
-fn get_used_link_args(cstore: cstore) -> ~[~str] {
+fn get_used_link_args(cstore: CStore) -> ~[~str] {
     return p(cstore).used_link_args;
 }
 
-fn add_use_stmt_cnum(cstore: cstore, use_id: ast::node_id,
+fn add_use_stmt_cnum(cstore: CStore, use_id: ast::node_id,
                      cnum: ast::crate_num) {
     p(cstore).use_crate_map.insert(use_id, cnum);
 }
 
-fn find_use_stmt_cnum(cstore: cstore,
+fn find_use_stmt_cnum(cstore: CStore,
                       use_id: ast::node_id) -> Option<ast::crate_num> {
     p(cstore).use_crate_map.find(use_id)
 }
 
 // returns hashes of crates directly used by this crate. Hashes are
 // sorted by crate name.
-fn get_dep_hashes(cstore: cstore) -> ~[~str] {
+fn get_dep_hashes(cstore: CStore) -> ~[~str] {
     type crate_hash = {name: ~str, hash: ~str};
     let mut result = ~[];
 
@@ -175,7 +175,7 @@ fn get_dep_hashes(cstore: cstore) -> ~[~str] {
     return vec::map(sorted, mapper);
 }
 
-fn get_path(cstore: cstore, d: ast::def_id) -> ~[~str] {
+fn get_path(cstore: CStore, d: ast::def_id) -> ~[~str] {
     option::map_default(&p(cstore).mod_path_map.find(d), ~[],
                         |ds| str::split_str(**ds, ~"::"))
 }
diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs
index 0e6bc2aee15..4e30132b1a7 100644
--- a/src/rustc/metadata/decoder.rs
+++ b/src/rustc/metadata/decoder.rs
@@ -1,7 +1,9 @@
 // Decoding metadata from a single crate's metadata
 
-use std::{ebml, map};
+use std::ebml;
+use std::map;
 use std::map::HashMap;
+use std::serialization::deserialize;
 use io::WriterUtil;
 use dvec::DVec;
 use syntax::{ast, ast_util};
@@ -17,6 +19,7 @@ use syntax::diagnostic::span_handler;
 use common::*;
 use syntax::parse::token::ident_interner;
 use hash::{Hash, HashUtil};
+use csearch::{ProvidedTraitMethodInfo, StaticMethodInfo};
 
 export class_dtor;
 export get_class_fields;
@@ -28,6 +31,7 @@ export get_type_param_count;
 export get_impl_traits;
 export get_class_method;
 export get_impl_method;
+export get_static_methods_if_impl;
 export lookup_def;
 export resolve_path;
 export get_crate_attributes;
@@ -38,7 +42,9 @@ export get_crate_hash;
 export get_crate_vers;
 export get_impls_for_mod;
 export get_trait_methods;
+export get_provided_trait_methods;
 export get_method_names_if_trait;
+export get_type_name_if_impl;
 export get_item_attrs;
 export get_crate_module_paths;
 export def_like;
@@ -69,10 +75,10 @@ fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) ->
     let table = ebml::get_doc(index, tag_index_table);
     let hash_pos = table.start + hash % 256u * 4u;
     let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4u) as uint;
-    let {tag:_, doc:bucket} = ebml::doc_at(d.data, pos);
+    let tagged_doc = ebml::doc_at(d.data, pos);
 
     let belt = tag_index_buckets_bucket_elt;
-    for ebml::tagged_docs(bucket, belt) |elt| {
+    for ebml::tagged_docs(tagged_doc.doc, belt) |elt| {
         let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint;
         if eq_fn(vec::view(*elt.data, elt.start + 4u, elt.end)) {
             return Some(ebml::doc_at(d.data, pos).doc);
@@ -122,7 +128,6 @@ enum Family {
     Variant,               // v
     Impl,                  // i
     Trait,                 // I
-    Class,                 // C
     Struct,                // S
     PublicField,           // g
     PrivateField,          // j
@@ -155,15 +160,21 @@ fn item_family(item: ebml::Doc) -> Family {
       'v' => Variant,
       'i' => Impl,
       'I' => Trait,
-      'C' => Class,
       'S' => Struct,
       'g' => PublicField,
       'j' => PrivateField,
       'N' => InheritedField,
-       c => fail (#fmt("unexpected family char: %c", c))
+       c => fail (fmt!("unexpected family char: %c", c))
     }
 }
 
+fn item_method_sort(item: ebml::Doc) -> char {
+    for ebml::tagged_docs(item, tag_item_trait_method_sort) |doc| {
+        return str::from_bytes(ebml::doc_data(doc))[0] as char;
+    }
+    return 'r';
+}
+
 fn item_symbol(item: ebml::Doc) -> ~str {
     let sym = ebml::get_doc(item, tag_items_data_item_symbol);
     return str::from_bytes(ebml::doc_data(sym));
@@ -176,6 +187,18 @@ fn item_parent_item(d: ebml::Doc) -> Option<ast::def_id> {
     None
 }
 
+fn translated_parent_item_opt(cnum: ast::crate_num, d: ebml::Doc) ->
+        Option<ast::def_id> {
+    let trait_did_opt = item_parent_item(d);
+    trait_did_opt.map(|trait_did| {crate: cnum, node: trait_did.node})
+}
+
+fn item_reqd_and_translated_parent_item(cnum: ast::crate_num,
+                                        d: ebml::Doc) -> ast::def_id {
+    let trait_did = item_parent_item(d).expect(~"item without parent");
+    {crate: cnum, node: trait_did.node}
+}
+
 fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id {
     let tagdoc = ebml::get_doc(d, tag_def_id);
     return translate_def_id(cdata, ebml::with_doc_data(tagdoc,
@@ -246,8 +269,7 @@ fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd)
 
 fn item_ty_region_param(item: ebml::Doc) -> Option<ty::region_variance> {
     ebml::maybe_get_doc(item, tag_region_param).map(|doc| {
-        let d = ebml::ebml_deserializer(*doc);
-        ty::deserialize_region_variance(d)
+        deserialize(&ebml::Deserializer(*doc))
     })
 }
 
@@ -296,35 +318,38 @@ fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident {
 }
 
 fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
-        -> def_like {
+    -> def_like
+{
     let fam = item_family(item);
     match fam {
-      Const     => dl_def(ast::def_const(did)),
-      Class     => dl_def(ast::def_class(did, true)),
-      Struct    => dl_def(ast::def_class(did, false)),
-      UnsafeFn  => dl_def(ast::def_fn(did, ast::unsafe_fn)),
-      Fn        => dl_def(ast::def_fn(did, ast::impure_fn)),
-      PureFn    => dl_def(ast::def_fn(did, ast::pure_fn)),
-      ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)),
-      UnsafeStaticMethod => dl_def(ast::def_static_method(did,
-                                                          ast::unsafe_fn)),
-      StaticMethod => dl_def(ast::def_static_method(did, ast::impure_fn)),
-      PureStaticMethod => dl_def(ast::def_static_method(did, ast::pure_fn)),
-      Type | ForeignType => dl_def(ast::def_ty(did)),
-      Mod => dl_def(ast::def_mod(did)),
-      ForeignMod => dl_def(ast::def_foreign_mod(did)),
-      Variant => {
-          match item_parent_item(item) {
-              Some(t) => {
-                let tid = {crate: cnum, node: t.node};
-                dl_def(ast::def_variant(tid, did))
-              }
-              None => fail ~"item_to_def_like: enum item has no parent"
-          }
-      }
-      Trait | Enum => dl_def(ast::def_ty(did)),
-      Impl => dl_impl(did),
-      PublicField | PrivateField | InheritedField => dl_field,
+        Const     => dl_def(ast::def_const(did)),
+        Struct    => dl_def(ast::def_class(did)),
+        UnsafeFn  => dl_def(ast::def_fn(did, ast::unsafe_fn)),
+        Fn        => dl_def(ast::def_fn(did, ast::impure_fn)),
+        PureFn    => dl_def(ast::def_fn(did, ast::pure_fn)),
+        ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)),
+        UnsafeStaticMethod => {
+            let trait_did_opt = translated_parent_item_opt(cnum, item);
+            dl_def(ast::def_static_method(did, trait_did_opt, ast::unsafe_fn))
+        }
+        StaticMethod => {
+            let trait_did_opt = translated_parent_item_opt(cnum, item);
+            dl_def(ast::def_static_method(did, trait_did_opt, ast::impure_fn))
+        }
+        PureStaticMethod => {
+            let trait_did_opt = translated_parent_item_opt(cnum, item);
+            dl_def(ast::def_static_method(did, trait_did_opt, ast::pure_fn))
+        }
+        Type | ForeignType => dl_def(ast::def_ty(did)),
+        Mod => dl_def(ast::def_mod(did)),
+        ForeignMod => dl_def(ast::def_foreign_mod(did)),
+        Variant => {
+            let enum_did = item_reqd_and_translated_parent_item(cnum, item);
+            dl_def(ast::def_variant(enum_did, did))
+        }
+        Trait | Enum => dl_def(ast::def_ty(did)),
+        Impl => dl_impl(did),
+        PublicField | PrivateField | InheritedField => dl_field,
     }
 }
 
@@ -581,13 +606,12 @@ fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id,
         let ctor_ty = item_type({crate: cdata.cnum, node: id}, item,
                                 tcx, cdata);
         let name = item_name(intr, item);
-        let mut arg_tys: ~[ty::t] = ~[];
-        match ty::get(ctor_ty).sty {
-          ty::ty_fn(f) => {
-            for f.sig.inputs.each |a| { arg_tys.push(a.ty); }
-          }
-          _ => { /* Nullary enum variant. */ }
-        }
+        let arg_tys = match ty::get(ctor_ty).sty {
+          ty::ty_fn(f) => f.sig.inputs.map(|a| a.ty),
+
+          // Nullary enum variant.
+          _ => ~[],
+        };
         match variant_disr_val(item) {
           Some(val) => { disr_val = val; }
           _         => { /* empty */ }
@@ -646,7 +670,6 @@ fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc,
         let mth_item = lookup_item(m_did.node, cdata.data);
         let self_ty = get_self_ty(mth_item);
         rslt.push(@{did: translate_def_id(cdata, m_did),
-                    /* FIXME (maybe #2323) tjc: take a look at this. */
                    n_tps: item_ty_param_count(mth_item) - base_tps,
                    ident: item_name(intr, mth_item),
                    self_type: self_ty});
@@ -694,6 +717,7 @@ fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id,
         let bounds = item_ty_param_bounds(mth, tcx, cdata);
         let name = item_name(intr, mth);
         let ty = doc_type(mth, tcx, cdata);
+        let def_id = item_def_id(mth, cdata);
         let fty = match ty::get(ty).sty {
           ty::ty_fn(f) => f,
           _ => {
@@ -701,14 +725,52 @@ fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id,
                 ~"get_trait_methods: id has non-function type");
         } };
         let self_ty = get_self_ty(mth);
-        result.push({ident: name, tps: bounds, fty: fty,
-                           self_ty: self_ty,
-                           vis: ast::public});
+        result.push({ident: name, tps: bounds, fty: fty, self_ty: self_ty,
+                     vis: ast::public, def_id: def_id});
     }
-    #debug("get_trait_methods: }");
+    debug!("get_trait_methods: }");
     @result
 }
 
+fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
+                              id: ast::node_id, tcx: ty::ctxt) ->
+        ~[ProvidedTraitMethodInfo] {
+    let data = cdata.data;
+    let item = lookup_item(id, data);
+    let mut result = ~[];
+
+    for ebml::tagged_docs(item, tag_item_trait_method) |mth| {
+        if item_method_sort(mth) != 'p' { loop; }
+
+        let did = item_def_id(mth, cdata);
+
+        let bounds = item_ty_param_bounds(mth, tcx, cdata);
+        let name = item_name(intr, mth);
+        let ty = doc_type(mth, tcx, cdata);
+
+        let fty;
+        match ty::get(ty).sty {
+            ty::ty_fn(f) => fty = f,
+            _ => {
+                tcx.diag.handler().bug(~"get_provided_trait_methods(): id \
+                                         has non-function type");
+            }
+        }
+
+        let self_ty = get_self_ty(mth);
+        let ty_method = {ident: name, tps: bounds, fty: fty, self_ty: self_ty,
+                         vis: ast::public, def_id: did};
+        let provided_trait_method_info = ProvidedTraitMethodInfo {
+            ty: ty_method,
+            def_id: did
+        };
+
+        vec::push(&mut result, move provided_trait_method_info);
+    }
+
+    return move result;
+}
+
 // If the item in question is a trait, returns its set of methods and
 // their self types. Otherwise, returns none. This overlaps in an
 // annoying way with get_trait_methods.
@@ -729,6 +791,67 @@ fn get_method_names_if_trait(intr: @ident_interner, cdata: cmd,
     return Some(resulting_methods);
 }
 
+fn get_type_name_if_impl(intr: @ident_interner,
+                         cdata: cmd,
+                         node_id: ast::node_id) -> Option<ast::ident> {
+    let item = lookup_item(node_id, cdata.data);
+    if item_family(item) != Impl {
+        return None;
+    }
+
+    for ebml::tagged_docs(item, tag_item_impl_type_basename) |doc| {
+        return Some(intr.intern(@str::from_bytes(ebml::doc_data(doc))));
+    }
+
+    return None;
+}
+
+fn get_static_methods_if_impl(intr: @ident_interner,
+                               cdata: cmd,
+                               node_id: ast::node_id) ->
+                               Option<~[StaticMethodInfo]> {
+    let item = lookup_item(node_id, cdata.data);
+    if item_family(item) != Impl {
+        return None;
+    }
+
+    // If this impl has a trait ref, don't consider it.
+    for ebml::tagged_docs(item, tag_impl_trait) |_doc| {
+        return None;
+    }
+
+    let impl_method_ids = DVec();
+    for ebml::tagged_docs(item, tag_item_impl_method) |impl_method_doc| {
+        impl_method_ids.push(parse_def_id(ebml::doc_data(impl_method_doc)));
+    }
+
+    let static_impl_methods = DVec();
+    for impl_method_ids.each |impl_method_id| {
+        let impl_method_doc = lookup_item(impl_method_id.node, cdata.data);
+        let family = item_family(impl_method_doc);
+        match family {
+            StaticMethod | UnsafeStaticMethod | PureStaticMethod => {
+                let purity;
+                match item_family(impl_method_doc) {
+                    StaticMethod => purity = ast::impure_fn,
+                    UnsafeStaticMethod => purity = ast::unsafe_fn,
+                    PureStaticMethod => purity = ast::pure_fn,
+                    _ => fail
+                }
+
+                static_impl_methods.push(StaticMethodInfo {
+                    ident: item_name(intr, impl_method_doc),
+                    def_id: item_def_id(impl_method_doc, cdata),
+                    purity: purity
+                });
+            }
+            _ => {}
+        }
+    }
+
+    return Some(dvec::unwrap(move static_impl_methods));
+}
+
 fn get_item_attrs(cdata: cmd,
                   node_id: ast::node_id,
                   f: fn(~[@ast::meta_item])) {
@@ -822,7 +945,6 @@ fn item_family_to_str(fam: Family) -> ~str {
       Variant => ~"variant",
       Impl => ~"impl",
       Trait => ~"trait",
-      Class => ~"class",
       Struct => ~"struct",
       PublicField => ~"public field",
       PrivateField => ~"private field",
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index a65c25a46ef..f7e80e53ed5 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -5,7 +5,7 @@ use util::ppaux::ty_to_str;
 use std::{ebml, map};
 use std::map::HashMap;
 use io::WriterUtil;
-use ebml::Writer;
+use ebml::Serializer;
 use syntax::ast::*;
 use syntax::print::pprust;
 use syntax::{ast_util, visit};
@@ -40,7 +40,7 @@ export encode_def_id;
 type abbrev_map = map::HashMap<ty::t, tyencode::ty_abbrev>;
 
 type encode_inlined_item = fn@(ecx: @encode_ctxt,
-                               ebml_w: ebml::Writer,
+                               ebml_w: ebml::Serializer,
                                path: ast_map::path,
                                ii: ast::inlined_item);
 
@@ -52,7 +52,7 @@ type encode_parms = {
     item_symbols: HashMap<ast::node_id, ~str>,
     discrim_symbols: HashMap<ast::node_id, ~str>,
     link_meta: link_meta,
-    cstore: cstore::cstore,
+    cstore: cstore::CStore,
     encode_inlined_item: encode_inlined_item
 };
 
@@ -77,7 +77,7 @@ enum encode_ctxt = {
     item_symbols: HashMap<ast::node_id, ~str>,
     discrim_symbols: HashMap<ast::node_id, ~str>,
     link_meta: link_meta,
-    cstore: cstore::cstore,
+    cstore: cstore::CStore,
     encode_inlined_item: encode_inlined_item,
     type_abbrevs: abbrev_map
 };
@@ -86,25 +86,31 @@ fn reachable(ecx: @encode_ctxt, id: node_id) -> bool {
     ecx.reachable.contains_key(id)
 }
 
-fn encode_name(ecx: @encode_ctxt, ebml_w: ebml::Writer, name: ident) {
+fn encode_name(ecx: @encode_ctxt, ebml_w: ebml::Serializer, name: ident) {
     ebml_w.wr_tagged_str(tag_paths_data_name, ecx.tcx.sess.str_of(name));
 }
 
-fn encode_def_id(ebml_w: ebml::Writer, id: def_id) {
+fn encode_impl_type_basename(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
+                             name: ident) {
+    ebml_w.wr_tagged_str(tag_item_impl_type_basename,
+                         ecx.tcx.sess.str_of(name));
+}
+
+fn encode_def_id(ebml_w: ebml::Serializer, id: def_id) {
     ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
 }
 
-fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                        it: @ast::item) {
     let opt_rp = ecx.tcx.region_paramd_items.find(it.id);
     for opt_rp.each |rp| {
         do ebml_w.wr_tag(tag_region_param) {
-            ty::serialize_region_variance(ebml_w, *rp);
+            (*rp).serialize(&ebml_w);
         }
     }
 }
 
-fn encode_mutability(ebml_w: ebml::Writer, mt: class_mutability) {
+fn encode_mutability(ebml_w: ebml::Serializer, mt: class_mutability) {
     do ebml_w.wr_tag(tag_class_mut) {
         let val = match mt {
           class_immutable => 'a',
@@ -116,7 +122,7 @@ fn encode_mutability(ebml_w: ebml::Writer, mt: class_mutability) {
 
 type entry<T> = {val: T, pos: uint};
 
-fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident],
+fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Serializer, path: &[ident],
                 index: &mut ~[entry<~str>], name: ident) {
     let mut full_path = ~[];
     full_path.push_all(path);
@@ -127,7 +133,8 @@ fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident],
          pos: ebml_w.writer.tell()});
 }
 
-fn encode_trait_ref(ebml_w: ebml::Writer, ecx: @encode_ctxt, t: @trait_ref) {
+fn encode_trait_ref(ebml_w: ebml::Serializer, ecx: @encode_ctxt,
+                    t: @trait_ref) {
     ebml_w.start_tag(tag_impl_trait);
     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
     ebml_w.end_tag();
@@ -135,7 +142,7 @@ fn encode_trait_ref(ebml_w: ebml::Writer, ecx: @encode_ctxt, t: @trait_ref) {
 
 
 // Item info table encoding
-fn encode_family(ebml_w: ebml::Writer, c: char) {
+fn encode_family(ebml_w: ebml::Serializer, c: char) {
     ebml_w.start_tag(tag_items_data_item_family);
     ebml_w.writer.write(&[c as u8]);
     ebml_w.end_tag();
@@ -143,7 +150,7 @@ fn encode_family(ebml_w: ebml::Writer, c: char) {
 
 fn def_to_str(did: def_id) -> ~str { fmt!("%d:%d", did.crate, did.node) }
 
-fn encode_ty_type_param_bounds(ebml_w: ebml::Writer, ecx: @encode_ctxt,
+fn encode_ty_type_param_bounds(ebml_w: ebml::Serializer, ecx: @encode_ctxt,
                                params: @~[ty::param_bounds]) {
     let ty_str_ctxt = @{diag: ecx.diag,
                         ds: def_to_str,
@@ -157,7 +164,7 @@ fn encode_ty_type_param_bounds(ebml_w: ebml::Writer, ecx: @encode_ctxt,
     }
 }
 
-fn encode_type_param_bounds(ebml_w: ebml::Writer, ecx: @encode_ctxt,
+fn encode_type_param_bounds(ebml_w: ebml::Serializer, ecx: @encode_ctxt,
                             params: ~[ty_param]) {
     let ty_param_bounds =
         @params.map(|param| ecx.tcx.ty_param_bounds.get(param.id));
@@ -165,13 +172,13 @@ fn encode_type_param_bounds(ebml_w: ebml::Writer, ecx: @encode_ctxt,
 }
 
 
-fn encode_variant_id(ebml_w: ebml::Writer, vid: def_id) {
+fn encode_variant_id(ebml_w: ebml::Serializer, vid: def_id) {
     ebml_w.start_tag(tag_items_data_item_variant);
     ebml_w.writer.write(str::to_bytes(def_to_str(vid)));
     ebml_w.end_tag();
 }
 
-fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
+fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Serializer, typ: ty::t) {
     let ty_str_ctxt =
         @{diag: ecx.diag,
           ds: def_to_str,
@@ -181,7 +188,8 @@ fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
 }
 
-fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Writer, vstore: ty::vstore) {
+fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
+                vstore: ty::vstore) {
     let ty_str_ctxt =
         @{diag: ecx.diag,
           ds: def_to_str,
@@ -191,13 +199,13 @@ fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Writer, vstore: ty::vstore) {
     tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
 }
 
-fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
+fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::Serializer, typ: ty::t) {
     ebml_w.start_tag(tag_items_data_item_type);
     write_type(ecx, ebml_w, typ);
     ebml_w.end_tag();
 }
 
-fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::Writer, id: node_id) {
+fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::Serializer, id: node_id) {
     ebml_w.start_tag(tag_items_data_item_symbol);
     let sym = match ecx.item_symbols.find(id) {
       Some(x) => x,
@@ -210,25 +218,27 @@ fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::Writer, id: node_id) {
     ebml_w.end_tag();
 }
 
-fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::Writer, id: node_id) {
+fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
+                       id: node_id) {
     ebml_w.start_tag(tag_items_data_item_symbol);
     ebml_w.writer.write(str::to_bytes(ecx.discrim_symbols.get(id)));
     ebml_w.end_tag();
 }
 
-fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::Writer, disr_val: int) {
+fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::Serializer,
+                   disr_val: int) {
     ebml_w.start_tag(tag_disr_val);
     ebml_w.writer.write(str::to_bytes(int::to_str(disr_val,10u)));
     ebml_w.end_tag();
 }
 
-fn encode_parent_item(ebml_w: ebml::Writer, id: def_id) {
+fn encode_parent_item(ebml_w: ebml::Serializer, id: def_id) {
     ebml_w.start_tag(tag_items_data_parent_item);
     ebml_w.writer.write(str::to_bytes(def_to_str(id)));
     ebml_w.end_tag();
 }
 
-fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                             id: node_id, variants: ~[variant],
                             path: ast_map::path, index: @mut ~[entry<int>],
                             ty_params: ~[ty_param]) {
@@ -265,9 +275,9 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::Writer,
     }
 }
 
-fn encode_path(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: ast_map::path,
-               name: ast_map::path_elt) {
-    fn encode_path_elt(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_path(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
+               path: ast_map::path, name: ast_map::path_elt) {
+    fn encode_path_elt(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                        elt: ast_map::path_elt) {
         let (tag, name) = match elt {
           ast_map::path_mod(name) => (tag_path_elt_mod, name),
@@ -286,7 +296,7 @@ fn encode_path(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: ast_map::path,
     }
 }
 
-fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::Writer, md: _mod,
+fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::Serializer, md: _mod,
                        id: node_id, path: ast_map::path, name: ident) {
     ebml_w.start_tag(tag_items_data_item);
     encode_def_id(ebml_w, local_def(id));
@@ -344,7 +354,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::Writer, md: _mod,
     ebml_w.end_tag();
 }
 
-fn encode_visibility(ebml_w: ebml::Writer, visibility: visibility) {
+fn encode_visibility(ebml_w: ebml::Serializer, visibility: visibility) {
     encode_family(ebml_w, match visibility {
         public => 'g',
         private => 'j',
@@ -352,7 +362,7 @@ fn encode_visibility(ebml_w: ebml::Writer, visibility: visibility) {
     });
 }
 
-fn encode_self_type(ebml_w: ebml::Writer, self_type: ast::self_ty_) {
+fn encode_self_type(ebml_w: ebml::Serializer, self_type: ast::self_ty_) {
     ebml_w.start_tag(tag_item_trait_method_self_ty);
 
     // Encode the base self type.
@@ -384,8 +394,14 @@ fn encode_self_type(ebml_w: ebml::Writer, self_type: ast::self_ty_) {
     ebml_w.end_tag();
 }
 
+fn encode_method_sort(ebml_w: ebml::Serializer, sort: char) {
+    ebml_w.start_tag(tag_item_trait_method_sort);
+    ebml_w.writer.write(&[ sort as u8 ]);
+    ebml_w.end_tag();
+}
+
 /* Returns an index of items in this class */
-fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                          id: node_id, path: ast_map::path,
                          class_tps: ~[ty_param],
                          fields: ~[@struct_field],
@@ -441,7 +457,7 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::Writer,
 }
 
 // This is for encoding info for ctors and dtors
-fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                         id: node_id, ident: ident, path: ast_map::path,
                         item: Option<inlined_item>, tps: ~[ty_param]) {
         ebml_w.start_tag(tag_items_data_item);
@@ -466,7 +482,7 @@ fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml::Writer,
         ebml_w.end_tag();
 }
 
-fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                           impl_path: ast_map::path, should_inline: bool,
                           parent_id: node_id,
                           m: @method, all_tps: ~[ty_param]) {
@@ -474,7 +490,12 @@ fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::Writer,
            ecx.tcx.sess.str_of(m.ident), all_tps.len());
     ebml_w.start_tag(tag_items_data_item);
     encode_def_id(ebml_w, local_def(m.id));
-    encode_family(ebml_w, purity_fn_family(m.purity));
+    match m.self_ty.node {
+        ast::sty_static => {
+            encode_family(ebml_w, purity_static_method_family(m.purity));
+        }
+        _ => encode_family(ebml_w, purity_fn_family(m.purity))
+    }
     encode_type_param_bounds(ebml_w, ecx, all_tps);
     encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
     encode_name(ecx, ebml_w, m.ident);
@@ -516,8 +537,9 @@ fn should_inline(attrs: ~[attribute]) -> bool {
 }
 
 
-fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
-                        index: @mut ~[entry<int>], path: ast_map::path) {
+fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
+                        item: @item, index: @mut ~[entry<int>],
+                        path: ast_map::path) {
 
     let tcx = ecx.tcx;
     let must_write =
@@ -528,7 +550,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
         };
     if !must_write && !reachable(ecx, item.id) { return; }
 
-    fn add_to_index_(item: @item, ebml_w: ebml::Writer,
+    fn add_to_index_(item: @item, ebml_w: ebml::Serializer,
                      index: @mut ~[entry<int>]) {
         index.push({val: item.id, pos: ebml_w.writer.tell()});
     }
@@ -630,12 +652,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
         /* Now, make an item for the class itself */
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(item.id));
-
-        match struct_def.ctor {
-            None => encode_family(ebml_w, 'S'),
-            Some(_) => encode_family(ebml_w, 'C')
-        }
-
+        encode_family(ebml_w, 'S');
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ecx, ebml_w, item.ident);
@@ -694,23 +711,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
         let bkts = create_index(idx);
         encode_index(ebml_w, bkts, write_int);
         ebml_w.end_tag();
-
-        /* Encode the constructor */
-        for struct_def.ctor.each |ctor| {
-            debug!("encoding info for ctor %s %d",
-                   ecx.tcx.sess.str_of(item.ident), ctor.node.id);
-            index.push({
-                val: ctor.node.id,
-                pos: ebml_w.writer.tell()
-            });
-            encode_info_for_ctor(ecx, ebml_w, ctor.node.id, item.ident,
-                                 path, if tps.len() > 0u {
-                                     Some(ii_ctor(*ctor, item.ident, tps,
-                                                  local_def(item.id))) }
-                                 else { None }, tps);
-        }
       }
-      item_impl(tps, opt_trait, _, methods) => {
+      item_impl(tps, opt_trait, ty, methods) => {
         add_to_index();
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(item.id));
@@ -720,6 +722,13 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ecx, ebml_w, item.ident);
         encode_attributes(ebml_w, item.attrs);
+        match ty.node {
+            ast::ty_path(path, _) if path.idents.len() == 1 => {
+                encode_impl_type_basename(ecx, ebml_w,
+                                          ast_util::path_to_ident(path));
+            }
+            _ => {}
+        }
         for methods.each |m| {
             ebml_w.start_tag(tag_item_impl_method);
             ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id))));
@@ -741,6 +750,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
         }
       }
       item_trait(tps, traits, ms) => {
+        let provided_methods = dvec::DVec();
+
         add_to_index();
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(item.id));
@@ -761,12 +772,21 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
                 encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
                 encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity));
                 encode_self_type(ebml_w, mty.self_ty);
+                encode_method_sort(ebml_w, 'r');
                 ebml_w.end_tag();
               }
               provided(m) => {
-                encode_info_for_method(ecx, ebml_w, path,
-                                       should_inline(m.attrs), item.id,
-                                       m, m.tps);
+                provided_methods.push(m);
+
+                ebml_w.start_tag(tag_item_trait_method);
+                encode_def_id(ebml_w, local_def(m.id));
+                encode_name(ecx, ebml_w, mty.ident);
+                encode_type_param_bounds(ebml_w, ecx, m.tps);
+                encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
+                encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity));
+                encode_self_type(ebml_w, mty.self_ty);
+                encode_method_sort(ebml_w, 'p');
+                ebml_w.end_tag();
               }
             }
             i += 1u;
@@ -789,6 +809,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
 
             ebml_w.start_tag(tag_items_data_item);
             encode_def_id(ebml_w, local_def(ty_m.id));
+            encode_parent_item(ebml_w, local_def(item.id));
             encode_name(ecx, ebml_w, ty_m.ident);
             encode_family(ebml_w,
                           purity_static_method_family(ty_m.purity));
@@ -799,13 +820,18 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
             ebml_w.end_tag();
         }
 
-
+        // Finally, output all the provided methods as items.
+        for provided_methods.each |m| {
+            index.push({val: m.id, pos: ebml_w.writer.tell()});
+            encode_info_for_method(ecx, ebml_w, path, true, item.id, *m,
+                                   m.tps);
+        }
       }
       item_mac(*) => fail ~"item macros unimplemented"
     }
 }
 
-fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                                 nitem: @foreign_item,
                                 index: @mut ~[entry<int>],
                                 path: ast_map::path, abi: foreign_abi) {
@@ -838,7 +864,7 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::Writer,
     ebml_w.end_tag();
 }
 
-fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                          crate: @crate) -> ~[entry<int>] {
     let index = @mut ~[];
     ebml_w.start_tag(tag_items_data);
@@ -893,7 +919,7 @@ fn create_index<T: Copy Hash IterBytes>(index: ~[entry<T>]) ->
     return buckets_frozen;
 }
 
-fn encode_index<T>(ebml_w: ebml::Writer, buckets: ~[@~[entry<T>]],
+fn encode_index<T>(ebml_w: ebml::Serializer, buckets: ~[@~[entry<T>]],
                    write_fn: fn(io::Writer, T)) {
     let writer = ebml_w.writer;
     ebml_w.start_tag(tag_index);
@@ -928,7 +954,7 @@ fn write_int(writer: io::Writer, &&n: int) {
     writer.write_be_u32(n as u32);
 }
 
-fn encode_meta_item(ebml_w: ebml::Writer, mi: meta_item) {
+fn encode_meta_item(ebml_w: ebml::Serializer, mi: meta_item) {
     match mi.node {
       meta_word(name) => {
         ebml_w.start_tag(tag_meta_item_word);
@@ -965,7 +991,7 @@ fn encode_meta_item(ebml_w: ebml::Writer, mi: meta_item) {
     }
 }
 
-fn encode_attributes(ebml_w: ebml::Writer, attrs: ~[attribute]) {
+fn encode_attributes(ebml_w: ebml::Serializer, attrs: ~[attribute]) {
     ebml_w.start_tag(tag_attributes);
     for attrs.each |attr| {
         ebml_w.start_tag(tag_attribute);
@@ -1026,10 +1052,10 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] {
     return attrs;
 }
 
-fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml::Writer,
-                     cstore: cstore::cstore) {
+fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
+                     cstore: cstore::CStore) {
 
-    fn get_ordered_deps(ecx: @encode_ctxt, cstore: cstore::cstore)
+    fn get_ordered_deps(ecx: @encode_ctxt, cstore: cstore::CStore)
         -> ~[decoder::crate_dep] {
 
         type hashkv = @{key: crate_num, val: cstore::crate_metadata};
@@ -1072,7 +1098,7 @@ fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml::Writer,
     ebml_w.end_tag();
 }
 
-fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml::Writer,
+fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml::Serializer,
                     dep: decoder::crate_dep) {
     ebml_w.start_tag(tag_crate_dep);
     ebml_w.start_tag(tag_crate_dep_name);
@@ -1087,7 +1113,7 @@ fn encode_crate_dep(ecx: @encode_ctxt, ebml_w: ebml::Writer,
     ebml_w.end_tag();
 }
 
-fn encode_hash(ebml_w: ebml::Writer, hash: ~str) {
+fn encode_hash(ebml_w: ebml::Serializer, hash: ~str) {
     ebml_w.start_tag(tag_crate_hash);
     ebml_w.writer.write(str::to_bytes(hash));
     ebml_w.end_tag();
@@ -1125,7 +1151,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
         type_abbrevs: ty::new_ty_hash()
      });
 
-    let ebml_w = ebml::Writer(wr as io::Writer);
+    let ebml_w = ebml::Serializer(wr as io::Writer);
 
     encode_hash(ebml_w, ecx.link_meta.extras_hash);
 
@@ -1154,7 +1180,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
 
     if (parms.tcx.sess.meta_stats()) {
 
-        do wr.buf.borrow |v| {
+        do wr.bytes.borrow |v| {
             do v.each |e| {
                 if *e == 0 {
                     ecx.stats.zero_bytes += 1;
@@ -1187,7 +1213,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
 
     (do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| {
         vec::slice(*bytes, 0, 8)
-    }) + flate::deflate_bytes(wr.buf.check_out(|buf| buf))
+    }) + flate::deflate_bytes(wr.bytes.check_out(|buf| buf))
 }
 
 // Get the encoded string for a type
diff --git a/src/rustc/metadata/filesearch.rs b/src/rustc/metadata/filesearch.rs
index 63370b09321..b2d20ce56e8 100644
--- a/src/rustc/metadata/filesearch.rs
+++ b/src/rustc/metadata/filesearch.rs
@@ -3,7 +3,7 @@
 // probably just be folded into cstore.
 
 use result::Result;
-export filesearch;
+export FileSearch;
 export mk_filesearch;
 export pick;
 export pick_file;
@@ -21,7 +21,7 @@ fn pick_file(file: Path, path: &Path) -> Option<Path> {
     else { option::None }
 }
 
-trait filesearch {
+trait FileSearch {
     fn sysroot() -> Path;
     fn lib_search_paths() -> ~[Path];
     fn get_target_lib_path() -> Path;
@@ -30,11 +30,11 @@ trait filesearch {
 
 fn mk_filesearch(maybe_sysroot: Option<Path>,
                  target_triple: &str,
-                 addl_lib_search_paths: ~[Path]) -> filesearch {
+                 addl_lib_search_paths: ~[Path]) -> FileSearch {
     type filesearch_impl = {sysroot: Path,
                             addl_lib_search_paths: ~[Path],
                             target_triple: ~str};
-    impl filesearch_impl: filesearch {
+    impl filesearch_impl: FileSearch {
         fn sysroot() -> Path { self.sysroot }
         fn lib_search_paths() -> ~[Path] {
             let mut paths = self.addl_lib_search_paths;
@@ -64,10 +64,10 @@ fn mk_filesearch(maybe_sysroot: Option<Path>,
     debug!("using sysroot = %s", sysroot.to_str());
     {sysroot: sysroot,
      addl_lib_search_paths: addl_lib_search_paths,
-     target_triple: str::from_slice(target_triple)} as filesearch
+     target_triple: str::from_slice(target_triple)} as FileSearch
 }
 
-fn search<T: Copy>(filesearch: filesearch, pick: pick<T>) -> Option<T> {
+fn search<T: Copy>(filesearch: FileSearch, pick: pick<T>) -> Option<T> {
     let mut rslt = None;
     for filesearch.lib_search_paths().each |lib_search_path| {
         debug!("searching %s", lib_search_path.to_str());
diff --git a/src/rustc/metadata/loader.rs b/src/rustc/metadata/loader.rs
index 0a8354be71f..61b8bcf9067 100644
--- a/src/rustc/metadata/loader.rs
+++ b/src/rustc/metadata/loader.rs
@@ -5,7 +5,7 @@ use syntax::{ast, attr};
 use syntax::print::pprust;
 use syntax::codemap::span;
 use lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
-use filesearch::filesearch;
+use filesearch::FileSearch;
 use io::WriterUtil;
 use syntax::parse::token::ident_interner;
 
@@ -28,7 +28,7 @@ enum os {
 
 type ctxt = {
     diag: span_handler,
-    filesearch: filesearch,
+    filesearch: FileSearch,
     span: span,
     ident: ast::ident,
     metas: ~[@ast::meta_item],
@@ -66,7 +66,7 @@ fn libname(cx: ctxt) -> {prefix: ~str, suffix: ~str} {
 
 fn find_library_crate_aux(cx: ctxt,
                           nn: {prefix: ~str, suffix: ~str},
-                          filesearch: filesearch::filesearch) ->
+                          filesearch: filesearch::FileSearch) ->
    Option<{ident: ~str, data: @~[u8]}> {
     let crate_name = crate_name_from_metas(cx.metas);
     let prefix: ~str = nn.prefix + crate_name + ~"-";
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index 1375ff2d0be..14aef6db1ad 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -162,7 +162,7 @@ fn parse_bound_region(st: @pstate) -> ty::bound_region {
     }
 }
 
-fn parse_region(st: @pstate) -> ty::region {
+fn parse_region(st: @pstate) -> ty::Region {
     match next(st) {
       'b' => {
         ty::re_bound(parse_bound_region(st))
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index 69689b16e15..941dd35bdf0 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -125,7 +125,7 @@ fn enc_substs(w: io::Writer, cx: @ctxt, substs: ty::substs) {
     w.write_char(']');
 }
 
-fn enc_region(w: io::Writer, cx: @ctxt, r: ty::region) {
+fn enc_region(w: io::Writer, cx: @ctxt, r: ty::Region) {
     match r {
       ty::re_bound(br) => {
         w.write_char('b');