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 { + 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, 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 { + 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, 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, // Maps a trait onto a list of impls of that trait. - pub trait_impls: RefCell>>>, + pub trait_impls: RefCell>>>, - // 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>>>, + pub inherent_impls: RefCell>>>, - // 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>, + pub impl_methods: RefCell>>, // 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::>() - .repr(self.tcx())); + impl_methods.iter().map(|&did| ty::method(self.tcx(), did).ident) + .collect::>() + .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. - } + 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) { 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 for type , - // and that impl is " - self.iter_impls_of_trait(trait_def_id, |b| { - let implementation_b = b; + // and that impl is " + 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 { 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 = 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, 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 \