rustc: Remove existing inheritance code from coherence
Inheritance will be implemented differently, hopefully simpler
This commit is contained in:
parent
28ecef7bf5
commit
daa89e0861
2 changed files with 48 additions and 90 deletions
|
@ -124,46 +124,8 @@ fn lookup_vtable_covariant(vcx: &VtableContext,
|
||||||
vcx.infcx.ty_to_str(ty),
|
vcx.infcx.ty_to_str(ty),
|
||||||
vcx.infcx.ty_to_str(trait_ty));
|
vcx.infcx.ty_to_str(trait_ty));
|
||||||
|
|
||||||
let worklist = dvec::DVec();
|
lookup_vtable_invariant(vcx, location_info, ty, trait_ty,
|
||||||
worklist.push(trait_ty);
|
allow_unsafe, is_early)
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up the vtable to use when treating an item of type `t` as if it has
|
// Look up the vtable to use when treating an item of type `t` as if it has
|
||||||
|
|
|
@ -144,9 +144,6 @@ struct CoherenceInfo {
|
||||||
// the associated trait must be imported at the call site.
|
// the associated trait must be imported at the call site.
|
||||||
extension_methods: HashMap<def_id,@DVec<@Impl>>,
|
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
|
// 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
|
// ID of the provided (a.k.a. default) methods in the traits that that
|
||||||
// implementation implements.
|
// implementation implements.
|
||||||
|
@ -157,7 +154,6 @@ fn CoherenceInfo() -> CoherenceInfo {
|
||||||
CoherenceInfo {
|
CoherenceInfo {
|
||||||
inherent_methods: HashMap(),
|
inherent_methods: HashMap(),
|
||||||
extension_methods: HashMap(),
|
extension_methods: HashMap(),
|
||||||
supertrait_to_subtraits: HashMap(),
|
|
||||||
provided_methods: HashMap(),
|
provided_methods: HashMap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,9 +200,6 @@ impl CoherenceChecker {
|
||||||
item_class(struct_def, _) => {
|
item_class(struct_def, _) => {
|
||||||
self.check_implementation(item, struct_def.traits);
|
self.check_implementation(item, struct_def.traits);
|
||||||
}
|
}
|
||||||
item_trait(_, supertraits, _) => {
|
|
||||||
self.register_inherited_trait(item, supertraits);
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
@ -215,12 +208,8 @@ impl CoherenceChecker {
|
||||||
.. *default_simple_visitor()
|
.. *default_simple_visitor()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Check trait coherence.
|
// Check that there are no overlapping trait instances
|
||||||
for self.crate_context.coherence_info.extension_methods.each
|
self.check_implementation_coherence();
|
||||||
|def_id, items| {
|
|
||||||
|
|
||||||
self.check_implementation_coherence(def_id, items);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether traits with base types are in privileged scopes.
|
// Check whether traits with base types are in privileged scopes.
|
||||||
self.check_privileged_scopes(crate);
|
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) {
|
fn add_inherent_method(base_def_id: def_id, implementation: @Impl) {
|
||||||
let implementation_list;
|
let implementation_list;
|
||||||
match self.crate_context.coherence_info.inherent_methods
|
match self.crate_context.coherence_info.inherent_methods
|
||||||
|
@ -432,32 +400,60 @@ impl CoherenceChecker {
|
||||||
implementation_list.push(implementation);
|
implementation_list.push(implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_implementation_coherence(_trait_def_id: def_id,
|
fn check_implementation_coherence() {
|
||||||
implementations: @DVec<@Impl>) {
|
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.
|
// Unify pairs of polytypes.
|
||||||
for range(0, implementations.len()) |i| {
|
do self.iter_impls_of_trait(trait_def_id) |a| {
|
||||||
let implementation_a = implementations.get_elt(i);
|
let implementation_a = a;
|
||||||
let polytype_a =
|
let polytype_a =
|
||||||
self.get_self_type_for_implementation(implementation_a);
|
self.get_self_type_for_implementation(implementation_a);
|
||||||
for range(i + 1, implementations.len()) |j| {
|
do self.iter_impls_of_trait(trait_def_id) |b| {
|
||||||
let implementation_b = implementations.get_elt(j);
|
let implementation_b = b;
|
||||||
let polytype_b =
|
|
||||||
self.get_self_type_for_implementation(implementation_b);
|
|
||||||
|
|
||||||
if self.polytypes_unify(polytype_a, polytype_b) {
|
// An impl is coherent with itself
|
||||||
let session = self.crate_context.tcx.sess;
|
if a.did != b.did {
|
||||||
session.span_err(self.span_of_impl(implementation_b),
|
let polytype_b = self.get_self_type_for_implementation(
|
||||||
~"conflicting implementations for a \
|
implementation_b);
|
||||||
trait");
|
|
||||||
session.span_note(self.span_of_impl(implementation_a),
|
if self.polytypes_unify(polytype_a, polytype_b) {
|
||||||
~"note conflicting implementation \
|
let session = self.crate_context.tcx.sess;
|
||||||
here");
|
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(
|
fn each_provided_trait_method(
|
||||||
trait_did: ast::def_id,
|
trait_did: ast::def_id,
|
||||||
f: &fn(x: &ty::method) -> bool) {
|
f: &fn(x: &ty::method) -> bool) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue