diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-11-21 11:34:00 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-11-21 12:07:40 +0100 |
| commit | 02574a5bdb7900fd6b40bf4f3c93080eafa35d4e (patch) | |
| tree | 9dac290ad36825f3d79464286d641b174665d92c /src/comp/middle | |
| parent | b4217b383bbbebafbdc621f31716d5bee3cd0c72 (diff) | |
| download | rust-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.rs | 18 |
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]); } |
