Skip to content

Commit 57e8de8

Browse files
committed
rustc: Implement multiple-traits-per-impl for cross-crate stuff
1 parent 635a959 commit 57e8de8

File tree

4 files changed

+46
-60
lines changed

4 files changed

+46
-60
lines changed

src/rustc/metadata/csearch.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export get_trait_methods;
2727
export get_method_names_if_trait;
2828
export each_path;
2929
export get_type;
30-
export get_impl_trait;
30+
export get_impl_traits;
3131
export get_impl_method;
3232
export get_item_path;
3333
export maybe_get_item_ast, found_ast, found, found_parent, not_found;
@@ -187,12 +187,13 @@ fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
187187
ret {bounds: @~[], rp: false, ty: ty};
188188
}
189189

190-
// Given a def_id for an impl or class, return the trait it implements,
191-
// or none if it's not for an impl or for a class that implements traits
192-
fn get_impl_trait(tcx: ty::ctxt, def: ast::def_id) -> option<ty::t> {
190+
// Given a def_id for an impl or class, return the traits it implements,
191+
// or the empty vector if it's not for an impl or for a class that implements
192+
// traits
193+
fn get_impl_traits(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::t] {
193194
let cstore = tcx.cstore;
194195
let cdata = cstore::get_crate_data(cstore, def.crate);
195-
decoder::get_impl_trait(cdata, def.node, tcx)
196+
decoder::get_impl_traits(cdata, def.node, tcx)
196197
}
197198

198199
fn get_impl_method(cstore: cstore::cstore,

src/rustc/metadata/decoder.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export get_enum_variants;
2424
export get_type;
2525
export get_region_param;
2626
export get_type_param_count;
27-
export get_impl_trait;
27+
export get_impl_traits;
2828
export get_class_method;
2929
export get_impl_method;
3030
export lookup_def;
@@ -168,13 +168,12 @@ fn item_type(item_id: ast::def_id, item: ebml::doc,
168168
} else { t }
169169
}
170170

171-
fn item_impl_trait(item: ebml::doc, tcx: ty::ctxt, cdata: cmd)
172-
-> option<ty::t> {
173-
let mut result = none;
171+
fn item_impl_traits(item: ebml::doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] {
172+
let mut results = ~[];
174173
do ebml::tagged_docs(item, tag_impl_trait) |ity| {
175-
result = some(doc_type(ity, tcx, cdata));
174+
vec::push(results, doc_type(ity, tcx, cdata));
176175
};
177-
result
176+
results
178177
}
179178

180179
fn item_ty_param_bounds(item: ebml::doc, tcx: ty::ctxt, cdata: cmd)
@@ -333,9 +332,8 @@ fn get_type_param_count(data: @~[u8], id: ast::node_id) -> uint {
333332
item_ty_param_count(lookup_item(id, data))
334333
}
335334

336-
fn get_impl_trait(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
337-
-> option<ty::t> {
338-
item_impl_trait(lookup_item(id, cdata.data), tcx, cdata)
335+
fn get_impl_traits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> ~[ty::t] {
336+
item_impl_traits(lookup_item(id, cdata.data), tcx, cdata)
339337
}
340338

341339
fn get_impl_method(cdata: cmd, id: ast::node_id,

src/rustc/middle/ty.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,15 +2507,7 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
25072507
_ { ~[] }
25082508
}
25092509
} else {
2510-
// XXX: csearch::get_impl_trait should return a vector.
2511-
alt csearch::get_impl_trait(cx, id) {
2512-
none {
2513-
~[]
2514-
}
2515-
some(trait_ref) {
2516-
~[trait_ref]
2517-
}
2518-
}
2510+
csearch::get_impl_traits(cx, id)
25192511
}
25202512
}
25212513

src/rustc/middle/typeck/coherence.rs

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// has at most one implementation for each type. Then we build a mapping from
55
// each trait in the system to its implementations.
66

7-
import metadata::csearch::{each_path, get_impl_trait, get_impls_for_mod};
7+
import metadata::csearch::{each_path, get_impl_traits, get_impls_for_mod};
88
import metadata::cstore::{cstore, iter_crate_data};
99
import metadata::decoder::{dl_def, dl_field, dl_impl};
1010
import middle::resolve3::Impl;
@@ -546,45 +546,40 @@ class CoherenceChecker {
546546

547547
let self_type = lookup_item_type(self.crate_context.tcx,
548548
implementation.did);
549-
let optional_trait =
550-
get_impl_trait(self.crate_context.tcx,
551-
implementation.did);
552-
alt optional_trait {
553-
none {
554-
// This is an inherent method. There should be
555-
// no problems here, but perform a sanity check
556-
// anyway.
557-
558-
alt get_base_type_def_id(self.inference_context,
559-
dummy_sp(),
560-
self_type.ty) {
561-
none {
562-
let session = self.crate_context.tcx.sess;
563-
session.bug(#fmt("no base type for \
564-
external impl with no \
565-
trait: %s (type %s)!",
566-
*implementation.ident,
567-
ty_to_str
568-
(self.crate_context.tcx,
569-
self_type.ty)));
570-
}
571-
some(_) {
572-
// Nothing to do.
573-
}
549+
let associated_traits = get_impl_traits(self.crate_context.tcx,
550+
implementation.did);
551+
552+
// Do a sanity check to make sure that inherent methods have base
553+
// types.
554+
555+
if associated_traits.len() == 0 {
556+
alt get_base_type_def_id(self.inference_context,
557+
dummy_sp(),
558+
self_type.ty) {
559+
none {
560+
let session = self.crate_context.tcx.sess;
561+
session.bug(#fmt("no base type for external impl \
562+
with no trait: %s (type %s)!",
563+
*implementation.ident,
564+
ty_to_str(self.crate_context.tcx,
565+
self_type.ty)));
566+
}
567+
some(_) {
568+
// Nothing to do.
574569
}
575570
}
571+
}
576572

577-
some(trait_type) {
578-
alt get(trait_type).struct {
579-
ty_trait(trait_id, _) {
580-
self.add_trait_method(trait_id,
581-
implementation);
582-
}
583-
_ {
584-
self.crate_context.tcx.sess
585-
.bug(~"trait type returned is not a \
586-
trait");
587-
}
573+
// Record all the trait methods.
574+
for associated_traits.each |trait_type| {
575+
alt get(trait_type).struct {
576+
ty_trait(trait_id, _) {
577+
self.add_trait_method(trait_id, implementation);
578+
}
579+
_ {
580+
self.crate_context.tcx.sess.bug(~"trait type \
581+
returned is not a \
582+
trait");
588583
}
589584
}
590585
}

0 commit comments

Comments
 (0)