Skip to content

Commit e624249

Browse files
committed
rustc: Have trans get the type parameters from the annotation instead of trying to deduce them itself. Un-XFAIL generic-fn-twice.rs.
1 parent 67a9532 commit e624249

File tree

2 files changed

+81
-25
lines changed

2 files changed

+81
-25
lines changed

src/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
452452
foreach-nested.rs \
453453
foreach-put-structured.rs \
454454
foreach-simple-outer-slot.rs \
455-
generic-fn-twice.rs \
456455
generic-iter-frame.rs \
457456
generic-tag-alt.rs \
458457
generic-tag-values.rs \

src/comp/middle/trans.rs

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,8 @@ fn type_of_fn_full(@crate_ctxt cx,
503503
ast.proto proto,
504504
option.t[TypeRef] obj_self,
505505
vec[ty.arg] inputs,
506-
@ty.t output) -> TypeRef {
506+
@ty.t output,
507+
uint ty_param_count) -> TypeRef {
507508
let vec[TypeRef] atys = vec();
508509

509510
// Arg 0: Output pointer.
@@ -529,10 +530,6 @@ fn type_of_fn_full(@crate_ctxt cx,
529530

530531
// Args >3: ty params, if not acquired via capture...
531532
if (obj_self == none[TypeRef]) {
532-
auto ty_param_count =
533-
ty.count_ty_params(plain_ty(ty.ty_fn(proto,
534-
inputs,
535-
output)));
536533
auto i = 0u;
537534
while (i < ty_param_count) {
538535
atys += T_ptr(T_tydesc(cx.tn));
@@ -547,7 +544,7 @@ fn type_of_fn_full(@crate_ctxt cx,
547544
atys += T_fn_pair(cx.tn,
548545
type_of_fn_full(cx, ast.proto_fn, none[TypeRef],
549546
vec(rec(mode=ast.val, ty=output)),
550-
plain_ty(ty.ty_nil)));
547+
plain_ty(ty.ty_nil), 0u));
551548
}
552549

553550
// ... then explicit args.
@@ -558,8 +555,11 @@ fn type_of_fn_full(@crate_ctxt cx,
558555

559556
fn type_of_fn(@crate_ctxt cx,
560557
ast.proto proto,
561-
vec[ty.arg] inputs, @ty.t output) -> TypeRef {
562-
ret type_of_fn_full(cx, proto, none[TypeRef], inputs, output);
558+
vec[ty.arg] inputs,
559+
@ty.t output,
560+
uint ty_param_count) -> TypeRef {
561+
ret type_of_fn_full(cx, proto, none[TypeRef], inputs, output,
562+
ty_param_count);
563563
}
564564

565565
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 {
634634
llty = T_struct(tys);
635635
}
636636
case (ty.ty_fn(?proto, ?args, ?out)) {
637-
llty = T_fn_pair(cx.tn, type_of_fn(cx, proto, args, out));
637+
llty = T_fn_pair(cx.tn, type_of_fn(cx, proto, args, out, 0u));
638638
}
639639
case (ty.ty_native_fn(?abi, ?args, ?out)) {
640640
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 {
648648
let TypeRef mty =
649649
type_of_fn_full(cx, m.proto,
650650
some[TypeRef](self_ty),
651-
m.inputs, m.output);
651+
m.inputs, m.output, 0u);
652652
mtys += T_ptr(mty);
653653
}
654654
let TypeRef vtbl = T_struct(mtys);
@@ -2820,7 +2820,7 @@ fn trans_for_each(@block_ctxt cx,
28202820
auto iter_body_llty = type_of_fn_full(cx.fcx.ccx, ast.proto_fn,
28212821
none[TypeRef],
28222822
vec(rec(mode=ast.val, ty=decl_ty)),
2823-
plain_ty(ty.ty_nil));
2823+
plain_ty(ty.ty_nil), 0u);
28242824

28252825
let ValueRef lliterbody = decl_fastcall_fn(cx.fcx.ccx.llmod,
28262826
s, iter_body_llty);
@@ -3447,6 +3447,16 @@ fn trans_bind_thunk(@crate_ctxt cx,
34473447
auto lltargetfn = bcx.build.GEP(lltarget.val,
34483448
vec(C_int(0),
34493449
C_int(abi.fn_field_code)));
3450+
3451+
// Cast the outgoing function to the appropriate type (see the comments in
3452+
// trans_bind below for why this is necessary).
3453+
auto lltargetty = type_of_fn(bcx.fcx.ccx,
3454+
ty.ty_fn_proto(outgoing_fty),
3455+
outgoing_args,
3456+
outgoing_ret_ty,
3457+
ty_param_count);
3458+
lltargetfn = bcx.build.PointerCast(lltargetfn, T_ptr(T_ptr(lltargetty)));
3459+
34503460
lltargetfn = bcx.build.Load(lltargetfn);
34513461

34523462
auto r = bcx.build.FastCall(lltargetfn, llargs);
@@ -3551,12 +3561,26 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
35513561
bcx = bindings_tydesc.bcx;
35523562
bcx.build.Store(bindings_tydesc.val, bound_tydesc);
35533563

3564+
// Determine the LLVM type for the outgoing function type. This
3565+
// may be different from the type returned by trans_malloc_boxed()
3566+
// since we have more information than that function does;
3567+
// specifically, we know how many type descriptors the outgoing
3568+
// function has, which type_of() doesn't, as only we know which
3569+
// item the function refers to.
3570+
auto llfnty = type_of_fn(bcx.fcx.ccx,
3571+
ty.ty_fn_proto(outgoing_fty),
3572+
ty.ty_fn_args(outgoing_fty),
3573+
ty.ty_fn_ret(outgoing_fty),
3574+
ty_param_count);
3575+
auto llclosurety = T_ptr(T_fn_pair(bcx.fcx.ccx.tn, llfnty));
3576+
35543577
// Store thunk-target.
35553578
auto bound_target =
35563579
bcx.build.GEP(closure,
35573580
vec(C_int(0),
35583581
C_int(abi.closure_elt_target)));
35593582
auto src = bcx.build.Load(f_res.res.val);
3583+
bound_target = bcx.build.PointerCast(bound_target, llclosurety);
35603584
bcx.build.Store(src, bound_target);
35613585

35623586
// Copy expr values into boxed bindings.
@@ -4691,7 +4715,8 @@ fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
46914715
case (ty.ty_fn(?proto, ?inputs, ?output)) {
46924716
llfnty = type_of_fn_full(cx, proto,
46934717
some[TypeRef](self_ty),
4694-
inputs, output);
4718+
inputs, output,
4719+
_vec.len[ast.ty_param](ty_params));
46954720
}
46964721
}
46974722

@@ -4990,11 +5015,23 @@ fn get_pair_fn_ty(TypeRef llpairty) -> TypeRef {
49905015
fn decl_fn_and_pair(@crate_ctxt cx,
49915016
str kind,
49925017
str name,
5018+
vec[ast.ty_param] ty_params,
49935019
&ast.ann ann,
49945020
ast.def_id id) {
49955021

4996-
auto llpairty = node_type(cx, ann);
4997-
auto llfty = get_pair_fn_ty(llpairty);
5022+
auto llfty;
5023+
auto llpairty;
5024+
alt (node_ann_type(cx, ann).struct) {
5025+
case (ty.ty_fn(?proto, ?inputs, ?output)) {
5026+
llfty = type_of_fn(cx, proto, inputs, output,
5027+
_vec.len[ast.ty_param](ty_params));
5028+
llpairty = T_fn_pair(cx.tn, llfty);
5029+
}
5030+
case (_) {
5031+
cx.sess.bug("decl_fn_and_pair(): fn item doesn't have fn type?!");
5032+
fail;
5033+
}
5034+
}
49985035

49995036
// Declare the function itself.
50005037
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,
50235060
cx.fn_pairs.insert(id, gvar);
50245061
}
50255062

5026-
fn native_fn_wrapper_type(@crate_ctxt cx, &ast.ann ann) -> TypeRef {
5063+
// Returns the number of type parameters that the given native function has.
5064+
fn native_fn_ty_param_count(@crate_ctxt cx, &ast.def_id id) -> uint {
5065+
auto count;
5066+
auto native_item = cx.native_items.get(id);
5067+
alt (native_item.node) {
5068+
case (ast.native_item_ty(_,_)) {
5069+
cx.sess.bug("decl_native_fn_and_pair(): native fn isn't " +
5070+
"actually a fn?!");
5071+
fail;
5072+
}
5073+
case (ast.native_item_fn(_, _, ?tps, _, _)) {
5074+
count = _vec.len[ast.ty_param](tps);
5075+
}
5076+
}
5077+
ret count;
5078+
}
5079+
5080+
fn native_fn_wrapper_type(@crate_ctxt cx, uint ty_param_count, &ast.ann ann)
5081+
-> TypeRef {
50275082
auto x = node_ann_type(cx, ann);
50285083
alt (x.struct) {
50295084
case (ty.ty_native_fn(?abi, ?args, ?out)) {
5030-
ret type_of_fn(cx, ast.proto_fn, args, out);
5085+
ret type_of_fn(cx, ast.proto_fn, args, out, ty_param_count);
50315086
}
50325087
}
50335088
fail;
@@ -5037,8 +5092,10 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
50375092
str name,
50385093
&ast.ann ann,
50395094
ast.def_id id) {
5095+
auto num_ty_param = native_fn_ty_param_count(cx, id);
5096+
50405097
// Declare the wrapper.
5041-
auto wrapper_type = native_fn_wrapper_type(cx, ann);
5098+
auto wrapper_type = native_fn_wrapper_type(cx, num_ty_param, ann);
50425099
let str s = cx.names.next("_rust_wrapper") + sep() + name;
50435100
let ValueRef wrapper_fn = decl_fastcall_fn(cx.llmod, s, wrapper_type);
50445101

@@ -5063,7 +5120,6 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
50635120
alt (abi) {
50645121
case (ast.native_abi_rust) {
50655122
call_args += vec(fcx.lltaskptr);
5066-
auto num_ty_param = ty.count_ty_params(plain_ty(fn_type.struct));
50675123
for each (uint i in _uint.range(0u, num_ty_param)) {
50685124
auto llarg = llvm.LLVMGetParam(fcx.llfn, arg_n);
50695125
check (llarg as int != 0);
@@ -5081,6 +5137,7 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
50815137
call_args += vec(llarg);
50825138
arg_n += 1u;
50835139
}
5140+
50845141
auto r = bcx.build.Call(function, call_args);
50855142
bcx.build.Store(r, fcx.llretptr);
50865143
bcx.build.RetVoid();
@@ -5102,16 +5159,16 @@ fn collect_native_item(&@crate_ctxt cx, @ast.native_item i) -> @crate_ctxt {
51025159
fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
51035160

51045161
alt (i.node) {
5105-
case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
5162+
case (ast.item_fn(?name, ?f, ?tps, ?fid, ?ann)) {
51065163
cx.items.insert(fid, i);
51075164
if (! cx.obj_methods.contains_key(fid)) {
5108-
decl_fn_and_pair(cx, "fn", name, ann, fid);
5165+
decl_fn_and_pair(cx, "fn", name, tps, ann, fid);
51095166
}
51105167
}
51115168

5112-
case (ast.item_obj(?name, ?ob, _, ?oid, ?ann)) {
5169+
case (ast.item_obj(?name, ?ob, ?tps, ?oid, ?ann)) {
51135170
cx.items.insert(oid, i);
5114-
decl_fn_and_pair(cx, "obj_ctor", name, ann, oid);
5171+
decl_fn_and_pair(cx, "obj_ctor", name, tps, ann, oid);
51155172
for (@ast.method m in ob.methods) {
51165173
cx.obj_methods.insert(m.node.id, ());
51175174
}
@@ -5151,11 +5208,11 @@ fn collect_tag_ctor(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
51515208

51525209
alt (i.node) {
51535210

5154-
case (ast.item_tag(_, ?variants, _, _)) {
5211+
case (ast.item_tag(_, ?variants, ?tps, _)) {
51555212
for (ast.variant variant in variants) {
51565213
if (_vec.len[ast.variant_arg](variant.args) != 0u) {
51575214
decl_fn_and_pair(cx, "tag", variant.name,
5158-
variant.ann, variant.id);
5215+
tps, variant.ann, variant.id);
51595216
}
51605217
}
51615218
}

0 commit comments

Comments
 (0)