diff options
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/driver/rustc.rs | 3 | ||||
| -rw-r--r-- | src/comp/front/ast.rs | 2 | ||||
| -rw-r--r-- | src/comp/middle/capture.rs | 119 | ||||
| -rw-r--r-- | src/comp/middle/resolve.rs | 61 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 3 | ||||
| -rw-r--r-- | src/comp/rustc.rc | 1 |
6 files changed, 49 insertions, 140 deletions
diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index ad89ac9c..6592c23a 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -7,7 +7,6 @@ import front::eval; import front::ast; import middle::trans; import middle::resolve; -import middle::capture; import middle::ty; import middle::typeck; import middle::typestate_check; @@ -94,8 +93,6 @@ fn compile_input(session::session sess, bind creader::read_crates(sess, crate)); auto def_map = time(time_passes, "resolution", bind resolve::resolve_crate(sess, crate)); - time[()](time_passes, "capture checking", - bind capture::check_for_captures(sess, crate, def_map)); auto ty_cx = ty::mk_ctxt(sess, def_map); auto typeck_result = diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index c107e7c8..5e5185bf 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -46,7 +46,6 @@ tag def { def_const(def_id); def_arg(def_id); def_local(def_id); - def_upvar(def_id); def_variant(def_id /* tag */, def_id /* variant */); def_ty(def_id); def_ty_arg(uint); @@ -74,7 +73,6 @@ fn def_id_of_def(def d) -> def_id { case (def_const(?id)) { ret id; } case (def_arg(?id)) { ret id; } case (def_local(?id)) { ret id; } - case (def_upvar(?id)) { ret id; } case (def_variant(_, ?id)) { ret id; } case (def_ty(?id)) { ret id; } case (def_ty_arg(_)) { fail; } diff --git a/src/comp/middle/capture.rs b/src/comp/middle/capture.rs deleted file mode 100644 index 7124554a..00000000 --- a/src/comp/middle/capture.rs +++ /dev/null @@ -1,119 +0,0 @@ -import driver::session; -import front::ast; -import std::map::hashmap; -import std::option; -import std::option::some; -import std::option::none; -import std::_int; -import std::_vec; -import util::common; -import resolve::def_map; - -type fn_id_of_local = std::map::hashmap[ast::def_id, ast::def_id]; -type env = rec(mutable vec[ast::def_id] current_context, // fn or obj - def_map def_map, - fn_id_of_local idmap, - session::session sess); - -fn current_context(&env e) -> ast::def_id { - ret e.current_context.(_vec::len(e.current_context) - 1u); -} - -fn enter_item(@env e, &@ast::item i) { - alt (i.node) { - case (ast::item_fn(?name, _, _, ?id, _)) { - _vec::push(e.current_context, id); - } - case (ast::item_obj(?name, _, _, ?ids, _)) { - _vec::push(e.current_context, ids.ty); - } - case (_) {} - } -} - -fn leave_item(@env e, &@ast::item i) { - alt (i.node) { - case (ast::item_fn(?name, _, _, ?id, _)) { - _vec::pop(e.current_context); - } - case (ast::item_obj(_, _, _, ?ids, _)) { - _vec::pop(e.current_context); - } - case (_) {} - } -} - -fn walk_expr(@env e, &@ast::expr x) { - alt (x.node) { - case (ast::expr_for(?d, _, _, _)) { - alt (d.node) { - case (ast::decl_local(?local)) { - e.idmap.insert(local.id, current_context(*e)); - } - case (_) { } - } - } - case (ast::expr_for_each(?d, _, _, _)) { - alt (d.node) { - case (ast::decl_local(?local)) { - e.idmap.insert(local.id, current_context(*e)); - } - case (_) { } - } - } - case (ast::expr_path(?pt, ?ann)) { - auto local_id; - alt (e.def_map.get(ast::ann_tag(ann))) { - case (ast::def_local(?id)) { local_id = id; } - case (_) { ret; } - } - auto df = ast::def_id_of_def(e.def_map.get(ast::ann_tag(ann))); - auto def_context = e.idmap.get(df); - - if (current_context(*e) != def_context) { - e.sess.span_err(x.span, - "attempted dynamic environment-capture"); - } - } - case (_) { } - } -} - -fn walk_block(@env e, &ast::block b) { - for (@ast::stmt st in b.node.stmts) { - alt (st.node) { - case (ast::stmt_decl(?d,_)) { - alt (d.node) { - case (ast::decl_local(?loc)) { - e.idmap.insert(loc.id, current_context(*e)); - } - case (_) { } - } - } - case (_) { } - } - } -} - -fn check_for_captures(session::session sess, @ast::crate crate, def_map dm) { - let vec[ast::def_id] curctx = vec(); - auto env = @rec(mutable current_context = curctx, - def_map = dm, - idmap = common::new_def_hash[ast::def_id](), - sess = sess); - auto visitor = rec(visit_item_pre = bind enter_item(env, _), - visit_item_post = bind leave_item(env, _), - visit_block_pre = bind walk_block(env, _), - visit_expr_pre = bind walk_expr(env, _) - with walk::default_visitor()); - walk::walk_crate(visitor, *crate); -} - -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; -// End: diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index ce7a2376..11837033 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -317,8 +317,8 @@ fn resolve_import(&env e, &@ast::view_item it, &list[scope] sc) { if (n_idents == 1u) { register(e, defid, it.span, end_id, - lookup_in_scope(e, sc, end_id, ns_value), - lookup_in_scope(e, sc, end_id, ns_type)); + lookup_in_scope(e, sc, it.span, end_id, ns_value), + lookup_in_scope(e, sc, it.span, end_id, ns_type)); } else { auto dcur = lookup_in_scope_strict(e, sc, it.span, ids.(0), ns_value); auto i = 1u; @@ -394,7 +394,7 @@ fn lookup_path_strict(&env e, &list[scope] sc, &span sp, vec[ident] idents, fn lookup_in_scope_strict(&env e, list[scope] sc, &span sp, ident id, namespace ns) -> def { - alt (lookup_in_scope(e, sc, id, ns)) { + alt (lookup_in_scope(e, sc, sp, id, ns)) { case (none[def]) { unresolved(e, sp, id, ns_name(ns)); fail; @@ -405,7 +405,35 @@ fn lookup_in_scope_strict(&env e, list[scope] sc, &span sp, ident id, } } -fn lookup_in_scope(&env e, list[scope] sc, ident id, namespace ns) +fn scope_is_fn(&scope sc) -> bool { + ret alt (sc) { + case (scope_item(?it)) { + alt (it.node) { + case (ast::item_fn(_, _, _, _, _)) { true } + case (_) { false } + } + } + case (scope_native_item(_)) { true } + case (_) { false } + }; +} + +fn def_is_local(&def d) -> bool { + ret alt (d) { + case (ast::def_arg(_)) { true } + case (ast::def_local(_)) { true } + case (ast::def_binding(_)) { true } + case (_) { false } + }; +} +fn def_is_obj_field(&def d) -> bool { + ret alt (d) { + case (ast::def_obj_field(_)) { true } + case (_) { false } + }; +} + +fn lookup_in_scope(&env e, list[scope] sc, &span sp, ident id, namespace ns) -> option::t[def] { fn in_scope(&env e, ident id, &scope s, namespace ns) -> option::t[def] { @@ -441,7 +469,6 @@ fn lookup_in_scope(&env e, list[scope] sc, ident id, namespace ns) case (_) {} } } - case (scope_native_item(?it)) { alt (it.node) { case (ast::native_item_fn(_, _, ?decl, ?ty_params, _, _)){ @@ -449,7 +476,6 @@ fn lookup_in_scope(&env e, list[scope] sc, ident id, namespace ns) } } } - case (scope_loop(?d)) { if (ns == ns_value) { alt (d.node) { @@ -461,11 +487,9 @@ fn lookup_in_scope(&env e, list[scope] sc, ident id, namespace ns) } } } - case (scope_block(?b)) { ret lookup_in_block(id, b.node, ns); } - case (scope_arm(?a)) { if (ns == ns_value) { ret lookup_in_pat(id, *a.pat); @@ -475,16 +499,30 @@ fn lookup_in_scope(&env e, list[scope] sc, ident id, namespace ns) ret none[def]; } + auto left_fn = false; + // Used to determine whether obj fields are in scope + auto left_fn_level2 = false; while (true) { alt (sc) { case (nil[scope]) { ret none[def]; } case (cons[scope](?hd, ?tl)) { - alt (in_scope(e, id, hd, ns)) { - case (some[def](?x)) { ret some(x); } - case (_) { sc = *tl; } + auto fnd = in_scope(e, id, hd, ns); + if (fnd != none[def]) { + auto df = option::get(fnd); + if ((left_fn && def_is_local(df)) || + (left_fn_level2 && def_is_obj_field(df))) { + e.sess.span_err(sp, "attempted dynamic " + + "environment-capture"); + } + ret fnd; + } + if (left_fn) { left_fn_level2 = true; } + if (ns == ns_value && !left_fn) { + left_fn = scope_is_fn(hd); } + sc = *tl; } } } @@ -841,7 +879,6 @@ fn check_def_by_ns(def d, namespace ns) -> bool { case (ast::def_const(?id)) { ns == ns_value } case (ast::def_arg(?id)) { ns == ns_value } case (ast::def_local(?id)) { ns == ns_value } - case (ast::def_upvar(?id)) { ns == ns_value } case (ast::def_variant(_, ?id)) { ns == ns_value } case (ast::def_ty(?id)) { ns == ns_type } case (ast::def_binding(?id)) { ns == ns_type } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 78a7a16a..d822be17 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3807,9 +3807,6 @@ fn collect_upvars(&@block_ctxt cx, &ast::block bloc, case (ast::def_local(?did)) { _vec::push[ast::def_id](e.refs, did); } - case (ast::def_upvar(?did)) { - _vec::push[ast::def_id](e.refs, did); - } case (_) {} } } diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index 0d011eee..ca5534b3 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -17,7 +17,6 @@ mod middle { mod walk; mod metadata; mod resolve; - mod capture; mod typeck; mod typestate_check; } |