Skip to content

Commit b41fd61

Browse files
committed
Make for-each bodies close over their parent's iterbody
Closes issue #639
1 parent 7ed556c commit b41fd61

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

src/comp/middle/trans.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -4488,15 +4488,20 @@ fn collect_upvars(&@block_ctxt cx, &ast::block bloc,
44884488
// contains pointers to all of the upvars and all of the tydescs in
44894489
// scope. Return the ValueRef and TypeRef corresponding to the closure.
44904490
fn build_environment(&@block_ctxt cx, &ast::node_id[] upvars) ->
4491-
tup(ValueRef, TypeRef)
4492-
{
4491+
tup(ValueRef, TypeRef) {
44934492
auto upvar_count = std::ivec::len(upvars);
4493+
auto has_iterbody = !option::is_none(cx.fcx.lliterbody);
4494+
if (has_iterbody) { upvar_count += 1u; }
44944495
auto llbindingsptr;
44954496

44964497
if (upvar_count > 0u) {
44974498
// Gather up the upvars.
44984499
let ValueRef[] llbindings = ~[];
44994500
let TypeRef[] llbindingtys = ~[];
4501+
if (has_iterbody) {
4502+
llbindings += ~[option::get(cx.fcx.lliterbody)];
4503+
llbindingtys += ~[val_ty(llbindings.(0))];
4504+
}
45004505
for (ast::node_id nid in upvars) {
45014506
auto llbinding;
45024507
alt (cx.fcx.lllocals.find(nid)) {
@@ -4566,9 +4571,7 @@ fn build_environment(&@block_ctxt cx, &ast::node_id[] upvars) ->
45664571
// and a list of upvars, generate code to load and populate the environment
45674572
// with the upvars and type descriptors.
45684573
fn load_environment(&@block_ctxt cx, &@fn_ctxt fcx,
4569-
TypeRef llenvptrty, &ast::node_id[] upvars)
4570-
{
4571-
auto upvar_count = std::ivec::len(upvars);
4574+
TypeRef llenvptrty, &ast::node_id[] upvars) {
45724575
auto copy_args_bcx = new_raw_block_ctxt(fcx, fcx.llcopyargs);
45734576

45744577
// Populate the upvars from the environment.
@@ -4581,7 +4584,17 @@ fn load_environment(&@block_ctxt cx, &@fn_ctxt fcx,
45814584
auto llremotebindingsptr =
45824585
copy_args_bcx.build.Load(llremotebindingsptrptr);
45834586
auto i = 0u;
4584-
while (i < upvar_count) {
4587+
auto end = std::ivec::len(upvars);
4588+
if (!option::is_none(cx.fcx.lliterbody)) {
4589+
end += 1u;
4590+
i += 1u;
4591+
auto lliterbodyptr =
4592+
copy_args_bcx.build.GEP(llremotebindingsptr,
4593+
~[C_int(0), C_int(0)]);
4594+
auto lliterbody = copy_args_bcx.build.Load(lliterbodyptr);
4595+
fcx.lliterbody = some(lliterbody);
4596+
}
4597+
while (i < end) {
45854598
auto upvar_id = upvars.(i);
45864599
auto llupvarptrptr =
45874600
copy_args_bcx.build.GEP(llremotebindingsptr,

0 commit comments

Comments
 (0)