rustc: Move ty::impl_traits over to a multiple-traits-per-impl world
This commit is contained in:
@@ -3263,7 +3263,7 @@ class Resolver {
|
|||||||
visitor: ResolveVisitor) {
|
visitor: ResolveVisitor) {
|
||||||
|
|
||||||
// Add a type into the def map. This is needed to prevent an ICE in
|
// Add a type into the def map. This is needed to prevent an ICE in
|
||||||
// ty::impl_trait.
|
// ty::impl_traits.
|
||||||
|
|
||||||
// If applicable, create a rib for the type parameters.
|
// If applicable, create a rib for the type parameters.
|
||||||
let outer_type_parameter_count = (*type_parameters).len();
|
let outer_type_parameter_count = (*type_parameters).len();
|
||||||
|
|||||||
@@ -253,10 +253,12 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
|
|||||||
vtables: typeck::vtable_res) -> ValueRef {
|
vtables: typeck::vtable_res) -> ValueRef {
|
||||||
let _icx = ccx.insn_ctxt(~"impl::make_impl_vtable");
|
let _icx = ccx.insn_ctxt(~"impl::make_impl_vtable");
|
||||||
let tcx = ccx.tcx;
|
let tcx = ccx.tcx;
|
||||||
|
|
||||||
|
// XXX: This should support multiple traits.
|
||||||
let ifce_id = expect(ccx.sess,
|
let ifce_id = expect(ccx.sess,
|
||||||
ty::ty_to_def_id(option::get(ty::impl_trait(tcx,
|
ty::ty_to_def_id(ty::impl_traits(tcx, impl_id)[0]),
|
||||||
impl_id))),
|
|
||||||
|| ~"make_impl_vtable: non-trait-type implemented");
|
|| ~"make_impl_vtable: non-trait-type implemented");
|
||||||
|
|
||||||
let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
|
let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
|
||||||
make_vtable(ccx, vec::map(*ty::trait_methods(tcx, ifce_id), |im| {
|
make_vtable(ccx, vec::map(*ty::trait_methods(tcx, ifce_id), |im| {
|
||||||
let fty = ty::subst_tps(tcx, substs, ty::mk_fn(tcx, im.fty));
|
let fty = ty::subst_tps(tcx, substs, ty::mk_fn(tcx, im.fty));
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export subst, subst_tps, substs_is_noop, substs_to_str, substs;
|
|||||||
export t;
|
export t;
|
||||||
export new_ty_hash;
|
export new_ty_hash;
|
||||||
export enum_variants, substd_enum_variants, enum_is_univariant;
|
export enum_variants, substd_enum_variants, enum_is_univariant;
|
||||||
export trait_methods, store_trait_methods, impl_trait;
|
export trait_methods, store_trait_methods, impl_traits;
|
||||||
export enum_variant_with_id;
|
export enum_variant_with_id;
|
||||||
export ty_dtor;
|
export ty_dtor;
|
||||||
export ty_param_bounds_and_ty;
|
export ty_param_bounds_and_ty;
|
||||||
@@ -2474,38 +2474,48 @@ fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: Needs to return an array of traits.
|
fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
|
||||||
fn impl_trait(cx: ctxt, id: ast::def_id) -> option<t> {
|
|
||||||
if id.crate == ast::local_crate {
|
if id.crate == ast::local_crate {
|
||||||
#debug("(impl_trait) searching for trait impl %?", id);
|
#debug("(impl_traits) searching for trait impl %?", id);
|
||||||
alt cx.items.find(id.node) {
|
alt cx.items.find(id.node) {
|
||||||
some(ast_map::node_item(@{
|
some(ast_map::node_item(@{
|
||||||
node: ast::item_impl(_, traits, _, _),
|
node: ast::item_impl(_, trait_refs, _, _),
|
||||||
_},
|
_},
|
||||||
_)) if traits.len() >= 1 {
|
_)) {
|
||||||
some(node_id_to_type(cx, traits[0].ref_id))
|
|
||||||
|
do vec::map(trait_refs) |trait_ref| {
|
||||||
|
node_id_to_type(cx, trait_ref.ref_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
some(ast_map::node_item(@{node: ast::item_class(*),
|
some(ast_map::node_item(@{node: ast::item_class(*),
|
||||||
_},_)) {
|
_},_)) {
|
||||||
alt cx.def_map.find(id.node) {
|
alt cx.def_map.find(id.node) {
|
||||||
some(def_ty(trait_id)) {
|
some(def_ty(trait_id)) {
|
||||||
// XXX: Doesn't work cross-crate.
|
// XXX: Doesn't work cross-crate.
|
||||||
#debug("(impl_trait) found trait id %?", trait_id);
|
#debug("(impl_traits) found trait id %?", trait_id);
|
||||||
some(node_id_to_type(cx, trait_id.node))
|
~[node_id_to_type(cx, trait_id.node)]
|
||||||
}
|
}
|
||||||
some(x) {
|
some(x) {
|
||||||
cx.sess.bug(#fmt("impl_trait: trait ref is in trait map \
|
cx.sess.bug(#fmt("impl_traits: trait ref is in trait map \
|
||||||
but is bound to %?", x));
|
but is bound to %?", x));
|
||||||
}
|
}
|
||||||
none {
|
none {
|
||||||
none
|
~[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ { none }
|
_ { ~[] }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
csearch::get_impl_trait(cx, id)
|
// XXX: csearch::get_impl_trait should return a vector.
|
||||||
|
alt csearch::get_impl_trait(cx, id) {
|
||||||
|
none {
|
||||||
|
~[]
|
||||||
|
}
|
||||||
|
some(trait_ref) {
|
||||||
|
~[trait_ref]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,11 +119,7 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
|
|||||||
for vec::each(*impls) |im| {
|
for vec::each(*impls) |im| {
|
||||||
// im = one specific impl
|
// im = one specific impl
|
||||||
// find the trait that im implements (if any)
|
// find the trait that im implements (if any)
|
||||||
let of_ty = alt ty::impl_trait(tcx, im.did) {
|
for vec::each(ty::impl_traits(tcx, im.did)) |of_ty| {
|
||||||
some(of_ty) { of_ty }
|
|
||||||
_ { again; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// it must have the same id as the expected one
|
// it must have the same id as the expected one
|
||||||
alt ty::get(of_ty).struct {
|
alt ty::get(of_ty).struct {
|
||||||
ty::ty_trait(id, _) if id != trait_id { again; }
|
ty::ty_trait(id, _) if id != trait_id { again; }
|
||||||
@@ -158,6 +154,7 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
|
|||||||
vec::push(found,
|
vec::push(found,
|
||||||
vtable_static(im.did, substs_f.tps, subres));
|
vtable_static(im.did, substs_f.tps, subres));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
alt found.len() {
|
alt found.len() {
|
||||||
0u { /* fallthrough */ }
|
0u { /* fallthrough */ }
|
||||||
@@ -195,7 +192,9 @@ fn fixup_ty(fcx: @fn_ctxt, sp: span, ty: ty::t) -> ty::t {
|
|||||||
fn connect_trait_tps(fcx: @fn_ctxt, sp: span, impl_tys: ~[ty::t],
|
fn connect_trait_tps(fcx: @fn_ctxt, sp: span, impl_tys: ~[ty::t],
|
||||||
trait_tys: ~[ty::t], impl_did: ast::def_id) {
|
trait_tys: ~[ty::t], impl_did: ast::def_id) {
|
||||||
let tcx = fcx.ccx.tcx;
|
let tcx = fcx.ccx.tcx;
|
||||||
let ity = option::get(ty::impl_trait(tcx, impl_did));
|
|
||||||
|
// XXX: This should work for multiple traits.
|
||||||
|
let ity = ty::impl_traits(tcx, impl_did)[0];
|
||||||
let trait_ty = ty::subst_tps(tcx, impl_tys, ity);
|
let trait_ty = ty::subst_tps(tcx, impl_tys, ity);
|
||||||
#debug("(connect trait tps) trait type is %?, impl did is %?",
|
#debug("(connect trait tps) trait type is %?, impl did is %?",
|
||||||
ty::get(trait_ty).struct, impl_did);
|
ty::get(trait_ty).struct, impl_did);
|
||||||
|
|||||||
Reference in New Issue
Block a user