Skip to content

Commit c7f1cdb

Browse files
committed
---
yaml --- r: 6901 b: refs/heads/master c: 6a90140 h: refs/heads/master i: 6899: 57c2085 v: v3
1 parent e7ce565 commit c7f1cdb

22 files changed

+393
-243
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 1e4de333740690357a8f58883c5c69bf58be1424
2+
refs/heads/master: 6a901409410fc2fbc6722eb7b352008135252cec

trunk/src/comp/middle/alias.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate) -> (copy_map, ref_map) {
6161
copy_map: std::map::new_int_hash(),
6262
ref_map: std::map::new_int_hash(),
6363
mutable silent: false};
64-
let v = @{visit_fn: bind visit_fn(cx, _, _, _, _, _, _, _),
64+
let v = @{visit_fn_body: bind visit_fn_body(cx, _, _, _, _, _, _, _),
6565
visit_expr: bind visit_expr(cx, _, _, _),
6666
visit_block: bind visit_block(cx, _, _, _)
6767
with *visit::default_visitor::<scope>()};
@@ -71,10 +71,12 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate) -> (copy_map, ref_map) {
7171
ret (cx.copy_map, cx.ref_map);
7272
}
7373

74-
fn visit_fn(cx: @ctx, f: ast::_fn, _tp: [ast::ty_param], sp: span,
75-
_name: fn_ident, id: ast::node_id, sc: scope, v: vt<scope>) {
76-
visit::visit_fn_decl(f.decl, sc, v);
77-
let args = ty::ty_fn_args(cx.tcx, ty::node_id_to_type(cx.tcx, id));
74+
fn visit_fn_body(cx: @ctx, decl: ast::fn_decl, body: ast::blk,
75+
sp: span, _name: ast::fn_ident,
76+
id: ast::node_id, sc: scope, v: vt<scope>) {
77+
visit::visit_fn_decl(decl, sc, v);
78+
let fty = ty::node_id_to_type(cx.tcx, id);
79+
let args = ty::ty_fn_args(cx.tcx, fty);
7880
for arg in args {
7981
if arg.mode == ast::by_val &&
8082
ty::type_has_dynamic_size(cx.tcx, arg.ty) {
@@ -84,11 +86,12 @@ fn visit_fn(cx: @ctx, f: ast::_fn, _tp: [ast::ty_param], sp: span,
8486

8587
// Blocks need to obey any restrictions from the enclosing scope, and may
8688
// be called multiple times.
87-
if f.proto == ast::proto_block {
88-
check_loop(*cx, sc) {|| v.visit_block(f.body, sc, v);}
89+
let proto = ty::ty_fn_proto(cx.tcx, fty);
90+
if proto == ast::proto_block {
91+
check_loop(*cx, sc) {|| v.visit_block(body, sc, v);}
8992
} else {
9093
let sc = {bs: [], invalid: @mutable list::nil};
91-
v.visit_block(f.body, sc, v);
94+
v.visit_block(body, sc, v);
9295
}
9396
}
9497

trunk/src/comp/middle/ast_map.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ fn map_crate(c: crate) -> map {
3232
(@{visit_item: bind map_item(cx, _),
3333
visit_native_item: bind map_native_item(cx, _),
3434
visit_expr: bind map_expr(cx, _),
35-
visit_fn: bind map_fn(cx, _, _, _, _, _),
35+
visit_fn_body: bind map_fn_body(cx, _, _, _, _, _),
3636
visit_local: bind map_local(cx, _),
3737
visit_arm: bind map_arm(cx, _)
3838
with *visit::default_simple_visitor()});
3939
visit::visit_crate(c, (), v_map);
4040
ret cx.map;
4141
}
4242

43-
fn map_fn(cx: ctx, f: _fn, _tp: [ty_param], _sp: codemap::span,
44-
_name: fn_ident, _id: node_id) {
45-
for a in f.decl.inputs {
43+
fn map_fn_body(cx: ctx, decl: fn_decl, _body: blk,
44+
_sp: codemap::span, _n: fn_ident, _id: node_id) {
45+
for a in decl.inputs {
4646
cx.map.insert(a.id, node_arg(a, cx.local_id));
4747
cx.local_id += 1u;
4848
}

trunk/src/comp/middle/debuginfo.rs

+3
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,9 @@ fn create_function(fcx: @fn_ctxt) -> @metadata<subprogram_md> {
740740
ast::expr_fn(f, _) {
741741
(dbg_cx.names.next("fn"), f.decl.output, expr.id)
742742
}
743+
ast::expr_fn_block(decl, _) {
744+
(dbg_cx.names.next("fn"), decl.output, expr.id)
745+
}
743746
}
744747
}
745748
};

trunk/src/comp/middle/freevars.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ type freevar_map = hashmap<ast::node_id, freevar_info>;
2828
// Since we want to be able to collect upvars in some arbitrary piece
2929
// of the AST, we take a walker function that we invoke with a visitor
3030
// in order to start the search.
31-
fn collect_freevars(def_map: resolve::def_map, walker: fn@(visit::vt<int>)) ->
32-
freevar_info {
31+
fn collect_freevars(def_map: resolve::def_map, blk: ast::blk)
32+
-> freevar_info {
3333
let seen = new_int_hash();
3434
let refs = @mutable [];
3535

@@ -43,6 +43,9 @@ fn collect_freevars(def_map: resolve::def_map, walker: fn@(visit::vt<int>)) ->
4343
visit::visit_expr(expr, depth + 1, v);
4444
}
4545
}
46+
ast::expr_fn_block(_, _) {
47+
visit::visit_expr(expr, depth + 1, v);
48+
}
4649
ast::expr_path(path) {
4750
let def = def_map.get(expr.id), i = 0;
4851
while i < depth {
@@ -64,8 +67,9 @@ fn collect_freevars(def_map: resolve::def_map, walker: fn@(visit::vt<int>)) ->
6467
}
6568
};
6669

67-
walker(visit::mk_vt(@{visit_item: ignore_item, visit_expr: walk_expr
68-
with *visit::default_visitor()}));
70+
let v = visit::mk_vt(@{visit_item: ignore_item, visit_expr: walk_expr
71+
with *visit::default_visitor()});
72+
v.visit_block(blk, 1, v);
6973
ret @*refs;
7074
}
7175

@@ -78,20 +82,16 @@ fn annotate_freevars(def_map: resolve::def_map, crate: @ast::crate) ->
7882
freevar_map {
7983
let freevars = new_int_hash();
8084

81-
let walk_fn =
82-
lambda (f: ast::_fn, tps: [ast::ty_param], sp: span, i: ast::fn_ident,
83-
nid: ast::node_id) {
84-
let start_walk =
85-
lambda (v: visit::vt<int>) {
86-
v.visit_fn(f, tps, sp, i, nid, 1, v);
87-
};
88-
let vars = collect_freevars(def_map, start_walk);
89-
freevars.insert(nid, vars);
90-
};
85+
let walk_fn_body = lambda (_decl: ast::fn_decl, blk: ast::blk,
86+
_sp: span, _nm: ast::fn_ident,
87+
nid: ast::node_id) {
88+
let vars = collect_freevars(def_map, blk);
89+
freevars.insert(nid, vars);
90+
};
9191

9292
let visitor =
93-
visit::mk_simple_visitor(@{visit_fn: walk_fn
94-
with *visit::default_simple_visitor()});
93+
visit::mk_simple_visitor(@{visit_fn_body: walk_fn_body
94+
with *visit::default_simple_visitor()});
9595
visit::visit_crate(*crate, (), visitor);
9696

9797
ret freevars;

trunk/src/comp/middle/last_use.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import syntax::{visit, ast_util};
22
import syntax::ast::*;
3+
import syntax::codemap::span;
34
import std::list::{list, nil, cons, tail};
45
import core::{vec, option};
56
import std::list;
@@ -42,7 +43,7 @@ type ctx = {last_uses: std::map::hashmap<node_id, bool>,
4243
fn find_last_uses(c: @crate, def_map: resolve::def_map,
4344
ref_map: alias::ref_map, tcx: ty::ctxt) -> last_uses {
4445
let v = visit::mk_vt(@{visit_expr: visit_expr,
45-
visit_fn: visit_fn
46+
visit_fn_body: visit_fn_body
4647
with *visit::default_visitor()});
4748
let cx = {last_uses: std::map::new_int_hash(),
4849
def_map: def_map,
@@ -136,6 +137,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
136137
alt arg.node {
137138
//NDM--register captured as uses
138139
expr_fn(_, captured) { fns += [arg]; }
140+
expr_fn_block(_, _) { fns += [arg]; }
139141
_ {
140142
alt arg_ts[i].mode {
141143
by_mut_ref. { clear_if_path(cx, arg, v, false); }
@@ -151,16 +153,19 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
151153
}
152154
}
153155

154-
fn visit_fn(f: _fn, tps: [ty_param], sp: syntax::codemap::span,
155-
ident: fn_ident, id: node_id, cx: ctx, v: visit::vt<ctx>) {
156-
if f.proto == proto_block {
156+
fn visit_fn_body(decl: fn_decl, body: blk,
157+
sp: span, nm: fn_ident, id: node_id,
158+
cx: ctx, v: visit::vt<ctx>) {
159+
let fty = ty::node_id_to_type(cx.tcx, id);
160+
let proto = ty::ty_fn_proto(cx.tcx, fty);
161+
if proto == proto_block {
157162
visit_block(func, cx, {||
158-
visit::visit_fn(f, tps, sp, ident, id, cx, v);
163+
visit::visit_fn_body(decl, body, sp, nm, id, cx, v);
159164
});
160165
} else {
161166
let old = nil;
162167
cx.blocks <-> old;
163-
visit::visit_fn(f, tps, sp, ident, id, cx, v);
168+
visit::visit_fn_body(decl, body, sp, nm, id, cx, v);
164169
cx.blocks <-> old;
165170
leave_fn(cx);
166171
}

trunk/src/comp/middle/mut.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ fn check_lval(cx: @ctx, dest: @expr, msg: msg) {
171171
alt dest.node {
172172
expr_path(p) {
173173
let def = cx.tcx.def_map.get(dest.id);
174-
alt is_immutable_def(def) {
174+
alt is_immutable_def(cx, def) {
175175
some(name) { mk_err(cx, dest.span, msg, name); }
176176
_ { }
177177
}
@@ -258,7 +258,7 @@ fn check_bind(cx: @ctx, f: @expr, args: [option::t<@expr>]) {
258258
}
259259
}
260260

261-
fn is_immutable_def(def: def) -> option::t<str> {
261+
fn is_immutable_def(cx: @ctx, def: def) -> option::t<str> {
262262
alt def {
263263
def_fn(_, _) | def_mod(_) | def_native_mod(_) | def_const(_) |
264264
def_use(_) {
@@ -268,8 +268,13 @@ fn is_immutable_def(def: def) -> option::t<str> {
268268
def_arg(_, mode_infer.) { some("argument") }
269269
def_obj_field(_, imm.) { some("immutable object field") }
270270
def_self(_) { some("self argument") }
271-
def_upvar(_, inner, mut) {
272-
if !mut { some("upvar") } else { is_immutable_def(*inner) }
271+
def_upvar(_, inner, node_id) {
272+
let ty = ty::node_id_to_monotype(cx.tcx, node_id);
273+
let proto = ty::ty_fn_proto(cx.tcx, ty);
274+
ret alt proto {
275+
proto_block. { is_immutable_def(cx, *inner) }
276+
_ { some("upvar") }
277+
};
273278
}
274279
def_binding(_) { some("binding") }
275280
def_local(_, let_ref.) { some("by-reference binding") }

trunk/src/comp/middle/resolve.rs

+41-25
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export _impl, iscopes, method_info;
3131
tag scope {
3232
scope_crate;
3333
scope_item(@ast::item);
34-
scope_fn(ast::fn_decl, ast::proto, [ast::ty_param]);
34+
scope_bare_fn(ast::fn_decl, node_id, [ast::ty_param]);
35+
scope_fn_expr(ast::fn_decl, node_id, [ast::ty_param]);
3536
scope_native_item(@ast::native_item);
3637
scope_loop(@ast::local); // there's only 1 decl per loop.
3738
scope_block(ast::blk, @mutable uint, @mutable uint);
@@ -335,8 +336,11 @@ fn resolve_names(e: @env, c: @ast::crate) {
335336
visit_expr: bind walk_expr(e, _, _, _),
336337
visit_ty: bind walk_ty(e, _, _, _),
337338
visit_constr: bind walk_constr(e, _, _, _, _, _),
338-
visit_fn: bind visit_fn_with_scope(e, _, _, _, _, _, _, _)
339-
with *visit::default_visitor()};
339+
visit_fn_proto:
340+
bind visit_fn_proto_with_scope(e, _, _, _, _, _, _, _),
341+
visit_fn_block:
342+
bind visit_fn_block_with_scope(e, _, _, _, _, _, _)
343+
with *visit::default_visitor()};
340344
visit::visit_crate(*c, cons(scope_crate, @nil), visit::mk_vt(v));
341345
e.used_imports.track = false;
342346
e.sess.abort_if_errors();
@@ -400,8 +404,8 @@ fn visit_item_with_scope(i: @ast::item, sc: scopes, v: vt<scopes>) {
400404
ast::item_impl(tps, sty, methods) {
401405
visit::visit_ty(sty, sc, v);
402406
for m in methods {
403-
v.visit_fn(m.node.meth, tps + m.node.tps, m.span,
404-
some(m.node.ident), m.node.id, sc, v);
407+
v.visit_fn_proto(m.node.meth, tps + m.node.tps, m.span,
408+
some(m.node.ident), m.node.id, sc, v);
405409
}
406410
}
407411
_ { visit::visit_item(i, sc, v); }
@@ -413,9 +417,9 @@ fn visit_native_item_with_scope(ni: @ast::native_item, sc: scopes,
413417
visit::visit_native_item(ni, cons(scope_native_item(ni), @sc), v);
414418
}
415419

416-
fn visit_fn_with_scope(e: @env, f: ast::_fn, tp: [ast::ty_param], sp: span,
417-
name: fn_ident, id: node_id, sc: scopes,
418-
v: vt<scopes>) {
420+
fn visit_fn_proto_with_scope(e: @env, f: ast::_fn, tp: [ast::ty_param],
421+
sp: span, name: fn_ident, id: node_id,
422+
sc: scopes, v: vt<scopes>) {
419423
// is this a main fn declaration?
420424
alt name {
421425
some(nm) {
@@ -431,8 +435,21 @@ fn visit_fn_with_scope(e: @env, f: ast::_fn, tp: [ast::ty_param], sp: span,
431435
// here's where we need to set up the mapping
432436
// for f's constrs in the table.
433437
for c: @ast::constr in f.decl.constraints { resolve_constr(e, c, sc, v); }
434-
visit::visit_fn(f, tp, sp, name, id,
435-
cons(scope_fn(f.decl, f.proto, tp), @sc), v);
438+
let scope = alt f.proto {
439+
ast::proto_bare. { scope_bare_fn(f.decl, id, tp) }
440+
_ { scope_fn_expr(f.decl, id, tp) }
441+
};
442+
443+
visit::visit_fn_proto(f, tp, sp, name, id, cons(scope, @sc), v);
444+
}
445+
446+
fn visit_fn_block_with_scope(_e: @env, decl: fn_decl, blk: ast::blk,
447+
span: span, id: node_id,
448+
sc: scopes, v: vt<scopes>) {
449+
let scope = scope_fn_expr(decl, id, []);
450+
log ("scope=", scope);
451+
visit::visit_fn_block(decl, blk, span, id, cons(scope, @sc), v);
452+
log ("unscope");
436453
}
437454

438455
fn visit_block_with_scope(b: ast::blk, sc: scopes, v: vt<scopes>) {
@@ -648,7 +665,8 @@ fn unresolved_err(e: env, cx: ctxt, sp: span, name: ident, kind: str) {
648665
alt sc {
649666
cons(cur, rest) {
650667
alt cur {
651-
scope_crate. | scope_fn(_, _, _) |
668+
scope_crate. | scope_bare_fn(_, _, _) |
669+
scope_fn_expr(_, _, _) |
652670
scope_item(@{node: ast::item_mod(_), _}) {
653671
ret some(cur);
654672
}
@@ -734,23 +752,17 @@ fn lookup_in_scope_strict(e: env, sc: scopes, sp: span, name: ident,
734752

735753
fn scope_is_fn(sc: scope) -> bool {
736754
ret alt sc {
737-
scope_fn(_, ast::proto_bare., _) |
738-
scope_native_item(_) {
739-
true
740-
}
741-
_ { false }
742-
};
755+
scope_bare_fn(_, _, _) | scope_native_item(_) { true }
756+
_ { false }
757+
};
743758
}
744759

745760
// Returns:
746761
// none - does not close
747-
// some(true) - closes and permits mutation
748-
// some(false) - closes but no mutation
749-
fn scope_closes(sc: scope) -> option::t<bool> {
762+
// some(node_id) - closes via the expr w/ node_id
763+
fn scope_closes(sc: scope) -> option::t<node_id> {
750764
alt sc {
751-
scope_fn(_, ast::proto_block., _) { some(true) }
752-
scope_fn(_, ast::proto_send., _) { some(false) }
753-
scope_fn(_, ast::proto_shared(_), _) { some(false) }
765+
scope_fn_expr(_, node_id, _) { some(node_id) }
754766
_ { none }
755767
}
756768
}
@@ -823,7 +835,8 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
823835
}
824836
}
825837
}
826-
scope_fn(decl, _, ty_params) {
838+
scope_bare_fn(decl, _, ty_params) |
839+
scope_fn_expr(decl, _, ty_params) {
827840
ret lookup_in_fn(name, decl, ty_params, ns);
828841
}
829842
scope_loop(local) {
@@ -887,7 +900,10 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
887900
left_fn_level2 = true;
888901
} else if ns == ns_value || ns == ns_type {
889902
left_fn = scope_is_fn(hd);
890-
alt scope_closes(hd) { some(mut) { closing += [mut]; } _ { } }
903+
alt scope_closes(hd) {
904+
some(node_id) { closing += [node_id]; }
905+
_ { }
906+
}
891907
}
892908
sc = *tl;
893909
}

trunk/src/comp/middle/trans.rs

+13
Original file line numberDiff line numberDiff line change
@@ -3558,6 +3558,19 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
35583558
ret trans_closure::trans_expr_fn(
35593559
bcx, f, e.span, e.id, *cap_clause, dest);
35603560
}
3561+
ast::expr_fn_block(decl, body) {
3562+
alt ty::struct(tcx, ty::expr_ty(tcx, e)) {
3563+
ty::ty_fn(proto, _, _, _, _) {
3564+
let f: ast::_fn = { decl: decl, proto: proto, body: body };
3565+
let cap_clause = { copies: [], moves: [] };
3566+
ret trans_closure::trans_expr_fn(
3567+
bcx, f, e.span, e.id, cap_clause, dest);
3568+
}
3569+
_ {
3570+
fail "Type of fn block is not a function!";
3571+
}
3572+
}
3573+
}
35613574
ast::expr_bind(f, args) {
35623575
ret trans_closure::trans_bind(
35633576
bcx, f, args, e.id, dest);

0 commit comments

Comments
 (0)