Skip to content

Commit 5ce6008

Browse files
committed
---
yaml --- r: 1599 b: refs/heads/master c: 7454b53 h: refs/heads/master i: 1597: fef63ea 1595: bb314eb 1591: 67418ab 1583: 7e109d3 1567: 7a0063b 1535: aa3059a v: v3
1 parent 97772c0 commit 5ce6008

File tree

3 files changed

+75
-6
lines changed

3 files changed

+75
-6
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 60f86354ad95802da4c861fb8df54abf95f1917b
2+
refs/heads/master: 7454b534112e8cb7b0192d28c8b8685db31ed283

trunk/src/comp/front/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ tag def {
3232
def_const(def_id);
3333
def_arg(def_id);
3434
def_local(def_id);
35+
def_upvar(def_id);
3536
def_variant(def_id /* tag */, def_id /* variant */);
3637
def_ty(def_id);
3738
def_ty_arg(def_id);

trunk/src/comp/middle/trans.rs

+73-5
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ state type fn_ctxt = rec(ValueRef llfn,
9898
hashmap[ast.def_id, ValueRef] llargs,
9999
hashmap[ast.def_id, ValueRef] llobjfields,
100100
hashmap[ast.def_id, ValueRef] lllocals,
101+
hashmap[ast.def_id, ValueRef] llupvars,
101102
hashmap[ast.def_id, ValueRef] lltydescs,
102103
@crate_ctxt ccx);
103104

@@ -2897,6 +2898,62 @@ fn trans_for(@block_ctxt cx,
28972898
bind inner(_, local, _, _, body));
28982899
}
28992900

2901+
2902+
// Iterator translation
2903+
2904+
// Searches through a block for all references to locals or upvars in this
2905+
// frame and returns the list of definition IDs thus found.
2906+
fn collect_upvars(@block_ctxt cx, &ast.block bloc, &ast.def_id initial_decl)
2907+
-> vec[ast.def_id] {
2908+
type env = @rec(
2909+
mutable vec[ast.def_id] refs,
2910+
hashmap[ast.def_id,()] decls
2911+
);
2912+
2913+
fn fold_expr_path(&env e, &common.span sp, &ast.path p,
2914+
&option.t[ast.def] d, ast.ann a) -> @ast.expr {
2915+
alt (option.get[ast.def](d)) {
2916+
case (ast.def_arg(?did)) { e.refs += vec(did); }
2917+
case (ast.def_local(?did)) { e.refs += vec(did); }
2918+
case (ast.def_upvar(?did)) { e.refs += vec(did); }
2919+
case (_) { /* ignore */ }
2920+
}
2921+
2922+
ret @fold.respan[ast.expr_](sp, ast.expr_path(p, d, a));
2923+
}
2924+
2925+
fn fold_decl_local(&env e, &common.span sp, @ast.local local)
2926+
-> @ast.decl {
2927+
e.decls.insert(local.id, ());
2928+
ret @fold.respan[ast.decl_](sp, ast.decl_local(local));
2929+
}
2930+
2931+
auto fep = fold_expr_path;
2932+
auto fdl = fold_decl_local;
2933+
auto fld = @rec(
2934+
fold_expr_path=fep,
2935+
fold_decl_local=fdl
2936+
with *fold.new_identity_fold[env]()
2937+
);
2938+
2939+
let vec[ast.def_id] refs = vec();
2940+
let hashmap[ast.def_id,()] decls = new_def_hash[()]();
2941+
decls.insert(initial_decl, ());
2942+
let env e = @rec(mutable refs=refs, decls=decls);
2943+
2944+
fold.fold_block[env](e, fld, bloc);
2945+
2946+
// Calculate (refs - decls). This is the set of captured upvars.
2947+
let vec[ast.def_id] result = vec();
2948+
for (ast.def_id ref_id in e.refs) {
2949+
if (!decls.contains_key(ref_id)) {
2950+
result += vec(ref_id);
2951+
}
2952+
}
2953+
2954+
ret result;
2955+
}
2956+
29002957
fn trans_for_each(@block_ctxt cx,
29012958
@ast.decl decl,
29022959
@ast.expr seq,
@@ -2928,19 +2985,26 @@ fn trans_for_each(@block_ctxt cx,
29282985
// escape. This could be determined upstream, and probably ought
29292986
// to be so, eventualy. For first cut, skip this. Null env.
29302987

2931-
auto env_ty = T_opaque_closure_ptr(cx.fcx.ccx.tn);
2932-
2933-
2934-
// Step 2: Declare foreach body function.
2935-
29362988
// FIXME: possibly support alias-mode here?
29372989
auto decl_ty = plain_ty(ty.ty_nil);
2990+
auto decl_id;
29382991
alt (decl.node) {
29392992
case (ast.decl_local(?local)) {
29402993
decl_ty = node_ann_type(cx.fcx.ccx, local.ann);
2994+
decl_id = local.id;
29412995
}
29422996
}
29432997

2998+
auto upvars = collect_upvars(cx, body, decl_id);
2999+
if (_vec.len[ast.def_id](upvars) > 0u) {
3000+
cx.fcx.ccx.sess.unimpl("upvars in for each");
3001+
fail;
3002+
}
3003+
3004+
auto env_ty = T_opaque_closure_ptr(cx.fcx.ccx.tn);
3005+
3006+
// Step 2: Declare foreach body function.
3007+
29443008
let str s =
29453009
cx.fcx.ccx.names.next("_rust_foreach")
29463010
+ sep() + cx.fcx.ccx.path;
@@ -4624,6 +4688,7 @@ fn new_fn_ctxt(@crate_ctxt cx,
46244688
let hashmap[ast.def_id, ValueRef] llargs = new_def_hash[ValueRef]();
46254689
let hashmap[ast.def_id, ValueRef] llobjfields = new_def_hash[ValueRef]();
46264690
let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
4691+
let hashmap[ast.def_id, ValueRef] llupvars = new_def_hash[ValueRef]();
46274692
let hashmap[ast.def_id, ValueRef] lltydescs = new_def_hash[ValueRef]();
46284693

46294694
ret @rec(llfn=llfndecl,
@@ -4635,6 +4700,7 @@ fn new_fn_ctxt(@crate_ctxt cx,
46354700
llargs=llargs,
46364701
llobjfields=llobjfields,
46374702
lllocals=lllocals,
4703+
llupvars=llupvars,
46384704
lltydescs=lltydescs,
46394705
ccx=cx);
46404706
}
@@ -5486,6 +5552,7 @@ fn trans_exit_task_glue(@crate_ctxt cx) {
54865552
llargs=new_def_hash[ValueRef](),
54875553
llobjfields=new_def_hash[ValueRef](),
54885554
lllocals=new_def_hash[ValueRef](),
5555+
llupvars=new_def_hash[ValueRef](),
54895556
lltydescs=new_def_hash[ValueRef](),
54905557
ccx=cx);
54915558

@@ -5819,6 +5886,7 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
58195886
llargs=new_def_hash[ValueRef](),
58205887
llobjfields=new_def_hash[ValueRef](),
58215888
lllocals=new_def_hash[ValueRef](),
5889+
llupvars=new_def_hash[ValueRef](),
58225890
lltydescs=new_def_hash[ValueRef](),
58235891
ccx=cx);
58245892

0 commit comments

Comments
 (0)