rustc: Remove existing inheritance code from coherence

Inheritance will be implemented differently, hopefully simpler
This commit is contained in:
Brian Anderson 2012-11-28 11:48:34 -08:00
parent 28ecef7bf5
commit daa89e0861
2 changed files with 48 additions and 90 deletions

View File

@ -124,46 +124,8 @@ fn lookup_vtable_covariant(vcx: &VtableContext,
vcx.infcx.ty_to_str(ty),
vcx.infcx.ty_to_str(trait_ty));
let worklist = dvec::DVec();
worklist.push(trait_ty);
while worklist.len() > 0 {
let trait_ty = worklist.pop();
let result = lookup_vtable_invariant(vcx, location_info, ty, trait_ty,
allow_unsafe, is_early);
if result.is_some() {
return result;
}
// Add subtraits to the worklist, if applicable.
match ty::get(trait_ty).sty {
ty::ty_trait(trait_id, _, _) => {
let table = vcx.ccx.coherence_info.supertrait_to_subtraits;
match table.find(trait_id) {
None => {}
Some(subtraits) => {
for subtraits.each |subtrait_id| {
// XXX: This is wrong; subtraits should themselves
// have substs.
let substs =
{ self_r: None, self_ty: None, tps: ~[] };
let trait_ty = ty::mk_trait(vcx.tcx(),
*subtrait_id,
substs,
ty::vstore_box);
worklist.push(trait_ty);
}
}
}
}
_ => {
vcx.tcx().sess.impossible_case(location_info.span,
"lookup_vtable_covariant: \
non-trait in worklist");
}
}
}
return None;
lookup_vtable_invariant(vcx, location_info, ty, trait_ty,
allow_unsafe, is_early)
}
// Look up the vtable to use when treating an item of type `t` as if it has

View File

@ -144,9 +144,6 @@ struct CoherenceInfo {
// the associated trait must be imported at the call site.
extension_methods: HashMap<def_id,@DVec<@Impl>>,
// A mapping from a supertrait to its subtraits.
supertrait_to_subtraits: HashMap<def_id,@DVec<def_id>>,
// A mapping from an implementation ID to the method info and trait method
// ID of the provided (a.k.a. default) methods in the traits that that
// implementation implements.
@ -157,7 +154,6 @@ fn CoherenceInfo() -> CoherenceInfo {
CoherenceInfo {
inherent_methods: HashMap(),
extension_methods: HashMap(),
supertrait_to_subtraits: HashMap(),
provided_methods: HashMap(),
}
}
@ -204,9 +200,6 @@ impl CoherenceChecker {
item_class(struct_def, _) => {
self.check_implementation(item, struct_def.traits);
}
item_trait(_, supertraits, _) => {
self.register_inherited_trait(item, supertraits);
}
_ => {
// Nothing to do.
}
@ -215,12 +208,8 @@ impl CoherenceChecker {
.. *default_simple_visitor()
}));
// Check trait coherence.
for self.crate_context.coherence_info.extension_methods.each
|def_id, items| {
self.check_implementation_coherence(def_id, items);
}
// Check that there are no overlapping trait instances
self.check_implementation_coherence();
// Check whether traits with base types are in privileged scopes.
self.check_privileged_scopes(crate);
@ -377,27 +366,6 @@ impl CoherenceChecker {
}
}
fn register_inherited_trait(item: @item, supertraits: ~[@trait_ref]) {
// XXX: This is wrong. We need to support substitutions; e.g.
// trait Foo : Bar<int>.
let supertrait_to_subtraits =
self.crate_context.coherence_info.supertrait_to_subtraits;
let subtrait_id = local_def(item.id);
for supertraits.each |supertrait| {
let supertrait_id = self.trait_ref_to_trait_def_id(*supertrait);
match supertrait_to_subtraits.find(supertrait_id) {
None => {
let new_vec = @dvec::DVec();
new_vec.push(subtrait_id);
supertrait_to_subtraits.insert(supertrait_id, new_vec);
}
Some(existing_vec) => {
existing_vec.push(subtrait_id);
}
}
}
}
fn add_inherent_method(base_def_id: def_id, implementation: @Impl) {
let implementation_list;
match self.crate_context.coherence_info.inherent_methods
@ -432,32 +400,60 @@ impl CoherenceChecker {
implementation_list.push(implementation);
}
fn check_implementation_coherence(_trait_def_id: def_id,
implementations: @DVec<@Impl>) {
fn check_implementation_coherence() {
let coherence_info = &self.crate_context.coherence_info;
let extension_methods = &coherence_info.extension_methods;
for extension_methods.each_key |trait_id| {
self.check_implementation_coherence_of(trait_id);
}
}
fn check_implementation_coherence_of(trait_def_id: def_id) {
// Unify pairs of polytypes.
for range(0, implementations.len()) |i| {
let implementation_a = implementations.get_elt(i);
do self.iter_impls_of_trait(trait_def_id) |a| {
let implementation_a = a;
let polytype_a =
self.get_self_type_for_implementation(implementation_a);
for range(i + 1, implementations.len()) |j| {
let implementation_b = implementations.get_elt(j);
let polytype_b =
self.get_self_type_for_implementation(implementation_b);
do self.iter_impls_of_trait(trait_def_id) |b| {
let implementation_b = b;
if self.polytypes_unify(polytype_a, polytype_b) {
let session = self.crate_context.tcx.sess;
session.span_err(self.span_of_impl(implementation_b),
~"conflicting implementations for a \
trait");
session.span_note(self.span_of_impl(implementation_a),
~"note conflicting implementation \
here");
// An impl is coherent with itself
if a.did != b.did {
let polytype_b = self.get_self_type_for_implementation(
implementation_b);
if self.polytypes_unify(polytype_a, polytype_b) {
let session = self.crate_context.tcx.sess;
session.span_err(self.span_of_impl(implementation_b),
~"conflicting implementations for a \
trait");
session.span_note(self.span_of_impl(implementation_a),
~"note conflicting implementation \
here");
}
}
}
}
}
fn iter_impls_of_trait(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) {
Some(impls) => {
for uint::range(0, impls.len()) |i| {
f(impls[i]);
}
}
None => { /* no impls? */ }
}
}
fn each_provided_trait_method(
trait_did: ast::def_id,
f: &fn(x: &ty::method) -> bool) {