Skip to content

Commit 013107a

Browse files
committed
Properly take mutable object fields into account during alias analysis
Closes #1055
1 parent cfdf193 commit 013107a

File tree

4 files changed

+35
-29
lines changed

4 files changed

+35
-29
lines changed

src/comp/middle/alias.rs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ fn ty_can_unsafely_include(cx: ctx, needle: unsafe_ty, haystack: ty::t,
551551
for t in ts { if helper(tcx, needle, t, mut) { ret true; } }
552552
ret false;
553553
}
554+
ty::ty_fn(ast::proto_bare., _, _, _, _) { ret false; }
554555
// These may contain anything.
555556
ty::ty_fn(_, _, _, _, _) | ty::ty_obj(_) { ret true; }
556557
// A type param may include everything, but can only be
@@ -665,26 +666,32 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
665666
for d in *base_root.ds {
666667
if d.mut { unsafe_ty = some(contains(d.outer_t)); break; }
667668
}
668-
if is_none(path_def_id(cx, base_root.ex)) {
669-
alt base_root.ex.node {
670-
ast::expr_call(f, args, _) {
671-
let fty = ty::expr_ty(cx.tcx, f);
672-
alt ty::ty_fn_ret_style(cx.tcx, fty) {
673-
ast::return_ref(mut, arg_n) {
674-
let arg = args[arg_n - 1u];
675-
let arg_root = expr_root(cx, arg, false);
676-
if mut {
677-
let ret_ty = ty::expr_ty(cx.tcx, base_root.ex);
678-
unsafe_ty = some(mut_contains(ret_ty));
679-
}
680-
if !is_none(arg_root.mut) { unsafe_ty = arg_root.mut; }
681-
ret {ex: arg_root.ex, mut: unsafe_ty};
682-
}
683-
_ {}
669+
alt base_root.ex.node {
670+
ast::expr_path(_) {
671+
alt cx.tcx.def_map.get(base_root.ex.id) {
672+
ast::def_obj_field(_, ast::mut.) {
673+
unsafe_ty = some(mut_contains(ty::expr_ty(cx.tcx, base_root.ex)));
674+
}
675+
_ {}
676+
}
677+
}
678+
ast::expr_call(f, args, _) {
679+
let fty = ty::expr_ty(cx.tcx, f);
680+
alt ty::ty_fn_ret_style(cx.tcx, fty) {
681+
ast::return_ref(mut, arg_n) {
682+
let arg = args[arg_n - 1u];
683+
let arg_root = expr_root(cx, arg, false);
684+
if mut {
685+
let ret_ty = ty::expr_ty(cx.tcx, base_root.ex);
686+
unsafe_ty = some(mut_contains(ret_ty));
684687
}
688+
if !is_none(arg_root.mut) { unsafe_ty = arg_root.mut; }
689+
ret {ex: arg_root.ex, mut: unsafe_ty};
685690
}
686691
_ {}
687692
}
693+
}
694+
_ {}
688695
}
689696
ret {ex: base_root.ex, mut: unsafe_ty};
690697
}

src/lib/map.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/**
22
* Hashmap implementation.
33
*/
4-
type hashfn<K> = fn@(K) -> uint;
4+
type hashfn<K> = fn(K) -> uint;
55

6-
type eqfn<K> = fn@(K, K) -> bool;
6+
type eqfn<K> = fn(K, K) -> bool;
77

88
type hashmap<K, V> =
99
obj {

src/test/run-fail/unwind-misc-1.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,10 @@ import std::uint;
66

77
fn main() {
88
let count = @mutable 0u;
9-
let hash = bind fn (&&_s: [@str], count: @mutable uint) -> uint {
10-
*count += 1u;
11-
if *count == 10u {
12-
fail;
13-
} else {
14-
ret *count;
15-
}
16-
} (_, count);
17-
9+
fn hash(&&s: [@str]) -> uint {
10+
if (std::vec::len(s) > 0u && std::str::eq(*s[0], "boom")) { fail; }
11+
ret 10u;
12+
}
1813
fn eq(&&s: [@str], &&t: [@str]) -> bool {
1914
ret s == t;
2015
}
@@ -25,4 +20,5 @@ fn main() {
2520
arr += [@"key stuff"];
2621
map.insert(arr, arr + [@"value stuff"]);
2722
}
23+
map.insert([@"boom"], []);
2824
}

src/test/stdtest/map.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import std::uint;
88
import std::util;
99
import std::option;
1010

11+
1112
#[test]
1213
fn test_simple() {
1314
log "*** starting test_simple";
1415
fn eq_uint(&&x: uint, &&y: uint) -> bool { ret x == y; }
15-
let hasher_uint: map::hashfn<uint> = bind util::id(_);
16+
fn uint_id(&&x: uint) -> uint { x }
17+
let hasher_uint: map::hashfn<uint> = uint_id;
1618
let eqer_uint: map::eqfn<uint> = eq_uint;
1719
let hasher_str: map::hashfn<str> = str::hash;
1820
let eqer_str: map::eqfn<str> = str::eq;
@@ -84,8 +86,9 @@ fn test_growth() {
8486
log "*** starting test_growth";
8587
let num_to_insert: uint = 64u;
8688
fn eq_uint(&&x: uint, &&y: uint) -> bool { ret x == y; }
89+
fn uint_id(&&x: uint) -> uint { x }
8790
log "uint -> uint";
88-
let hasher_uint: map::hashfn<uint> = bind util::id(_);
91+
let hasher_uint: map::hashfn<uint> = uint_id;
8992
let eqer_uint: map::eqfn<uint> = eq_uint;
9093
let hm_uu: map::hashmap<uint, uint> =
9194
map::mk_hashmap::<uint, uint>(hasher_uint, eqer_uint);

0 commit comments

Comments
 (0)