Start of data structure cleanup for trait system. Get rid of CoherenceInfo, make trait_impls less bogus.
This commit is contained in:
parent
874eb1939b
commit
37702216eb
@ -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| {
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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(
|
||||
|
@ -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.
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user