rustc: Have trans get the type parameters from the annotation instead of trying to deduce them itself. Un-XFAIL generic-fn-twice.rs.

This commit is contained in:
Patrick Walton 2011-03-08 16:51:23 -08:00
parent 67a9532dee
commit e62424944b
2 changed files with 81 additions and 25 deletions

View File

@ -452,7 +452,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
foreach-nested.rs \
foreach-put-structured.rs \
foreach-simple-outer-slot.rs \
generic-fn-twice.rs \
generic-iter-frame.rs \
generic-tag-alt.rs \
generic-tag-values.rs \

View File

@ -503,7 +503,8 @@ fn type_of_fn_full(@crate_ctxt cx,
ast.proto proto,
option.t[TypeRef] obj_self,
vec[ty.arg] inputs,
@ty.t output) -> TypeRef {
@ty.t output,
uint ty_param_count) -> TypeRef {
let vec[TypeRef] atys = vec();
// Arg 0: Output pointer.
@ -529,10 +530,6 @@ fn type_of_fn_full(@crate_ctxt cx,
// Args >3: ty params, if not acquired via capture...
if (obj_self == none[TypeRef]) {
auto ty_param_count =
ty.count_ty_params(plain_ty(ty.ty_fn(proto,
inputs,
output)));
auto i = 0u;
while (i < ty_param_count) {
atys += T_ptr(T_tydesc(cx.tn));
@ -547,7 +544,7 @@ fn type_of_fn_full(@crate_ctxt cx,
atys += T_fn_pair(cx.tn,
type_of_fn_full(cx, ast.proto_fn, none[TypeRef],
vec(rec(mode=ast.val, ty=output)),
plain_ty(ty.ty_nil)));
plain_ty(ty.ty_nil), 0u));
}
// ... then explicit args.
@ -558,8 +555,11 @@ fn type_of_fn_full(@crate_ctxt cx,
fn type_of_fn(@crate_ctxt cx,
ast.proto proto,
vec[ty.arg] inputs, @ty.t output) -> TypeRef {
ret type_of_fn_full(cx, proto, none[TypeRef], inputs, output);
vec[ty.arg] inputs,
@ty.t output,
uint ty_param_count) -> TypeRef {
ret type_of_fn_full(cx, proto, none[TypeRef], inputs, output,
ty_param_count);
}
fn type_of_native_fn(@crate_ctxt cx, ast.native_abi abi,
@ -634,7 +634,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
llty = T_struct(tys);
}
case (ty.ty_fn(?proto, ?args, ?out)) {
llty = T_fn_pair(cx.tn, type_of_fn(cx, proto, args, out));
llty = T_fn_pair(cx.tn, type_of_fn(cx, proto, args, out, 0u));
}
case (ty.ty_native_fn(?abi, ?args, ?out)) {
llty = T_fn_pair(cx.tn, type_of_native_fn(cx, abi, args, out));
@ -648,7 +648,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
let TypeRef mty =
type_of_fn_full(cx, m.proto,
some[TypeRef](self_ty),
m.inputs, m.output);
m.inputs, m.output, 0u);
mtys += T_ptr(mty);
}
let TypeRef vtbl = T_struct(mtys);
@ -2820,7 +2820,7 @@ fn trans_for_each(@block_ctxt cx,
auto iter_body_llty = type_of_fn_full(cx.fcx.ccx, ast.proto_fn,
none[TypeRef],
vec(rec(mode=ast.val, ty=decl_ty)),
plain_ty(ty.ty_nil));
plain_ty(ty.ty_nil), 0u);
let ValueRef lliterbody = decl_fastcall_fn(cx.fcx.ccx.llmod,
s, iter_body_llty);
@ -3447,6 +3447,16 @@ fn trans_bind_thunk(@crate_ctxt cx,
auto lltargetfn = bcx.build.GEP(lltarget.val,
vec(C_int(0),
C_int(abi.fn_field_code)));
// Cast the outgoing function to the appropriate type (see the comments in
// trans_bind below for why this is necessary).
auto lltargetty = type_of_fn(bcx.fcx.ccx,
ty.ty_fn_proto(outgoing_fty),
outgoing_args,
outgoing_ret_ty,
ty_param_count);
lltargetfn = bcx.build.PointerCast(lltargetfn, T_ptr(T_ptr(lltargetty)));
lltargetfn = bcx.build.Load(lltargetfn);
auto r = bcx.build.FastCall(lltargetfn, llargs);
@ -3551,12 +3561,26 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
bcx = bindings_tydesc.bcx;
bcx.build.Store(bindings_tydesc.val, bound_tydesc);
// Determine the LLVM type for the outgoing function type. This
// may be different from the type returned by trans_malloc_boxed()
// since we have more information than that function does;
// specifically, we know how many type descriptors the outgoing
// function has, which type_of() doesn't, as only we know which
// item the function refers to.
auto llfnty = type_of_fn(bcx.fcx.ccx,
ty.ty_fn_proto(outgoing_fty),
ty.ty_fn_args(outgoing_fty),
ty.ty_fn_ret(outgoing_fty),
ty_param_count);
auto llclosurety = T_ptr(T_fn_pair(bcx.fcx.ccx.tn, llfnty));
// Store thunk-target.
auto bound_target =
bcx.build.GEP(closure,
vec(C_int(0),
C_int(abi.closure_elt_target)));
auto src = bcx.build.Load(f_res.res.val);
bound_target = bcx.build.PointerCast(bound_target, llclosurety);
bcx.build.Store(src, bound_target);
// Copy expr values into boxed bindings.
@ -4691,7 +4715,8 @@ fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
case (ty.ty_fn(?proto, ?inputs, ?output)) {
llfnty = type_of_fn_full(cx, proto,
some[TypeRef](self_ty),
inputs, output);
inputs, output,
_vec.len[ast.ty_param](ty_params));
}
}
@ -4990,11 +5015,23 @@ fn get_pair_fn_ty(TypeRef llpairty) -> TypeRef {
fn decl_fn_and_pair(@crate_ctxt cx,
str kind,
str name,
vec[ast.ty_param] ty_params,
&ast.ann ann,
ast.def_id id) {
auto llpairty = node_type(cx, ann);
auto llfty = get_pair_fn_ty(llpairty);
auto llfty;
auto llpairty;
alt (node_ann_type(cx, ann).struct) {
case (ty.ty_fn(?proto, ?inputs, ?output)) {
llfty = type_of_fn(cx, proto, inputs, output,
_vec.len[ast.ty_param](ty_params));
llpairty = T_fn_pair(cx.tn, llfty);
}
case (_) {
cx.sess.bug("decl_fn_and_pair(): fn item doesn't have fn type?!");
fail;
}
}
// Declare the function itself.
let str s = cx.names.next("_rust_" + kind) + sep() + name;
@ -5023,11 +5060,29 @@ fn register_fn_pair(@crate_ctxt cx, str ps, TypeRef llpairty, ValueRef llfn,
cx.fn_pairs.insert(id, gvar);
}
fn native_fn_wrapper_type(@crate_ctxt cx, &ast.ann ann) -> TypeRef {
// Returns the number of type parameters that the given native function has.
fn native_fn_ty_param_count(@crate_ctxt cx, &ast.def_id id) -> uint {
auto count;
auto native_item = cx.native_items.get(id);
alt (native_item.node) {
case (ast.native_item_ty(_,_)) {
cx.sess.bug("decl_native_fn_and_pair(): native fn isn't " +
"actually a fn?!");
fail;
}
case (ast.native_item_fn(_, _, ?tps, _, _)) {
count = _vec.len[ast.ty_param](tps);
}
}
ret count;
}
fn native_fn_wrapper_type(@crate_ctxt cx, uint ty_param_count, &ast.ann ann)
-> TypeRef {
auto x = node_ann_type(cx, ann);
alt (x.struct) {
case (ty.ty_native_fn(?abi, ?args, ?out)) {
ret type_of_fn(cx, ast.proto_fn, args, out);
ret type_of_fn(cx, ast.proto_fn, args, out, ty_param_count);
}
}
fail;
@ -5037,8 +5092,10 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
str name,
&ast.ann ann,
ast.def_id id) {
auto num_ty_param = native_fn_ty_param_count(cx, id);
// Declare the wrapper.
auto wrapper_type = native_fn_wrapper_type(cx, ann);
auto wrapper_type = native_fn_wrapper_type(cx, num_ty_param, ann);
let str s = cx.names.next("_rust_wrapper") + sep() + name;
let ValueRef wrapper_fn = decl_fastcall_fn(cx.llmod, s, wrapper_type);
@ -5063,7 +5120,6 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
alt (abi) {
case (ast.native_abi_rust) {
call_args += vec(fcx.lltaskptr);
auto num_ty_param = ty.count_ty_params(plain_ty(fn_type.struct));
for each (uint i in _uint.range(0u, num_ty_param)) {
auto llarg = llvm.LLVMGetParam(fcx.llfn, arg_n);
check (llarg as int != 0);
@ -5081,6 +5137,7 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
call_args += vec(llarg);
arg_n += 1u;
}
auto r = bcx.build.Call(function, call_args);
bcx.build.Store(r, fcx.llretptr);
bcx.build.RetVoid();
@ -5102,16 +5159,16 @@ fn collect_native_item(&@crate_ctxt cx, @ast.native_item i) -> @crate_ctxt {
fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
alt (i.node) {
case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
case (ast.item_fn(?name, ?f, ?tps, ?fid, ?ann)) {
cx.items.insert(fid, i);
if (! cx.obj_methods.contains_key(fid)) {
decl_fn_and_pair(cx, "fn", name, ann, fid);
decl_fn_and_pair(cx, "fn", name, tps, ann, fid);
}
}
case (ast.item_obj(?name, ?ob, _, ?oid, ?ann)) {
case (ast.item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
cx.items.insert(oid, i);
decl_fn_and_pair(cx, "obj_ctor", name, ann, oid);
decl_fn_and_pair(cx, "obj_ctor", name, tps, ann, oid);
for (@ast.method m in ob.methods) {
cx.obj_methods.insert(m.node.id, ());
}
@ -5151,11 +5208,11 @@ fn collect_tag_ctor(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
alt (i.node) {
case (ast.item_tag(_, ?variants, _, _)) {
case (ast.item_tag(_, ?variants, ?tps, _)) {
for (ast.variant variant in variants) {
if (_vec.len[ast.variant_arg](variant.args) != 0u) {
decl_fn_and_pair(cx, "tag", variant.name,
variant.ann, variant.id);
tps, variant.ann, variant.id);
}
}
}