Start of data structure cleanup for trait system. Get rid of CoherenceInfo, make trait_impls less bogus.

This commit is contained in:
Michael Sullivan 2013-07-12 18:26:07 -07:00
parent 874eb1939b
commit 37702216eb
7 changed files with 50 additions and 105 deletions

View File

@ -396,7 +396,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
ebml_w: &mut writer::Encoder,
exp: &middle::resolve::Export2)
-> bool {
match ecx.tcx.base_impls.find(&exp.def_id) {
match ecx.tcx.inherent_impls.find(&exp.def_id) {
Some(implementations) => {
for implementations.iter().advance |&base_impl| {
for base_impl.methods.iter().advance |&m| {

View File

@ -162,7 +162,7 @@ pub fn trans_method_callee(bcx: block,
let self_ty = node_id_type(bcx, this.id);
// <impl_id> is the ID of the implementation of
// trait <trait_id> for type <self_ty>
let impl_id = ty::get_impl_id(tcx, trait_id, self_ty);
let impl_id = ty::bogus_get_impl_id_from_ty(tcx, trait_id, self_ty);
// Get the supertrait's methods
let supertrait_method_def_ids = ty::trait_method_def_ids(tcx, trait_id);
// Make sure to fail with a readable error message if

View File

@ -303,11 +303,13 @@ struct ctxt_ {
// A method will be in this list if and only if it is a destructor.
destructors: @mut HashSet<ast::def_id>,
// Maps a trait onto a mapping from self-ty to impl
trait_impls: @mut HashMap<ast::def_id, @mut HashMap<t, @Impl>>,
// Maps a trait onto a list of impls of that trait.
trait_impls: @mut HashMap<ast::def_id, @mut ~[@Impl]>,
// Maps a base type to its impl
base_impls: @mut HashMap<ast::def_id, @mut ~[@Impl]>,
// Maps a def_id 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.
inherent_impls: @mut HashMap<ast::def_id, @mut ~[@Impl]>,
// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
// present in this set can be warned about.
@ -908,7 +910,7 @@ pub fn mk_ctxt(s: session::Session,
destructor_for_type: @mut HashMap::new(),
destructors: @mut HashSet::new(),
trait_impls: @mut HashMap::new(),
base_impls: @mut HashMap::new(),
inherent_impls: @mut HashMap::new(),
used_unsafe: @mut HashSet::new(),
used_mut_nodes: @mut HashSet::new(),
}
@ -3596,20 +3598,6 @@ pub fn trait_method(cx: ctxt, trait_did: ast::def_id, idx: uint) -> @Method {
}
pub fn add_base_impl(cx: ctxt, base_def_id: def_id, implementation: @Impl) {
let implementations;
match cx.base_impls.find(&base_def_id) {
None => {
implementations = @mut ~[];
cx.base_impls.insert(base_def_id, implementations);
}
Some(&existing) => {
implementations = existing;
}
}
implementations.push(implementation);
}
pub fn trait_methods(cx: ctxt, trait_did: ast::def_id) -> @~[@Method] {
match cx.trait_methods_cache.find(&trait_did) {
Some(&methods) => methods,
@ -4375,16 +4363,25 @@ pub fn count_traits_and_supertraits(tcx: ctxt,
return total;
}
// Given a trait and a type, returns the impl of that type
pub fn get_impl_id(tcx: ctxt, trait_id: def_id, self_ty: t) -> def_id {
// Given a trait and a type, returns the impl of that type.
// This is broken, of course, by parametric impls. This used to use
// a table specifically for this mapping, but I removed that table.
// This is only used when calling a supertrait method from a default method,
// and should go away once I fix how that works. -sully
pub fn bogus_get_impl_id_from_ty(tcx: ctxt,
trait_id: def_id, self_ty: t) -> def_id {
match tcx.trait_impls.find(&trait_id) {
Some(ty_to_impl) => match ty_to_impl.find(&self_ty) {
Some(the_impl) => the_impl.did,
None => // try autoderef!
match deref(tcx, self_ty, false) {
Some(some_ty) => get_impl_id(tcx, trait_id, some_ty.ty),
None => tcx.sess.bug("get_impl_id: no impl of trait for \
this type")
Some(ty_to_impl) => {
for ty_to_impl.iter().advance |imp| {
let impl_ty = tcx.tcache.get_copy(&imp.did);
if impl_ty.ty == self_ty { return imp.did; }
}
// try autoderef!
match deref(tcx, self_ty, false) {
Some(some_ty) =>
bogus_get_impl_id_from_ty(tcx, trait_id, some_ty.ty),
None => tcx.sess.bug("get_impl_id: no impl of trait for \
this type")
}
},
None => tcx.sess.bug("get_impl_id: trait isn't in trait_impls")

View File

@ -330,8 +330,7 @@ impl<'self> LookupContext<'self> {
for opt_applicable_traits.iter().advance |applicable_traits| {
for applicable_traits.iter().advance |trait_did| {
// Look for explicit implementations.
let opt_impl_infos =
self.fcx.ccx.coherence_info.extension_methods.find(trait_did);
let opt_impl_infos = self.tcx().trait_impls.find(trait_did);
for opt_impl_infos.iter().advance |impl_infos| {
for impl_infos.iter().advance |impl_info| {
self.push_candidates_from_impl(
@ -517,8 +516,7 @@ impl<'self> LookupContext<'self> {
}
pub fn push_inherent_impl_candidates_for_type(&self, did: def_id) {
let opt_impl_infos =
self.fcx.ccx.coherence_info.inherent_methods.find(&did);
let opt_impl_infos = self.tcx().inherent_impls.find(&did);
for opt_impl_infos.iter().advance |impl_infos| {
for impl_infos.iter().advance |impl_info| {
self.push_candidates_from_impl(

View File

@ -260,7 +260,7 @@ fn lookup_vtable(vcx: &VtableContext,
let mut impls_seen = HashSet::new();
match vcx.ccx.coherence_info.extension_methods.find(&trait_ref.def_id) {
match tcx.trait_impls.find(&trait_ref.def_id) {
None => {
// Nothing found. Continue.
}

View File

@ -159,23 +159,6 @@ pub fn method_to_MethodInfo(ast_method: @method) -> @MethodInfo {
}
}
pub struct CoherenceInfo {
// Contains implementations of methods that are inherent to a type.
// Methods in these implementations don't need to be exported.
inherent_methods: @mut HashMap<def_id, @mut ~[@Impl]>,
// Contains implementations of methods associated with a trait. For these,
// the associated trait must be imported at the call site.
extension_methods: @mut HashMap<def_id, @mut ~[@Impl]>,
}
pub fn CoherenceInfo() -> CoherenceInfo {
CoherenceInfo {
inherent_methods: @mut HashMap::new(),
extension_methods: @mut HashMap::new(),
}
}
pub fn CoherenceChecker(crate_context: @mut CrateCtxt) -> CoherenceChecker {
CoherenceChecker {
crate_context: crate_context,
@ -287,7 +270,7 @@ impl CoherenceChecker {
implementation_opt = Some(implementation);
}
self.add_trait_method(trait_ref.def_id, implementation_opt.get());
self.add_trait_impl(trait_ref.def_id, implementation_opt.get());
}
// Add the implementation to the mapping from implementation to base
@ -313,8 +296,7 @@ impl CoherenceChecker {
}
}
self.add_inherent_method(base_type_def_id,
implementation);
self.add_inherent_impl(base_type_def_id, implementation);
}
self.base_type_def_ids.insert(local_def(item.id),
@ -418,16 +400,15 @@ impl CoherenceChecker {
}
}
pub fn add_inherent_method(&self,
base_def_id: def_id,
implementation: @Impl) {
pub fn add_inherent_impl(&self,
base_def_id: def_id,
implementation: @Impl) {
let tcx = self.crate_context.tcx;
let implementation_list;
match self.crate_context.coherence_info.inherent_methods
.find(&base_def_id) {
match tcx.inherent_impls.find(&base_def_id) {
None => {
implementation_list = @mut ~[];
self.crate_context.coherence_info.inherent_methods
.insert(base_def_id, implementation_list);
tcx.inherent_impls.insert(base_def_id, implementation_list);
}
Some(&existing_implementation_list) => {
implementation_list = existing_implementation_list;
@ -435,18 +416,17 @@ impl CoherenceChecker {
}
implementation_list.push(implementation);
ty::add_base_impl(self.crate_context.tcx, base_def_id, implementation);
}
pub fn add_trait_method(&self, trait_id: def_id, implementation: @Impl) {
pub fn add_trait_impl(&self,
base_def_id: def_id,
implementation: @Impl) {
let tcx = self.crate_context.tcx;
let implementation_list;
match self.crate_context.coherence_info.extension_methods
.find(&trait_id) {
match tcx.trait_impls.find(&base_def_id) {
None => {
implementation_list = @mut ~[];
self.crate_context.coherence_info.extension_methods
.insert(trait_id, implementation_list);
tcx.trait_impls.insert(base_def_id, implementation_list);
}
Some(&existing_implementation_list) => {
implementation_list = existing_implementation_list;
@ -457,8 +437,7 @@ impl CoherenceChecker {
}
pub fn check_implementation_coherence(&self) {
let coherence_info = &self.crate_context.coherence_info;
for coherence_info.extension_methods.each_key |&trait_id| {
for self.crate_context.tcx.trait_impls.each_key |&trait_id| {
self.check_implementation_coherence_of(trait_id);
}
}
@ -472,8 +451,6 @@ impl CoherenceChecker {
// "We have an impl of trait <trait_def_id> for type <polytype_a>,
// and that impl is <implementation_a>"
self.add_impl_for_trait(trait_def_id, polytype_a.ty,
implementation_a);
do self.iter_impls_of_trait(trait_def_id) |b| {
let implementation_b = b;
@ -494,32 +471,8 @@ impl CoherenceChecker {
}
}
// Adds an impl of trait trait_t for self type self_t; that impl
// is the_impl
pub fn add_impl_for_trait(&self,
trait_t: def_id,
self_t: t,
the_impl: @Impl) {
debug!("Adding impl %? of %? for %s",
the_impl.did, trait_t,
ty_to_str(self.crate_context.tcx, self_t));
match self.crate_context.tcx.trait_impls.find(&trait_t) {
None => {
let m = @mut HashMap::new();
m.insert(self_t, the_impl);
self.crate_context.tcx.trait_impls.insert(trait_t, m);
}
Some(&m) => {
m.insert(self_t, the_impl);
}
}
}
pub fn iter_impls_of_trait(&self, trait_def_id: def_id, f: &fn(@Impl)) {
let coherence_info = &self.crate_context.coherence_info;
let extension_methods = &*coherence_info.extension_methods;
match extension_methods.find(&trait_def_id) {
match self.crate_context.tcx.trait_impls.find(&trait_def_id) {
Some(impls) => {
for impls.iter().advance |&im| {
f(im);
@ -874,7 +827,7 @@ impl CoherenceChecker {
..*implementation
};
self.add_trait_method(trait_ref.def_id, implementation);
self.add_trait_impl(trait_ref.def_id, implementation);
}
// Add the implementation to the mapping from implementation to base
@ -887,8 +840,8 @@ impl CoherenceChecker {
// inherent methods apply to `impl Type` but not
// `impl Trait for Type`:
if associated_traits.is_none() {
self.add_inherent_method(base_type_def_id,
implementation);
self.add_inherent_impl(base_type_def_id,
implementation);
}
self.base_type_def_ids.insert(implementation.did,
@ -922,12 +875,11 @@ impl CoherenceChecker {
//
pub fn populate_destructor_table(&self) {
let coherence_info = &self.crate_context.coherence_info;
let tcx = self.crate_context.tcx;
let drop_trait = match tcx.lang_items.drop_trait() {
Some(id) => id, None => { return }
};
let impls_opt = coherence_info.extension_methods.find(&drop_trait);
let impls_opt = tcx.trait_impls.find(&drop_trait);
let impls;
match impls_opt {

View File

@ -192,7 +192,6 @@ pub struct CrateCtxt {
trait_map: resolve::TraitMap,
method_map: method_map,
vtable_map: vtable_map,
coherence_info: coherence::CoherenceInfo,
tcx: ty::ctxt
}
@ -415,7 +414,6 @@ pub fn check_crate(tcx: ty::ctxt,
trait_map: trait_map,
method_map: @mut HashMap::new(),
vtable_map: @mut HashMap::new(),
coherence_info: coherence::CoherenceInfo(),
tcx: tcx
};