about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2014-04-21 12:04:35 +0300
committerEduard Burtescu <edy.burt@gmail.com>2014-04-22 19:14:52 +0300
commit1e5a112922fbac2a6f2d0aa9e6eb90bc3a4422a5 (patch)
treea0886cf39d3cb85d54f6acec572da5772e5f44d1
parent8f3cfe064bf4669082ec2d195f214cc36b36b568 (diff)
downloadrust-1e5a112922fbac2a6f2d0aa9e6eb90bc3a4422a5.tar.gz
rust-1e5a112922fbac2a6f2d0aa9e6eb90bc3a4422a5.zip
rustc: remove ty::Impl.
-rw-r--r--src/librustc/metadata/csearch.rs8
-rw-r--r--src/librustc/metadata/decoder.rs29
-rw-r--r--src/librustc/metadata/encoder.rs29
-rw-r--r--src/librustc/middle/dead.rs10
-rw-r--r--src/librustc/middle/trans/meth.rs20
-rw-r--r--src/librustc/middle/ty.rs61
-rw-r--r--src/librustc/middle/typeck/check/method.rs45
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs16
-rw-r--r--src/librustc/middle/typeck/coherence.rs127
9 files changed, 156 insertions, 189 deletions
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 61caa0cf499..a01e088a9f4 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -114,10 +114,10 @@ pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
 }
 
 /// Returns information about the given implementation.
-pub fn get_impl(tcx: &ty::ctxt, impl_def_id: ast::DefId)
-                -> ty::Impl {
-    let cdata = tcx.sess.cstore.get_crate_data(impl_def_id.krate);
-    decoder::get_impl(tcx.sess.cstore.intr.clone(), &*cdata, impl_def_id.node, tcx)
+pub fn get_impl_methods(cstore: &cstore::CStore, impl_def_id: ast::DefId)
+                        -> Vec<ast::DefId> {
+    let cdata = cstore.get_crate_data(impl_def_id.krate);
+    decoder::get_impl_methods(&*cdata, impl_def_id.node)
 }
 
 pub fn get_method(tcx: &ty::ctxt, def: ast::DefId) -> ty::Method {
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 9751ca3615f..74156510fac 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -733,32 +733,17 @@ fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ {
     }
 }
 
-fn item_impl_methods(intr: Rc<IdentInterner>, cdata: Cmd, item: ebml::Doc,
-                     tcx: &ty::ctxt) -> Vec<@ty::Method> {
-    let mut rslt = Vec::new();
-    reader::tagged_docs(item, tag_item_impl_method, |doc| {
+/// Returns information about the given implementation.
+pub fn get_impl_methods(cdata: Cmd, impl_id: ast::NodeId) -> Vec<ast::DefId> {
+    let mut methods = Vec::new();
+    reader::tagged_docs(lookup_item(impl_id, cdata.data()),
+                        tag_item_impl_method, |doc| {
         let m_did = reader::with_doc_data(doc, parse_def_id);
-        rslt.push(@get_method(intr.clone(), cdata, m_did.node, tcx));
+        methods.push(translate_def_id(cdata, m_did));
         true
     });
 
-    rslt
-}
-
-/// Returns information about the given implementation.
-pub fn get_impl(intr: Rc<IdentInterner>, cdata: Cmd, impl_id: ast::NodeId,
-               tcx: &ty::ctxt)
-                -> ty::Impl {
-    let data = cdata.data();
-    let impl_item = lookup_item(impl_id, data);
-    ty::Impl {
-        did: ast::DefId {
-            krate: cdata.cnum,
-            node: impl_id,
-        },
-        ident: item_name(&*intr, impl_item),
-        methods: item_impl_methods(intr, cdata, impl_item, tcx),
-    }
+    methods
 }
 
 pub fn get_method_name_and_explicit_self(
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index b167af268a3..a3f32cb93ac 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -398,10 +398,12 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
                                          ebml_w: &mut Encoder,
                                          exp: &middle::resolve::Export2)
                                          -> bool {
+    let impl_methods = ecx.tcx.impl_methods.borrow();
     match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) {
         Some(implementations) => {
-            for &base_impl in implementations.borrow().iter() {
-                for &m in base_impl.methods.iter() {
+            for base_impl_did in implementations.borrow().iter() {
+                for &method_did in impl_methods.get(base_impl_did).iter() {
+                    let m = ty::method(ecx.tcx, method_did);
                     if m.explicit_self == ast::SelfStatic {
                         encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
                     }
@@ -822,9 +824,9 @@ fn encode_inherent_implementations(ecx: &EncodeContext,
     match ecx.tcx.inherent_impls.borrow().find(&def_id) {
         None => {}
         Some(implementations) => {
-            for implementation in implementations.borrow().iter() {
+            for &impl_def_id in implementations.borrow().iter() {
                 ebml_w.start_tag(tag_items_data_item_inherent_impl);
-                encode_def_id(ebml_w, implementation.did);
+                encode_def_id(ebml_w, impl_def_id);
                 ebml_w.end_tag();
             }
         }
@@ -838,9 +840,9 @@ fn encode_extension_implementations(ecx: &EncodeContext,
     match ecx.tcx.trait_impls.borrow().find(&trait_def_id) {
         None => {}
         Some(implementations) => {
-            for implementation in implementations.borrow().iter() {
+            for &impl_def_id in implementations.borrow().iter() {
                 ebml_w.start_tag(tag_items_data_item_extension_impl);
-                encode_def_id(ebml_w, implementation.did);
+                encode_def_id(ebml_w, impl_def_id);
                 ebml_w.end_tag();
             }
         }
@@ -1028,8 +1030,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
       ItemImpl(_, ref opt_trait, ty, ref ast_methods) => {
         // We need to encode information about the default methods we
         // have inherited, so we drive this based on the impl structure.
-        let impls = tcx.impls.borrow();
-        let imp = impls.get(&def_id);
+        let impl_methods = tcx.impl_methods.borrow();
+        let methods = impl_methods.get(&def_id);
 
         add_to_index(item, ebml_w, index);
         ebml_w.start_tag(tag_items_data_item);
@@ -1046,9 +1048,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
             }
             _ => {}
         }
-        for method in imp.methods.iter() {
+        for &method_def_id in methods.iter() {
             ebml_w.start_tag(tag_item_impl_method);
-            let s = def_to_str(method.def_id);
+            let s = def_to_str(method_def_id);
             ebml_w.writer.write(s.as_bytes());
             ebml_w.end_tag();
         }
@@ -1067,18 +1069,19 @@ fn encode_info_for_item(ecx: &EncodeContext,
         // appear first in the impl structure, in the same order they do
         // in the ast. This is a little sketchy.
         let num_implemented_methods = ast_methods.len();
-        for (i, m) in imp.methods.iter().enumerate() {
+        for (i, &method_def_id) in methods.iter().enumerate() {
             let ast_method = if i < num_implemented_methods {
                 Some(*ast_methods.get(i))
             } else { None };
 
             index.push(entry {
-                val: m.def_id.node as i64,
+                val: method_def_id.node as i64,
                 pos: ebml_w.writer.tell().unwrap(),
             });
+            let m = ty::method(tcx, method_def_id);
             encode_info_for_method(ecx,
                                    ebml_w,
-                                   *m,
+                                   m,
                                    path.clone(),
                                    false,
                                    item.id,
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 94d3cab1ef6..74355357fe7 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -336,13 +336,13 @@ impl<'a> DeadVisitor<'a> {
         // This is done to handle the case where, for example, the static
         // method of a private type is used, but the type itself is never
         // called directly.
-        let def_id = local_def(id);
-        match self.tcx.inherent_impls.borrow().find(&def_id) {
+        let impl_methods = self.tcx.impl_methods.borrow();
+        match self.tcx.inherent_impls.borrow().find(&local_def(id)) {
             None => (),
             Some(impl_list) => {
-                for impl_ in impl_list.borrow().iter() {
-                    for method in impl_.methods.iter() {
-                        if self.live_symbols.contains(&method.def_id.node) {
+                for impl_did in impl_list.borrow().iter() {
+                    for method_did in impl_methods.get(impl_did).iter() {
+                        if self.live_symbols.contains(&method_did.node) {
                             return true;
                         }
                     }
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 0155af02eb5..d122edb7678 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -221,22 +221,22 @@ pub fn trans_static_method_callee(bcx: &Block,
     }
 }
 
-pub fn method_with_name(ccx: &CrateContext,
-                        impl_id: ast::DefId,
-                        name: ast::Name) -> ast::DefId {
+fn method_with_name(ccx: &CrateContext,
+                    impl_id: ast::DefId,
+                    name: ast::Name) -> ast::DefId {
     match ccx.impl_method_cache.borrow().find_copy(&(impl_id, name)) {
         Some(m) => return m,
         None => {}
     }
 
-    let imp = ccx.tcx.impls.borrow();
-    let imp = imp.find(&impl_id)
-                 .expect("could not find impl while translating");
-    let meth = imp.methods.iter().find(|m| m.ident.name == name)
-                  .expect("could not find method while translating");
+    let methods = ccx.tcx.impl_methods.borrow();
+    let methods = methods.find(&impl_id)
+                         .expect("could not find impl while translating");
+    let meth_did = methods.iter().find(|&did| ty::method(&ccx.tcx, *did).ident.name == name)
+                                 .expect("could not find method while translating");
 
-    ccx.impl_method_cache.borrow_mut().insert((impl_id, name), meth.def_id);
-    meth.def_id
+    ccx.impl_method_cache.borrow_mut().insert((impl_id, name), *meth_did);
+    *meth_did
 }
 
 fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 771cd619663..865d82b6779 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -116,12 +116,6 @@ impl Method {
     }
 }
 
-pub struct Impl {
-    pub did: DefId,
-    pub ident: Ident,
-    pub methods: Vec<@Method>,
-}
-
 #[deriving(Clone, Eq, TotalEq, Hash)]
 pub struct mt {
     pub ty: t,
@@ -320,18 +314,18 @@ pub struct ctxt {
     pub destructors: RefCell<DefIdSet>,
 
     // Maps a trait onto a list of impls of that trait.
-    pub trait_impls: RefCell<DefIdMap<@RefCell<Vec<@Impl>>>>,
+    pub trait_impls: RefCell<DefIdMap<@RefCell<Vec<ast::DefId>>>>,
 
-    // Maps a def_id of a type to a list of its inherent impls.
+    // Maps a DefId of a type to a list of its inherent impls.
     // Contains implementations of methods that are inherent to a type.
     // Methods in these implementations don't need to be exported.
-    pub inherent_impls: RefCell<DefIdMap<@RefCell<Vec<@Impl>>>>,
+    pub inherent_impls: RefCell<DefIdMap<@RefCell<Vec<ast::DefId>>>>,
 
-    // Maps a def_id of an impl to an Impl structure.
+    // Maps a DefId of an impl to a list of its methods.
     // Note that this contains all of the impls that we know about,
     // including ones in other crates. It's not clear that this is the best
     // way to do it.
-    pub impls: RefCell<DefIdMap<@Impl>>,
+    pub impl_methods: RefCell<DefIdMap<Vec<ast::DefId>>>,
 
     // Set of used unsafe nodes (functions or blocks). Unsafe nodes not
     // present in this set can be warned about.
@@ -1126,7 +1120,7 @@ pub fn mk_ctxt(s: Session,
         destructors: RefCell::new(DefIdSet::new()),
         trait_impls: RefCell::new(DefIdMap::new()),
         inherent_impls: RefCell::new(DefIdMap::new()),
-        impls: RefCell::new(DefIdMap::new()),
+        impl_methods: RefCell::new(DefIdMap::new()),
         used_unsafe: RefCell::new(NodeSet::new()),
         used_mut_nodes: RefCell::new(NodeSet::new()),
         impl_vtables: RefCell::new(DefIdMap::new()),
@@ -4384,15 +4378,15 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> @ItemVariances {
 /// Records a trait-to-implementation mapping.
 pub fn record_trait_implementation(tcx: &ctxt,
                                    trait_def_id: DefId,
-                                   implementation: @Impl) {
+                                   impl_def_id: DefId) {
     match tcx.trait_impls.borrow().find(&trait_def_id) {
         Some(impls_for_trait) => {
-            impls_for_trait.borrow_mut().push(implementation);
+            impls_for_trait.borrow_mut().push(impl_def_id);
             return;
         }
         None => {}
     }
-    tcx.trait_impls.borrow_mut().insert(trait_def_id, @RefCell::new(vec!(implementation)));
+    tcx.trait_impls.borrow_mut().insert(trait_def_id, @RefCell::new(vec!(impl_def_id)));
 }
 
 /// Populates the type context with all the implementations for the given type
@@ -4407,40 +4401,36 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
     }
 
     csearch::each_implementation_for_type(&tcx.sess.cstore, type_id,
-            |implementation_def_id| {
-        let implementation = @csearch::get_impl(tcx, implementation_def_id);
+            |impl_def_id| {
+        let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id);
 
         // Record the trait->implementation mappings, if applicable.
-        let associated_traits = csearch::get_impl_trait(tcx,
-                                                        implementation.did);
+        let associated_traits = csearch::get_impl_trait(tcx, impl_def_id);
         for trait_ref in associated_traits.iter() {
-            record_trait_implementation(tcx,
-                                        trait_ref.def_id,
-                                        implementation);
+            record_trait_implementation(tcx, trait_ref.def_id, impl_def_id);
         }
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for method in implementation.methods.iter() {
-            for source in method.provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut()
-                   .insert(method.def_id, *source);
+        for &method_def_id in methods.iter() {
+            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
+                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
             }
         }
 
         // Store the implementation info.
-        tcx.impls.borrow_mut().insert(implementation_def_id, implementation);
+        tcx.impl_methods.borrow_mut().insert(impl_def_id, methods);
 
         // If this is an inherent implementation, record it.
         if associated_traits.is_none() {
             match tcx.inherent_impls.borrow().find(&type_id) {
                 Some(implementation_list) => {
-                    implementation_list.borrow_mut().push(implementation);
+                    implementation_list.borrow_mut().push(impl_def_id);
                     return;
                 }
                 None => {}
             }
-            tcx.inherent_impls.borrow_mut().insert(type_id, @RefCell::new(vec!(implementation)));
+            tcx.inherent_impls.borrow_mut().insert(type_id, @RefCell::new(vec!(impl_def_id)));
         }
     });
 
@@ -4461,22 +4451,21 @@ pub fn populate_implementations_for_trait_if_necessary(
 
     csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id,
             |implementation_def_id| {
-        let implementation = @csearch::get_impl(tcx, implementation_def_id);
+        let methods = csearch::get_impl_methods(&tcx.sess.cstore, implementation_def_id);
 
         // Record the trait->implementation mapping.
-        record_trait_implementation(tcx, trait_id, implementation);
+        record_trait_implementation(tcx, trait_id, implementation_def_id);
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for method in implementation.methods.iter() {
-            for source in method.provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut()
-                   .insert(method.def_id, *source);
+        for &method_def_id in methods.iter() {
+            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
+                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
             }
         }
 
         // Store the implementation info.
-        tcx.impls.borrow_mut().insert(implementation_def_id, implementation);
+        tcx.impl_methods.borrow_mut().insert(implementation_def_id, methods);
     });
 
     tcx.populated_external_traits.borrow_mut().insert(trait_id);
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 793f9e44c42..b2b0054fb4d 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -468,9 +468,11 @@ impl<'a> LookupContext<'a> {
         ty::populate_implementations_for_trait_if_necessary(self.tcx(), trait_did);
 
         // Look for explicit implementations.
+        let impl_methods = self.tcx().impl_methods.borrow();
         for impl_infos in self.tcx().trait_impls.borrow().find(&trait_did).iter() {
-            for impl_info in impl_infos.borrow().iter() {
-                self.push_candidates_from_impl(*impl_info, true);
+            for impl_did in impl_infos.borrow().iter() {
+                let methods = impl_methods.get(impl_did);
+                self.push_candidates_from_impl(*impl_did, methods.as_slice(), true);
             }
         }
     }
@@ -643,40 +645,35 @@ impl<'a> LookupContext<'a> {
         // metadata if necessary.
         ty::populate_implementations_for_type_if_necessary(self.tcx(), did);
 
+        let impl_methods = self.tcx().impl_methods.borrow();
         for impl_infos in self.tcx().inherent_impls.borrow().find(&did).iter() {
-            for impl_info in impl_infos.borrow().iter() {
-                self.push_candidates_from_impl(*impl_info, false);
+            for impl_did in impl_infos.borrow().iter() {
+                let methods = impl_methods.get(impl_did);
+                self.push_candidates_from_impl(*impl_did, methods.as_slice(), false);
             }
         }
     }
 
     fn push_candidates_from_impl(&mut self,
-                                 impl_info: &ty::Impl,
+                                 impl_did: DefId,
+                                 impl_methods: &[DefId],
                                  is_extension: bool) {
-        if !self.impl_dups.insert(impl_info.did) {
+        if !self.impl_dups.insert(impl_did) {
             return; // already visited
         }
 
-        debug!("push_candidates_from_impl: {} {} {}",
+        debug!("push_candidates_from_impl: {} {}",
                token::get_name(self.m_name),
-               impl_info.ident.repr(self.tcx()),
-               impl_info.methods.iter()
-                                .map(|m| m.ident)
-                                .collect::<Vec<ast::Ident>>()
-                                .repr(self.tcx()));
-
-        let idx = {
-            match impl_info.methods
-                           .iter()
-                           .position(|m| m.ident.name == self.m_name) {
-                Some(idx) => idx,
-                None => { return; } // No method with the right name.
-            }
+               impl_methods.iter().map(|&did| ty::method(self.tcx(), did).ident)
+                                 .collect::<Vec<ast::Ident>>()
+                                 .repr(self.tcx()));
+
+        let method = match impl_methods.iter().map(|&did| ty::method(self.tcx(), did))
+                                              .find(|m| m.ident.name == self.m_name) {
+            Some(method) => method,
+            None => { return; } // No method with the right name.
         };
 
-        let method = ty::method(self.tcx(),
-                                impl_info.methods.get(idx).def_id);
-
         // determine the `self` of the impl with fresh
         // variables for each parameter:
         let span = self.self_expr.map_or(self.span, |e| e.span);
@@ -684,7 +681,7 @@ impl<'a> LookupContext<'a> {
         let ty::ty_param_substs_and_ty {
             substs: impl_substs,
             ty: impl_ty
-        } = impl_self_ty(&vcx, span, impl_info.did);
+        } = impl_self_ty(&vcx, span, impl_did);
 
         let candidates = if is_extension {
             &mut self.extension_candidates
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 1ab4578f6ce..792c89e43f9 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -325,21 +325,21 @@ fn search_for_vtable(vcx: &VtableContext,
         }
     };
     // impls is the list of all impls in scope for trait_ref.
-    for im in impls.borrow().iter() {
+    for &impl_did in impls.borrow().iter() {
         // im is one specific impl of trait_ref.
 
         // First, ensure we haven't processed this impl yet.
-        if impls_seen.contains(&im.did) {
+        if impls_seen.contains(&impl_did) {
             continue;
         }
-        impls_seen.insert(im.did);
+        impls_seen.insert(impl_did);
 
         // ty::impl_traits gives us the trait im implements.
         //
         // If foo implements a trait t, and if t is the same trait as
         // trait_ref, we need to unify it with trait_ref in order to
         // get all the ty vars sorted out.
-        let r = ty::impl_trait_ref(tcx, im.did);
+        let r = ty::impl_trait_ref(tcx, impl_did);
         let of_trait_ref = r.expect("trait_ref missing on trait impl");
         if of_trait_ref.def_id != trait_ref.def_id { continue; }
 
@@ -362,7 +362,7 @@ fn search_for_vtable(vcx: &VtableContext,
         let ty::ty_param_substs_and_ty {
             substs: substs,
             ty: for_ty
-        } = impl_self_ty(vcx, span, im.did);
+        } = impl_self_ty(vcx, span, impl_did);
         match infer::mk_subty(vcx.infcx,
                               false,
                               infer::RelateSelfType(span),
@@ -405,7 +405,7 @@ fn search_for_vtable(vcx: &VtableContext,
         // type variables in substs. This might still be OK: the
         // process of looking up bounds might constrain some of them.
         let im_generics =
-            ty::lookup_item_type(tcx, im.did).generics;
+            ty::lookup_item_type(tcx, impl_did).generics;
         let subres = lookup_vtables(vcx, span,
                                     im_generics.type_param_defs(), &substs,
                                     is_early);
@@ -438,12 +438,12 @@ fn search_for_vtable(vcx: &VtableContext,
         // I am a little confused about this, since it seems to be
         // very similar to the relate_trait_refs we already do,
         // but problems crop up if it is removed, so... -sully
-        connect_trait_tps(vcx, span, &substs_f, trait_ref, im.did);
+        connect_trait_tps(vcx, span, &substs_f, trait_ref, impl_did);
 
         // Finally, we register that we found a matching impl, and
         // record the def ID of the impl as well as the resolved list
         // of type substitutions for the target trait.
-        found.push(vtable_static(im.did, substs_f.tps.clone(), subres));
+        found.push(vtable_static(impl_did, substs_f.tps.clone(), subres));
     }
 
     match found.len() {
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index df79a448030..1ee227089bc 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -27,7 +27,6 @@ use middle::ty::{ty_uint, ty_uniq, ty_bare_fn, ty_closure};
 use middle::ty::type_is_ty_var;
 use middle::subst::Subst;
 use middle::ty;
-use middle::ty::{Impl, Method};
 use middle::typeck::CrateCtxt;
 use middle::typeck::infer::combine::Combine;
 use middle::typeck::infer::InferCtxt;
@@ -252,7 +251,8 @@ impl<'a> CoherenceChecker<'a> {
     fn check_implementation(&self, item: &Item,
                             associated_traits: &[TraitRef]) {
         let tcx = self.crate_context.tcx;
-        let self_type = ty::lookup_item_type(tcx, local_def(item.id));
+        let impl_did = local_def(item.id);
+        let self_type = ty::lookup_item_type(tcx, impl_did);
 
         // If there are no traits, then this implementation must have a
         // base type.
@@ -276,7 +276,7 @@ impl<'a> CoherenceChecker<'a> {
             }
         }
 
-        let implementation = self.create_impl_from_item(item);
+        let impl_methods = self.create_impl_from_item(item);
 
         for associated_trait in associated_traits.iter() {
             let trait_ref = ty::node_id_to_trait_ref(
@@ -285,7 +285,7 @@ impl<'a> CoherenceChecker<'a> {
                    trait_ref.repr(self.crate_context.tcx),
                    token::get_ident(item.ident));
 
-            self.add_trait_impl(trait_ref.def_id, implementation);
+            self.add_trait_impl(trait_ref.def_id, impl_did);
         }
 
         // Add the implementation to the mapping from implementation to base
@@ -300,20 +300,20 @@ impl<'a> CoherenceChecker<'a> {
             Some(base_type_def_id) => {
                 // FIXME: Gather up default methods?
                 if associated_traits.len() == 0 {
-                    self.add_inherent_impl(base_type_def_id, implementation);
+                    self.add_inherent_impl(base_type_def_id, impl_did);
                 }
             }
         }
 
-        tcx.impls.borrow_mut().insert(implementation.did, implementation);
+        tcx.impl_methods.borrow_mut().insert(impl_did, impl_methods);
     }
 
     // Creates default method IDs and performs type substitutions for an impl
     // and trait pair. Then, for each provided method in the trait, inserts a
     // `ProvidedMethodInfo` instance into the `provided_method_sources` map.
-    fn instantiate_default_methods(&self, impl_id: ast::DefId,
+    fn instantiate_default_methods(&self, impl_id: DefId,
                                    trait_ref: &ty::TraitRef,
-                                   all_methods: &mut Vec<@Method> ) {
+                                   all_methods: &mut Vec<DefId>) {
         let tcx = self.crate_context.tcx;
         debug!("instantiate_default_methods(impl_id={:?}, trait_ref={})",
                impl_id, trait_ref.repr(tcx));
@@ -339,7 +339,7 @@ impl<'a> CoherenceChecker<'a> {
                     Some(trait_method.def_id));
 
             debug!("new_method_ty={}", new_method_ty.repr(tcx));
-            all_methods.push(new_method_ty);
+            all_methods.push(new_did);
 
             // construct the polytype for the method based on the method_ty
             let new_generics = ty::Generics {
@@ -366,23 +366,23 @@ impl<'a> CoherenceChecker<'a> {
         }
     }
 
-    fn add_inherent_impl(&self, base_def_id: DefId, implementation: @Impl) {
+    fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
         let tcx = self.crate_context.tcx;
         match tcx.inherent_impls.borrow().find(&base_def_id) {
             Some(implementation_list) => {
-                implementation_list.borrow_mut().push(implementation);
+                implementation_list.borrow_mut().push(impl_def_id);
                 return;
             }
             None => {}
         }
 
-        tcx.inherent_impls.borrow_mut().insert(base_def_id, @RefCell::new(vec!(implementation)));
+        tcx.inherent_impls.borrow_mut().insert(base_def_id, @RefCell::new(vec!(impl_def_id)));
     }
 
-    fn add_trait_impl(&self, base_def_id: DefId, implementation: @Impl) {
+    fn add_trait_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
         ty::record_trait_implementation(self.crate_context.tcx,
                                         base_def_id,
-                                        implementation);
+                                        impl_def_id);
     }
 
     fn check_implementation_coherence(&self) {
@@ -393,34 +393,32 @@ impl<'a> CoherenceChecker<'a> {
 
     fn check_implementation_coherence_of(&self, trait_def_id: DefId) {
         // Unify pairs of polytypes.
-        self.iter_impls_of_trait_local(trait_def_id, |a| {
-            let implementation_a = a;
+        self.iter_impls_of_trait_local(trait_def_id, |impl_a| {
             let polytype_a =
-                self.get_self_type_for_implementation(implementation_a);
+                self.get_self_type_for_implementation(impl_a);
 
             // "We have an impl of trait <trait_def_id> for type <polytype_a>,
-            // and that impl is <implementation_a>"
-            self.iter_impls_of_trait(trait_def_id, |b| {
-                let implementation_b = b;
+            // and that impl is <impl_a>"
+            self.iter_impls_of_trait(trait_def_id, |impl_b| {
 
                 // An impl is coherent with itself
-                if a.did != b.did {
+                if impl_a != impl_b {
                     let polytype_b = self.get_self_type_for_implementation(
-                            implementation_b);
+                            impl_b);
 
                     if self.polytypes_unify(polytype_a.clone(), polytype_b) {
                         let session = &self.crate_context.tcx.sess;
                         session.span_err(
-                            self.span_of_impl(implementation_a),
+                            self.span_of_impl(impl_a),
                             format!("conflicting implementations for trait `{}`",
                                  ty::item_path_str(self.crate_context.tcx,
                                                    trait_def_id)));
-                        if implementation_b.did.krate == LOCAL_CRATE {
-                            session.span_note(self.span_of_impl(implementation_b),
+                        if impl_b.krate == LOCAL_CRATE {
+                            session.span_note(self.span_of_impl(impl_b),
                                               "note conflicting implementation here");
                         } else {
                             let crate_store = &self.crate_context.tcx.sess.cstore;
-                            let cdata = crate_store.get_crate_data(implementation_b.did.krate);
+                            let cdata = crate_store.get_crate_data(impl_b.krate);
                             session.note(
                                 "conflicting implementation in crate `" + cdata.name + "`");
                         }
@@ -430,7 +428,7 @@ impl<'a> CoherenceChecker<'a> {
         })
     }
 
-    fn iter_impls_of_trait(&self, trait_def_id: DefId, f: |@Impl|) {
+    fn iter_impls_of_trait(&self, trait_def_id: DefId, f: |DefId|) {
         self.iter_impls_of_trait_local(trait_def_id, |x| f(x));
 
         if trait_def_id.krate == LOCAL_CRATE {
@@ -439,17 +437,17 @@ impl<'a> CoherenceChecker<'a> {
 
         let crate_store = &self.crate_context.tcx.sess.cstore;
         csearch::each_implementation_for_trait(crate_store, trait_def_id, |impl_def_id| {
-            let implementation = @csearch::get_impl(self.crate_context.tcx, impl_def_id);
-            let _ = lookup_item_type(self.crate_context.tcx, implementation.did);
-            f(implementation);
+            // Is this actually necessary?
+            let _ = lookup_item_type(self.crate_context.tcx, impl_def_id);
+            f(impl_def_id);
         });
     }
 
-    fn iter_impls_of_trait_local(&self, trait_def_id: DefId, f: |@Impl|) {
+    fn iter_impls_of_trait_local(&self, trait_def_id: DefId, f: |DefId|) {
         match self.crate_context.tcx.trait_impls.borrow().find(&trait_def_id) {
             Some(impls) => {
-                for &im in impls.borrow().iter() {
-                    f(im);
+                for &impl_did in impls.borrow().iter() {
+                    f(impl_did);
                 }
             }
             None => { /* no impls? */ }
@@ -509,9 +507,9 @@ impl<'a> CoherenceChecker<'a> {
                             b.monotype).is_ok()
     }
 
-    fn get_self_type_for_implementation(&self, implementation: @Impl)
+    fn get_self_type_for_implementation(&self, impl_did: DefId)
                                         -> ty_param_bounds_and_ty {
-        self.crate_context.tcx.tcache.borrow().get_copy(&implementation.did)
+        self.crate_context.tcx.tcache.borrow().get_copy(&impl_did)
     }
 
     // Privileged scope checking
@@ -563,15 +561,13 @@ impl<'a> CoherenceChecker<'a> {
         }
     }
 
-    // Converts an implementation in the AST to an Impl structure.
-    fn create_impl_from_item(&self, item: &Item) -> @Impl {
-        let tcx = self.crate_context.tcx;
+    // Converts an implementation in the AST to a vector of methods.
+    fn create_impl_from_item(&self, item: &Item) -> Vec<DefId> {
         match item.node {
             ItemImpl(_, ref trait_refs, _, ref ast_methods) => {
-                let mut methods = Vec::new();
-                for ast_method in ast_methods.iter() {
-                    methods.push(ty::method(tcx, local_def(ast_method.id)));
-                }
+                let mut methods: Vec<DefId> = ast_methods.iter().map(|ast_method| {
+                    local_def(ast_method.id)
+                }).collect();
 
                 for trait_ref in trait_refs.iter() {
                     let ty_trait_ref = ty::node_id_to_trait_ref(
@@ -583,11 +579,7 @@ impl<'a> CoherenceChecker<'a> {
                                                      &mut methods);
                 }
 
-                return @Impl {
-                    did: local_def(item.id),
-                    ident: item.ident,
-                    methods: methods
-                };
+                methods
             }
             _ => {
                 self.crate_context.tcx.sess.span_bug(item.span,
@@ -596,9 +588,9 @@ impl<'a> CoherenceChecker<'a> {
         }
     }
 
-    fn span_of_impl(&self, implementation: @Impl) -> Span {
-        assert_eq!(implementation.did.krate, LOCAL_CRATE);
-        self.crate_context.tcx.map.span(implementation.did.node)
+    fn span_of_impl(&self, impl_did: DefId) -> Span {
+        assert_eq!(impl_did.krate, LOCAL_CRATE);
+        self.crate_context.tcx.map.span(impl_did.node)
     }
 
     // External crate handling
@@ -607,36 +599,35 @@ impl<'a> CoherenceChecker<'a> {
                          impls_seen: &mut HashSet<DefId>,
                          impl_def_id: DefId) {
         let tcx = self.crate_context.tcx;
-        let implementation = @csearch::get_impl(tcx, impl_def_id);
+        let methods = csearch::get_impl_methods(&tcx.sess.cstore, impl_def_id);
 
         // Make sure we don't visit the same implementation multiple times.
-        if !impls_seen.insert(implementation.did) {
+        if !impls_seen.insert(impl_def_id) {
             // Skip this one.
             return
         }
         // Good. Continue.
 
-        let _ = lookup_item_type(tcx, implementation.did);
-        let associated_traits = get_impl_trait(tcx, implementation.did);
+        let _ = lookup_item_type(tcx, impl_def_id);
+        let associated_traits = get_impl_trait(tcx, impl_def_id);
 
         // Do a sanity check.
         assert!(associated_traits.is_some());
 
         // Record all the trait methods.
         for trait_ref in associated_traits.iter() {
-              self.add_trait_impl(trait_ref.def_id, implementation);
+            self.add_trait_impl(trait_ref.def_id, impl_def_id);
         }
 
         // For any methods that use a default implementation, add them to
         // the map. This is a bit unfortunate.
-        for method in implementation.methods.iter() {
-            for source in method.provided_source.iter() {
-                tcx.provided_method_sources.borrow_mut()
-                   .insert(method.def_id, *source);
+        for &method_def_id in methods.iter() {
+            for &source in ty::method(tcx, method_def_id).provided_source.iter() {
+                tcx.provided_method_sources.borrow_mut().insert(method_def_id, source);
             }
         }
 
-        tcx.impls.borrow_mut().insert(implementation.did, implementation);
+        tcx.impl_methods.borrow_mut().insert(impl_def_id, methods);
     }
 
     // Adds implementations and traits from external crates to the coherence
@@ -663,19 +654,21 @@ impl<'a> CoherenceChecker<'a> {
             Some(id) => id, None => { return }
         };
 
-        let impls = match tcx.trait_impls.borrow().find_copy(&drop_trait) {
+        let impl_methods = tcx.impl_methods.borrow();
+        let trait_impls = match tcx.trait_impls.borrow().find_copy(&drop_trait) {
             None => return, // No types with (new-style) dtors present.
             Some(found_impls) => found_impls
         };
 
-        for impl_info in impls.borrow().iter() {
-            if impl_info.methods.len() < 1 {
+        for &impl_did in trait_impls.borrow().iter() {
+            let methods = impl_methods.get(&impl_did);
+            if methods.len() < 1 {
                 // We'll error out later. For now, just don't ICE.
                 continue;
             }
-            let method_def_id = impl_info.methods.get(0).def_id;
+            let method_def_id = *methods.get(0);
 
-            let self_type = self.get_self_type_for_implementation(*impl_info);
+            let self_type = self.get_self_type_for_implementation(impl_did);
             match ty::get(self_type.ty).sty {
                 ty::ty_enum(type_def_id, _) |
                 ty::ty_struct(type_def_id, _) => {
@@ -685,9 +678,9 @@ impl<'a> CoherenceChecker<'a> {
                 }
                 _ => {
                     // Destructors only work on nominal types.
-                    if impl_info.did.krate == ast::LOCAL_CRATE {
+                    if impl_did.krate == ast::LOCAL_CRATE {
                         {
-                            match tcx.map.find(impl_info.did.node) {
+                            match tcx.map.find(impl_did.node) {
                                 Some(ast_map::NodeItem(item)) => {
                                     tcx.sess.span_err((*item).span,
                                                       "the Drop trait may \