Skip to content

Commit 9d34c70

Browse files
committed
rustc: Move ty::impl_traits over to a multiple-traits-per-impl world
1 parent 3c583de commit 9d34c70

File tree

4 files changed

+64
-53
lines changed

4 files changed

+64
-53
lines changed

src/rustc/middle/resolve3.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3263,7 +3263,7 @@ class Resolver {
32633263
visitor: ResolveVisitor) {
32643264

32653265
// Add a type into the def map. This is needed to prevent an ICE in
3266-
// ty::impl_trait.
3266+
// ty::impl_traits.
32673267

32683268
// If applicable, create a rib for the type parameters.
32693269
let outer_type_parameter_count = (*type_parameters).len();

src/rustc/middle/trans/impl.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,12 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
253253
vtables: typeck::vtable_res) -> ValueRef {
254254
let _icx = ccx.insn_ctxt(~"impl::make_impl_vtable");
255255
let tcx = ccx.tcx;
256+
257+
// XXX: This should support multiple traits.
256258
let ifce_id = expect(ccx.sess,
257-
ty::ty_to_def_id(option::get(ty::impl_trait(tcx,
258-
impl_id))),
259+
ty::ty_to_def_id(ty::impl_traits(tcx, impl_id)[0]),
259260
|| ~"make_impl_vtable: non-trait-type implemented");
261+
260262
let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
261263
make_vtable(ccx, vec::map(*ty::trait_methods(tcx, ifce_id), |im| {
262264
let fty = ty::subst_tps(tcx, substs, ty::mk_fn(tcx, im.fty));

src/rustc/middle/ty.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export subst, subst_tps, substs_is_noop, substs_to_str, substs;
6565
export t;
6666
export new_ty_hash;
6767
export enum_variants, substd_enum_variants, enum_is_univariant;
68-
export trait_methods, store_trait_methods, impl_trait;
68+
export trait_methods, store_trait_methods, impl_traits;
6969
export enum_variant_with_id;
7070
export ty_dtor;
7171
export ty_param_bounds_and_ty;
@@ -2474,38 +2474,48 @@ fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
24742474
result
24752475
}
24762476

2477-
// XXX: Needs to return an array of traits.
2478-
fn impl_trait(cx: ctxt, id: ast::def_id) -> option<t> {
2477+
fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
24792478
if id.crate == ast::local_crate {
2480-
#debug("(impl_trait) searching for trait impl %?", id);
2479+
#debug("(impl_traits) searching for trait impl %?", id);
24812480
alt cx.items.find(id.node) {
24822481
some(ast_map::node_item(@{
2483-
node: ast::item_impl(_, traits, _, _),
2484-
_},
2485-
_)) if traits.len() >= 1 {
2486-
some(node_id_to_type(cx, traits[0].ref_id))
2482+
node: ast::item_impl(_, trait_refs, _, _),
2483+
_},
2484+
_)) {
2485+
2486+
do vec::map(trait_refs) |trait_ref| {
2487+
node_id_to_type(cx, trait_ref.ref_id)
2488+
}
24872489
}
24882490
some(ast_map::node_item(@{node: ast::item_class(*),
24892491
_},_)) {
24902492
alt cx.def_map.find(id.node) {
24912493
some(def_ty(trait_id)) {
24922494
// XXX: Doesn't work cross-crate.
2493-
#debug("(impl_trait) found trait id %?", trait_id);
2494-
some(node_id_to_type(cx, trait_id.node))
2495+
#debug("(impl_traits) found trait id %?", trait_id);
2496+
~[node_id_to_type(cx, trait_id.node)]
24952497
}
24962498
some(x) {
2497-
cx.sess.bug(#fmt("impl_trait: trait ref is in trait map \
2499+
cx.sess.bug(#fmt("impl_traits: trait ref is in trait map \
24982500
but is bound to %?", x));
24992501
}
25002502
none {
2501-
none
2503+
~[]
25022504
}
25032505
}
25042506
}
2505-
_ { none }
2507+
_ { ~[] }
25062508
}
25072509
} else {
2508-
csearch::get_impl_trait(cx, id)
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+
}
25092519
}
25102520
}
25112521

src/rustc/middle/typeck/check/vtable.rs

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -119,44 +119,41 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
119119
for vec::each(*impls) |im| {
120120
// im = one specific impl
121121
// find the trait that im implements (if any)
122-
let of_ty = alt ty::impl_trait(tcx, im.did) {
123-
some(of_ty) { of_ty }
124-
_ { again; }
125-
};
126-
127-
// it must have the same id as the expected one
128-
alt ty::get(of_ty).struct {
129-
ty::ty_trait(id, _) if id != trait_id { again; }
130-
_ { /* ok */ }
131-
}
122+
for vec::each(ty::impl_traits(tcx, im.did)) |of_ty| {
123+
// it must have the same id as the expected one
124+
alt ty::get(of_ty).struct {
125+
ty::ty_trait(id, _) if id != trait_id { again; }
126+
_ { /* ok */ }
127+
}
132128

133-
// check whether the type unifies with the type
134-
// that the impl is for, and continue if not
135-
let {substs: substs, ty: for_ty} =
136-
impl_self_ty(fcx, im.did);
137-
let im_bs = ty::lookup_item_type(tcx, im.did).bounds;
138-
alt fcx.mk_subty(ty, for_ty) {
139-
result::err(_) { again; }
140-
result::ok(()) { }
141-
}
129+
// check whether the type unifies with the type
130+
// that the impl is for, and continue if not
131+
let {substs: substs, ty: for_ty} =
132+
impl_self_ty(fcx, im.did);
133+
let im_bs = ty::lookup_item_type(tcx, im.did).bounds;
134+
alt fcx.mk_subty(ty, for_ty) {
135+
result::err(_) { again; }
136+
result::ok(()) { }
137+
}
142138

143-
// check that desired trait type unifies
144-
#debug("(checking vtable) @2 relating trait ty %s to \
145-
of_ty %s",
146-
fcx.infcx.ty_to_str(trait_ty),
147-
fcx.infcx.ty_to_str(of_ty));
148-
let of_ty = ty::subst(tcx, substs, of_ty);
149-
relate_trait_tys(fcx, sp, trait_ty, of_ty);
139+
// check that desired trait type unifies
140+
#debug("(checking vtable) @2 relating trait ty %s to \
141+
of_ty %s",
142+
fcx.infcx.ty_to_str(trait_ty),
143+
fcx.infcx.ty_to_str(of_ty));
144+
let of_ty = ty::subst(tcx, substs, of_ty);
145+
relate_trait_tys(fcx, sp, trait_ty, of_ty);
150146

151-
// recursively process the bounds
152-
let trait_tps = trait_substs.tps;
153-
let substs_f = fixup_substs(fcx, sp, trait_id, substs);
154-
connect_trait_tps(fcx, sp, substs_f.tps,
155-
trait_tps, im.did);
156-
let subres = lookup_vtables(fcx, isc, sp,
157-
im_bs, substs_f, false);
158-
vec::push(found,
159-
vtable_static(im.did, substs_f.tps, subres));
147+
// recursively process the bounds
148+
let trait_tps = trait_substs.tps;
149+
let substs_f = fixup_substs(fcx, sp, trait_id, substs);
150+
connect_trait_tps(fcx, sp, substs_f.tps,
151+
trait_tps, im.did);
152+
let subres = lookup_vtables(fcx, isc, sp,
153+
im_bs, substs_f, false);
154+
vec::push(found,
155+
vtable_static(im.did, substs_f.tps, subres));
156+
}
160157
}
161158

162159
alt found.len() {
@@ -195,7 +192,9 @@ fn fixup_ty(fcx: @fn_ctxt, sp: span, ty: ty::t) -> ty::t {
195192
fn connect_trait_tps(fcx: @fn_ctxt, sp: span, impl_tys: ~[ty::t],
196193
trait_tys: ~[ty::t], impl_did: ast::def_id) {
197194
let tcx = fcx.ccx.tcx;
198-
let ity = option::get(ty::impl_trait(tcx, impl_did));
195+
196+
// XXX: This should work for multiple traits.
197+
let ity = ty::impl_traits(tcx, impl_did)[0];
199198
let trait_ty = ty::subst_tps(tcx, impl_tys, ity);
200199
#debug("(connect trait tps) trait type is %?, impl did is %?",
201200
ty::get(trait_ty).struct, impl_did);

0 commit comments

Comments
 (0)