Skip to content

Commit da82874

Browse files
committed
correct use of GEP_tup_like in closure constr
also, streamline type_is_tup_like() to the cases which actually work
1 parent 2286d8c commit da82874

File tree

5 files changed

+66
-28
lines changed

5 files changed

+66
-28
lines changed

src/comp/middle/trans.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,9 @@ fn GEP_tup_like(bcx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
691691
: type_is_tup_like(bcx, t) -> result {
692692
// It might be a static-known type. Handle this.
693693
if !ty::type_has_dynamic_size(bcx_tcx(bcx), t) {
694+
#debug["GEP_tup_like t=%? ixs=%? -> static",
695+
ty_to_str(bcx_tcx(bcx), t), ixs];
696+
694697
ret rslt(bcx, GEPi(bcx, base, ixs));
695698
}
696699
// It is a dynamic-containing type that, if we convert directly to an LLVM
@@ -758,6 +761,10 @@ fn GEP_tup_like(bcx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
758761
for typ: ty::t in s.prefix { args += [typ]; }
759762
let prefix_ty = ty::mk_tup(bcx_tcx(bcx), args);
760763

764+
#debug["GEP_tup_like t=%? ixs=%? prefix_ty=%?",
765+
ty_to_str(bcx_tcx(bcx), t), ixs,
766+
ty_to_str(bcx_tcx(bcx), prefix_ty)];
767+
761768
let sz = size_of_(bcx, prefix_ty, align_next(s.target));
762769
ret rslt(sz.bcx, bump_ptr(sz.bcx, s.target, base, sz.val));
763770
}

src/comp/middle/trans_closure.rs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ fn allocate_cbox(bcx: @block_ctxt,
261261

262262
type closure_result = {
263263
llbox: ValueRef, // llvalue of ptr to closure
264-
cboxptr_ty: ty::t, // type of ptr to closure
264+
cbox_ty: ty::t, // type of the closure data
265265
bcx: @block_ctxt // final bcx
266266
};
267267

@@ -332,12 +332,12 @@ fn store_environment(
332332
// whatever.
333333
let cboxptr_ty = ty::mk_ptr(tcx, {ty:cbox_ty, mut:ast::imm});
334334
let llbox = cast_if_we_can(bcx, llbox, cboxptr_ty);
335-
check type_is_tup_like(bcx, cboxptr_ty);
335+
check type_is_tup_like(bcx, cbox_ty);
336336

337337
// If necessary, copy tydescs describing type parameters into the
338338
// appropriate slot in the closure.
339339
let {bcx:bcx, val:ty_params_slot} =
340-
GEP_tup_like_1(bcx, cboxptr_ty, llbox, [0, abi::cbox_elt_ty_params]);
340+
GEP_tup_like(bcx, cbox_ty, llbox, [0, abi::cbox_elt_ty_params]);
341341
let off = 0;
342342
for tp in lltyparams {
343343
let cloned_td = maybe_clone_tydesc(bcx, ck, tp.desc);
@@ -354,15 +354,16 @@ fn store_environment(
354354

355355
// Copy expr values into boxed bindings.
356356
// Silly check
357-
let {bcx: bcx, val:bindings_slot} =
358-
GEP_tup_like_1(bcx, cboxptr_ty, llbox, [0, abi::cbox_elt_bindings]);
359357
vec::iteri(bound_values) { |i, bv|
360358
if (!ccx.sess.opts.no_asm_comments) {
361359
add_comment(bcx, #fmt("Copy %s into closure",
362360
ev_to_str(ccx, bv)));
363361
}
364362

365-
let bound_data = GEPi(bcx, bindings_slot, [0, i as int]);
363+
let bound_data = GEP_tup_like_1(bcx, cbox_ty, llbox,
364+
[0, abi::cbox_elt_bindings, i as int]);
365+
bcx = bound_data.bcx;
366+
let bound_data = bound_data.val;
366367
alt bv {
367368
env_expr(e) {
368369
bcx = trans::trans_expr_save_in(bcx, e, bound_data);
@@ -397,7 +398,7 @@ fn store_environment(
397398
}
398399
for cleanup in temp_cleanups { revoke_clean(bcx, cleanup); }
399400

400-
ret {llbox: llbox, cboxptr_ty: cboxptr_ty, bcx: bcx};
401+
ret {llbox: llbox, cbox_ty: cbox_ty, bcx: bcx};
401402
}
402403

403404
// Given a context and a list of upvars, build a closure. This just
@@ -441,13 +442,15 @@ fn build_closure(bcx0: @block_ctxt,
441442
// with the upvars and type descriptors.
442443
fn load_environment(enclosing_cx: @block_ctxt,
443444
fcx: @fn_ctxt,
444-
cboxptr_ty: ty::t,
445+
cbox_ty: ty::t,
445446
cap_vars: [capture::capture_var],
446447
ck: ty::closure_kind) {
447448
let bcx = new_raw_block_ctxt(fcx, fcx.llloadenv);
448449
let ccx = bcx_ccx(bcx);
450+
let tcx = bcx_tcx(bcx);
449451

450452
let sp = bcx.sp;
453+
let cboxptr_ty = ty::mk_ptr(tcx, {ty:cbox_ty, mut:ast::imm});
451454
check (type_has_static_size(ccx, cboxptr_ty));
452455
let llty = type_of(ccx, sp, cboxptr_ty);
453456
let llclosure = PointerCast(bcx, fcx.llenv, llty);
@@ -479,9 +482,9 @@ fn load_environment(enclosing_cx: @block_ctxt,
479482
alt cap_var.mode {
480483
capture::cap_drop. { /* ignore */ }
481484
_ {
482-
check type_is_tup_like(bcx, cboxptr_ty);
485+
check type_is_tup_like(bcx, cbox_ty);
483486
let upvarptr = GEP_tup_like(
484-
bcx, cboxptr_ty, llclosure, path + [i as int]);
487+
bcx, cbox_ty, llclosure, path + [i as int]);
485488
bcx = upvarptr.bcx;
486489
let llupvarptr = upvarptr.val;
487490
alt ck {
@@ -516,9 +519,9 @@ fn trans_expr_fn(bcx: @block_ctxt,
516519
let trans_closure_env = fn@(ck: ty::closure_kind) -> ValueRef {
517520
let cap_vars = capture::compute_capture_vars(
518521
ccx.tcx, id, proto, cap_clause);
519-
let {llbox, cboxptr_ty, bcx} = build_closure(bcx, cap_vars, ck);
522+
let {llbox, cbox_ty, bcx} = build_closure(bcx, cap_vars, ck);
520523
trans_closure(sub_cx, sp, decl, body, llfn, no_self, [], id, {|fcx|
521-
load_environment(bcx, fcx, cboxptr_ty, cap_vars, ck);
524+
load_environment(bcx, fcx, cbox_ty, cap_vars, ck);
522525
});
523526
llbox
524527
};
@@ -616,15 +619,15 @@ fn trans_bind_1(cx: @block_ctxt, outgoing_fty: ty::t,
616619
};
617620

618621
// Actually construct the closure
619-
let {llbox, cboxptr_ty, bcx} = store_environment(
622+
let {llbox, cbox_ty, bcx} = store_environment(
620623
bcx, vec::map(lltydescs, {|d| {desc: d, dicts: none}}),
621624
env_vals + vec::map(bound, {|x| env_expr(x)}),
622625
ty::ck_box);
623626

624627
// Make thunk
625628
let llthunk =
626629
trans_bind_thunk(cx.fcx.lcx, cx.sp, pair_ty, outgoing_fty_real, args,
627-
cboxptr_ty, *param_bounds, target_res);
630+
cbox_ty, *param_bounds, target_res);
628631

629632
// Fill the function pair
630633
fill_fn_pair(bcx, get_dest_addr(dest), llthunk.val, llbox);
@@ -782,7 +785,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
782785
incoming_fty: ty::t,
783786
outgoing_fty: ty::t,
784787
args: [option::t<@ast::expr>],
785-
cboxptr_ty: ty::t,
788+
cbox_ty: ty::t,
786789
param_bounds: [ty::param_bounds],
787790
target_fn: option::t<ValueRef>)
788791
-> {val: ValueRef, ty: TypeRef} {
@@ -794,6 +797,7 @@ fn trans_bind_thunk(cx: @local_ctxt,
794797
*/
795798
// but since we don't, we have to do the checks at the beginning.
796799
let ccx = cx.ccx;
800+
let tcx = ccx_tcx(ccx);
797801
check type_has_static_size(ccx, incoming_fty);
798802

799803
// Here we're not necessarily constructing a thunk in the sense of
@@ -838,7 +842,8 @@ fn trans_bind_thunk(cx: @local_ctxt,
838842
// to the original function. So, let's create one of those:
839843

840844
// The llenv pointer needs to be the correct size. That size is
841-
// 'cboxptr_ty', which was determined by trans_bind.
845+
// 'cbox_ty', which was determined by trans_bind.
846+
let cboxptr_ty = ty::mk_ptr(tcx, {ty:cbox_ty, mut:ast::imm});
842847
check type_has_static_size(ccx, cboxptr_ty);
843848
let llclosure_ptr_ty = type_of(ccx, sp, cboxptr_ty);
844849
let llclosure = PointerCast(l_bcx, fcx.llenv, llclosure_ptr_ty);
@@ -854,9 +859,9 @@ fn trans_bind_thunk(cx: @local_ctxt,
854859
}
855860
none. {
856861
// Silly check
857-
check type_is_tup_like(bcx, cboxptr_ty);
862+
check type_is_tup_like(bcx, cbox_ty);
858863
let {bcx: cx, val: pair} =
859-
GEP_tup_like(bcx, cboxptr_ty, llclosure,
864+
GEP_tup_like(bcx, cbox_ty, llclosure,
860865
[0, abi::cbox_elt_bindings, 0]);
861866
let lltargetenv =
862867
Load(cx, GEPi(cx, pair, [0, abi::fn_field_box]));
@@ -891,9 +896,9 @@ fn trans_bind_thunk(cx: @local_ctxt,
891896
let llargs: [ValueRef] = [llretptr, lltargetenv];
892897

893898
// Copy in the type parameters.
894-
check type_is_tup_like(l_bcx, cboxptr_ty);
899+
check type_is_tup_like(l_bcx, cbox_ty);
895900
let {bcx: l_bcx, val: param_record} =
896-
GEP_tup_like(l_bcx, cboxptr_ty, llclosure,
901+
GEP_tup_like(l_bcx, cbox_ty, llclosure,
897902
[0, abi::cbox_elt_ty_params]);
898903
let off = 0;
899904
for param in param_bounds {
@@ -932,9 +937,9 @@ fn trans_bind_thunk(cx: @local_ctxt,
932937
// closure.
933938
some(e) {
934939
// Silly check
935-
check type_is_tup_like(bcx, cboxptr_ty);
940+
check type_is_tup_like(bcx, cbox_ty);
936941
let bound_arg =
937-
GEP_tup_like(bcx, cboxptr_ty, llclosure,
942+
GEP_tup_like(bcx, cbox_ty, llclosure,
938943
[0, abi::cbox_elt_bindings, b]);
939944
bcx = bound_arg.bcx;
940945
let val = bound_arg.val;

src/comp/middle/ty.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -859,8 +859,7 @@ fn sequence_element_type(cx: ctxt, ty: t) -> t {
859859
pure fn type_is_tup_like(cx: ctxt, ty: t) -> bool {
860860
let sty = struct(cx, ty);
861861
alt sty {
862-
ty_ptr(_) | ty_uniq(_) |
863-
ty_box(_) | ty_rec(_) | ty_tup(_) | ty_tag(_,_) { true }
862+
ty_rec(_) | ty_tup(_) { true }
864863
_ { false }
865864
}
866865
}
@@ -871,12 +870,9 @@ fn get_element_type(cx: ctxt, ty: t, i: uint) -> t {
871870
ty_tup(ts) { ret ts[i]; }
872871
_ {
873872
cx.sess.bug("get_element_type called on type " + ty_to_str(cx, ty) +
874-
" - expected a \
875-
tuple or record");
873+
" - expected a tuple or record");
876874
}
877875
}
878-
// NB: This is not exhaustive -- struct(cx, ty) could be a box or a
879-
// tag.
880876
}
881877

882878
pure fn type_is_box(cx: ctxt, ty: t) -> bool {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
type pair<A,B> = {
2+
a: A, b: B
3+
};
4+
5+
fn f<A:copy>(a: A, b: u16) -> fn@() -> (A, u16) {
6+
fn@() -> (A, u16) { (a, b) }
7+
}
8+
9+
fn main() {
10+
let (a, b) = f(22_u64, 44u16)();
11+
#debug["a=%? b=%?", a, b];
12+
assert a == 22u64;
13+
assert b == 44u16;
14+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type pair<A,B> = {
2+
a: A, b: B
3+
};
4+
5+
fn f<A:send,B:send>(a: A, b: B) -> fn~() -> (A, B) {
6+
fn~() -> (A, B) { (a, b) }
7+
}
8+
9+
fn main() {
10+
let x = 22_u8;
11+
let y = 44_u64;
12+
let (a, b) = f(~x, ~y)();
13+
#debug["a=%? b=%?", *a, *b];
14+
assert *a == x;
15+
assert *b == y;
16+
}

0 commit comments

Comments
 (0)