mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-14 16:03:17 +00:00
Properly take mutable object fields into account during alias analysis
Closes #1055
This commit is contained in:
parent
cfdf193c46
commit
013107a25c
@ -551,6 +551,7 @@ fn ty_can_unsafely_include(cx: ctx, needle: unsafe_ty, haystack: ty::t,
|
||||
for t in ts { if helper(tcx, needle, t, mut) { ret true; } }
|
||||
ret false;
|
||||
}
|
||||
ty::ty_fn(ast::proto_bare., _, _, _, _) { ret false; }
|
||||
// These may contain anything.
|
||||
ty::ty_fn(_, _, _, _, _) | ty::ty_obj(_) { ret true; }
|
||||
// A type param may include everything, but can only be
|
||||
@ -665,26 +666,32 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
|
||||
for d in *base_root.ds {
|
||||
if d.mut { unsafe_ty = some(contains(d.outer_t)); break; }
|
||||
}
|
||||
if is_none(path_def_id(cx, base_root.ex)) {
|
||||
alt base_root.ex.node {
|
||||
ast::expr_call(f, args, _) {
|
||||
let fty = ty::expr_ty(cx.tcx, f);
|
||||
alt ty::ty_fn_ret_style(cx.tcx, fty) {
|
||||
ast::return_ref(mut, arg_n) {
|
||||
let arg = args[arg_n - 1u];
|
||||
let arg_root = expr_root(cx, arg, false);
|
||||
if mut {
|
||||
let ret_ty = ty::expr_ty(cx.tcx, base_root.ex);
|
||||
unsafe_ty = some(mut_contains(ret_ty));
|
||||
}
|
||||
if !is_none(arg_root.mut) { unsafe_ty = arg_root.mut; }
|
||||
ret {ex: arg_root.ex, mut: unsafe_ty};
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
alt base_root.ex.node {
|
||||
ast::expr_path(_) {
|
||||
alt cx.tcx.def_map.get(base_root.ex.id) {
|
||||
ast::def_obj_field(_, ast::mut.) {
|
||||
unsafe_ty = some(mut_contains(ty::expr_ty(cx.tcx, base_root.ex)));
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
ast::expr_call(f, args, _) {
|
||||
let fty = ty::expr_ty(cx.tcx, f);
|
||||
alt ty::ty_fn_ret_style(cx.tcx, fty) {
|
||||
ast::return_ref(mut, arg_n) {
|
||||
let arg = args[arg_n - 1u];
|
||||
let arg_root = expr_root(cx, arg, false);
|
||||
if mut {
|
||||
let ret_ty = ty::expr_ty(cx.tcx, base_root.ex);
|
||||
unsafe_ty = some(mut_contains(ret_ty));
|
||||
}
|
||||
if !is_none(arg_root.mut) { unsafe_ty = arg_root.mut; }
|
||||
ret {ex: arg_root.ex, mut: unsafe_ty};
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
ret {ex: base_root.ex, mut: unsafe_ty};
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
/**
|
||||
* Hashmap implementation.
|
||||
*/
|
||||
type hashfn<K> = fn@(K) -> uint;
|
||||
type hashfn<K> = fn(K) -> uint;
|
||||
|
||||
type eqfn<K> = fn@(K, K) -> bool;
|
||||
type eqfn<K> = fn(K, K) -> bool;
|
||||
|
||||
type hashmap<K, V> =
|
||||
obj {
|
||||
|
@ -6,15 +6,10 @@ import std::uint;
|
||||
|
||||
fn main() {
|
||||
let count = @mutable 0u;
|
||||
let hash = bind fn (&&_s: [@str], count: @mutable uint) -> uint {
|
||||
*count += 1u;
|
||||
if *count == 10u {
|
||||
fail;
|
||||
} else {
|
||||
ret *count;
|
||||
}
|
||||
} (_, count);
|
||||
|
||||
fn hash(&&s: [@str]) -> uint {
|
||||
if (std::vec::len(s) > 0u && std::str::eq(*s[0], "boom")) { fail; }
|
||||
ret 10u;
|
||||
}
|
||||
fn eq(&&s: [@str], &&t: [@str]) -> bool {
|
||||
ret s == t;
|
||||
}
|
||||
@ -25,4 +20,5 @@ fn main() {
|
||||
arr += [@"key stuff"];
|
||||
map.insert(arr, arr + [@"value stuff"]);
|
||||
}
|
||||
map.insert([@"boom"], []);
|
||||
}
|
@ -8,11 +8,13 @@ import std::uint;
|
||||
import std::util;
|
||||
import std::option;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
log "*** starting test_simple";
|
||||
fn eq_uint(&&x: uint, &&y: uint) -> bool { ret x == y; }
|
||||
let hasher_uint: map::hashfn<uint> = bind util::id(_);
|
||||
fn uint_id(&&x: uint) -> uint { x }
|
||||
let hasher_uint: map::hashfn<uint> = uint_id;
|
||||
let eqer_uint: map::eqfn<uint> = eq_uint;
|
||||
let hasher_str: map::hashfn<str> = str::hash;
|
||||
let eqer_str: map::eqfn<str> = str::eq;
|
||||
@ -84,8 +86,9 @@ fn test_growth() {
|
||||
log "*** starting test_growth";
|
||||
let num_to_insert: uint = 64u;
|
||||
fn eq_uint(&&x: uint, &&y: uint) -> bool { ret x == y; }
|
||||
fn uint_id(&&x: uint) -> uint { x }
|
||||
log "uint -> uint";
|
||||
let hasher_uint: map::hashfn<uint> = bind util::id(_);
|
||||
let hasher_uint: map::hashfn<uint> = uint_id;
|
||||
let eqer_uint: map::eqfn<uint> = eq_uint;
|
||||
let hm_uu: map::hashmap<uint, uint> =
|
||||
map::mk_hashmap::<uint, uint>(hasher_uint, eqer_uint);
|
||||
|
Loading…
Reference in New Issue
Block a user