about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/comp/middle/freevars.rs21
-rw-r--r--src/comp/syntax/ast.rs6
2 files changed, 23 insertions, 4 deletions
diff --git a/src/comp/middle/freevars.rs b/src/comp/middle/freevars.rs
index 5c8f496d16b..540716550ce 100644
--- a/src/comp/middle/freevars.rs
+++ b/src/comp/middle/freevars.rs
@@ -18,8 +18,8 @@ export freevar_set;
 export freevar_map;
 export get_freevars;
 export has_freevars;
-export is_freevarof;
-
+export is_freevar_of;
+export def_lookup;
 
 type freevar_set = @ast::node_id[];
 type freevar_map = hashmap[ast::node_id, freevar_set];
@@ -138,10 +138,10 @@ fn annotate_freevars(&session::session sess, &resolve::def_map def_map,
 
 fn get_freevars(&ty::ctxt tcx, ast::node_id fid) -> freevar_set {
     alt (tcx.freevars.find(fid)) {
-        case (none) {
+        none {
             fail "get_freevars: " + int::str(fid) + " has no freevars";
         }
-        case (some(?d)) { ret d; }
+        some(?d) { ret d; }
     }
 }
 fn has_freevars(&ty::ctxt tcx, ast::node_id fid) -> bool {
@@ -150,6 +150,19 @@ fn has_freevars(&ty::ctxt tcx, ast::node_id fid) -> bool {
 fn is_freevar_of(&ty::ctxt tcx, ast::node_id var, ast::node_id f) -> bool {
     ret ivec::member(var, *get_freevars(tcx, f));
 }
+fn def_lookup(&ty::ctxt tcx, ast::node_id f, ast::node_id id) ->
+    option::t[ast::def] {
+    alt (tcx.def_map.find(id)) {
+      none { ret none; }
+      some(?d) {
+        auto did = ast::def_id_of_def(d);
+        if is_freevar_of(tcx, did._1, f) {
+            ret some(ast::def_upvar(did, @d));
+        } else { ret some(d); }
+      }
+    }
+}
+
 
 // Local Variables:
 // mode: rust
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index 5992a857d14..a9367724c5e 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -52,6 +52,11 @@ tag def {
     def_use(def_id);
     def_native_ty(def_id);
     def_native_fn(def_id);
+
+    /* A "fake" def for upvars. This never appears in the def_map, but
+     * freevars::def_lookup will return it for a def that is an upvar.
+     * It contains the actual def. */
+    def_upvar(def_id, @def);
 }
 
 fn variant_def_ids(&def d) -> tup(def_id, def_id) {
@@ -76,6 +81,7 @@ fn def_id_of_def(def d) -> def_id {
         case (def_use(?id)) { ret id; }
         case (def_native_ty(?id)) { ret id; }
         case (def_native_fn(?id)) { ret id; }
+        case (def_upvar(?id, _)) { ret id; }
     }
     fail;
 }