about summary refs log tree commit diff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-11-21 11:34:00 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2011-11-21 12:07:40 +0100
commit02574a5bdb7900fd6b40bf4f3c93080eafa35d4e (patch)
tree9dac290ad36825f3d79464286d641b174665d92c /src/comp/middle
parentb4217b383bbbebafbdc621f31716d5bee3cd0c72 (diff)
downloadrust-02574a5bdb7900fd6b40bf4f3c93080eafa35d4e.tar.gz
rust-02574a5bdb7900fd6b40bf4f3c93080eafa35d4e.zip
Close hole in safe-reference analysis
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/alias.rs18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs
index 7322583a926..89efd15ef29 100644
--- a/src/comp/middle/alias.rs
+++ b/src/comp/middle/alias.rs
@@ -110,7 +110,7 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
     let handled = true;
     alt ex.node {
       ast::expr_call(f, args, _) {
-        check_call(*cx, f, args);
+        check_call(*cx, sc, f, args);
         handled = false;
       }
       ast::expr_alt(input, arms) { check_alt(*cx, input, arms, sc, v); }
@@ -234,7 +234,8 @@ fn cant_copy(cx: ctx, b: binding) -> bool {
     } else { ret true; }
 }
 
-fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [binding] {
+fn check_call(cx: ctx, sc: scope, f: @ast::expr, args: [@ast::expr])
+    -> [binding] {
     let fty = ty::expr_ty(cx.tcx, f);
     let by_ref = alt ty::ty_fn_ret_style(cx.tcx, fty) {
       ast::return_ref(_, arg_n) { arg_n } _ { 0u }
@@ -276,7 +277,18 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [binding] {
     if f_may_close {
         let i = 0u;
         for b in bindings {
-            if vec::len(b.unsafe_tys) > 0u && cant_copy(cx, b) {
+            let unsfe = vec::len(b.unsafe_tys) > 0u;
+            alt b.root_var {
+              some(rid) {
+                for o in sc.bs {
+                    if o.node_id == rid && vec::len(o.unsafe_tys) > 0u {
+                        unsfe = true; break;
+                    }
+                }
+              }
+              _ {}
+            }
+            if unsfe && cant_copy(cx, b) {
                 err(cx, f.span, #fmt["function may alias with argument \
                                      %u, which is not immutably rooted", i]);
             }