Make resolution of dictionaries on bounded params work

Issue #1227
This commit is contained in:
Marijn Haverbeke 2012-01-03 16:37:41 +01:00
parent 5ea3c96938
commit 4e88d5ae92
3 changed files with 19 additions and 8 deletions

View File

@ -147,6 +147,8 @@ fn get_dict(bcx: @block_ctxt, origin: typeck::dict_origin) -> result {
}
rslt(bcx, PointerCast(bcx, dict, T_ptr(T_dict())))
}
typeck::dict_param(_param) { fail "FIXME[impl]"; }
typeck::dict_param(n_param, n_bound) {
rslt(bcx, option::get(bcx.fcx.lltyparams[n_param].dicts)[n_bound])
}
}
}

View File

@ -1515,10 +1515,10 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
}
_ {}
}
bound_n += 1u;
}
_ {}
}
bound_n += 1u;
}
ret none;
}
@ -2868,7 +2868,8 @@ fn check_for_main_fn(tcx: ty::ctxt, crate: @ast::crate) {
type dict_res = @[dict_origin];
tag dict_origin {
dict_static(ast::def_id, [ty::t], dict_res);
dict_param(uint);
// Param number, bound number
dict_param(uint, uint);
}
type dict_map = hashmap<ast::node_id, dict_res>;
@ -2882,7 +2883,7 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
dict_map: dict_map};
let cx = {tcx: tcx, impl_map: impl_map,
method_map: method_map, dict_map: new_int_hash()};
fn has_iface_bounds(tps: [ty::param_bounds]) -> bool {
vec::any(tps, {|bs|
vec::any(*bs, {|b|
@ -2947,21 +2948,23 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map,
}
fn lookup_dict(tcx: ty::ctxt, isc: resolve::iscopes, sp: span,
ty: ty::t, iface_ty: ty::t) -> dict_origin {
ty: ty::t, iface_ty: ty::t) -> dict_origin {
let iface_id = alt ty::struct(tcx, iface_ty) {
ty::ty_iface(did, _) { did }
_ { tcx.sess.abort_if_errors(); fail; }
};
alt ty::struct(tcx, ty) {
ty::ty_param(n, did) {
let n_bound = 0u;
for bound in *tcx.ty_param_bounds.get(did.node) {
alt bound {
ty::bound_iface(ity) {
alt ty::struct(tcx, ity) {
ty::ty_iface(idid, _) {
if did == idid { ret dict_param(n); }
if iface_id == idid { ret dict_param(n, n_bound); }
}
}
n_bound += 1u;
}
_ {}
}

View File

@ -13,10 +13,16 @@ impl <T: to_str> of to_str for [T] {
}
fn main() {
assert 1.to_str() == "1";
assert [2, 3, 4].to_str() == "[2, 3, 4]";
fn indirect<T: to_str>(x: T) -> str {
x.to_str() + "!"
}
assert 1.to_str() == "1";
assert [2, 3, 4].to_str() == "[2, 3, 4]";
assert indirect([10, 20]) == "[10, 20]!";
fn indirect2<T: to_str>(x: T) -> str {
indirect(x)
}
assert indirect2([1]) == "[1]!";
}