Some more workarounds to please the alias checker
Some of the vec utilities now only work on immutable vecs, since they would have to be rewritten to do a lot more copying to be alias-safe. Some forced copying was added to map.rs, showing a weakness in the alias checker (or maybe the alias system): when fn args are passed into a function, calling them must assume all aliases that are not immutably rooted (directly connected to a local or temporary without any mutable edges) become invalid. This will be a drag on functional programming in Rust. Work around alias issues in the stdlib
This commit is contained in:
parent
bd90c7a3cb
commit
77c1b9650f
5 changed files with 27 additions and 20 deletions
|
@ -339,7 +339,8 @@ fn crate_meta_extras_hash(sha1 sha, &ast::crate crate) -> str {
|
|||
}
|
||||
sort::quick_sort(lteq, v);
|
||||
sha.reset();
|
||||
for (@ast::meta_item m in v) {
|
||||
for (@ast::meta_item m_ in v) {
|
||||
auto m = m_;
|
||||
sha.input_str(len_and_str(m.node.name));
|
||||
sha.input_str(len_and_str(m.node.value));
|
||||
}
|
||||
|
|
|
@ -76,8 +76,10 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
|
|||
let uint j = hash(h, nbkts, i);
|
||||
alt (bkts.(j)) {
|
||||
case (some(?k, _)) {
|
||||
if (eqer(key, k)) {
|
||||
bkts.(j) = some[K, V](k, val);
|
||||
// Copy key to please alias analysis.
|
||||
auto k_ = k;
|
||||
if (eqer(key, k_)) {
|
||||
bkts.(j) = some[K, V](k_, val);
|
||||
ret false;
|
||||
}
|
||||
i += 1u;
|
||||
|
@ -104,8 +106,11 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
|
|||
let uint j = (hash(h, nbkts, i));
|
||||
alt (bkts.(j)) {
|
||||
case (some(?k, ?v)) {
|
||||
if (eqer(key, k)) {
|
||||
ret option::some[V](v);
|
||||
// Copy to please alias analysis.
|
||||
auto k_ = k;
|
||||
auto v_ = v;
|
||||
if (eqer(key, k_)) {
|
||||
ret option::some[V](v_);
|
||||
}
|
||||
}
|
||||
case (nil) {
|
||||
|
@ -190,10 +195,11 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
|
|||
let uint j = (hash(h, nbkts, i));
|
||||
alt (bkts.(j)) {
|
||||
case (some(?k, ?v)) {
|
||||
if (eqer(key, k)) {
|
||||
auto k_ = k; auto vo = option::some(v);
|
||||
if (eqer(key, k_)) {
|
||||
bkts.(j) = deleted[K, V];
|
||||
nelts -= 1u;
|
||||
ret option::some[V](v);
|
||||
ret vo;
|
||||
}
|
||||
}
|
||||
case (deleted) { }
|
||||
|
|
|
@ -58,7 +58,7 @@ fn part[T](lteq[T] compare_func, vec[mutable T] arr, uint left,
|
|||
let uint storage_index = left;
|
||||
let uint i = left;
|
||||
while (i<right) {
|
||||
if (compare_func(arr.(i), pivot_value)) {
|
||||
if (compare_func({arr.(i)}, pivot_value)) {
|
||||
swap[T](arr, i, storage_index);
|
||||
storage_index += 1u;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ fn quick_sort[T](lteq[T] compare_func, vec[mutable T] arr) {
|
|||
// 'randomly ordered keys, abstract compare' & 'small number of key values'
|
||||
|
||||
fn qsort3[T](lteq[T] compare_func_lt, lteq[T] compare_func_eq,
|
||||
vec[mutable T] arr, int left, int right) {
|
||||
vec[mutable T] arr, int left, int right) {
|
||||
|
||||
if (right <= left) {
|
||||
ret;
|
||||
|
@ -111,11 +111,11 @@ fn qsort3[T](lteq[T] compare_func_lt, lteq[T] compare_func_eq,
|
|||
|
||||
while (true) {
|
||||
i += 1;
|
||||
while (compare_func_lt(arr.(i), v)) {
|
||||
while (compare_func_lt({arr.(i)}, v)) {
|
||||
i += 1;
|
||||
}
|
||||
j -= 1;
|
||||
while (compare_func_lt(v, arr.(j))) {
|
||||
while (compare_func_lt(v, {arr.(j)})) {
|
||||
if (j == left) {
|
||||
break;
|
||||
}
|
||||
|
@ -125,11 +125,11 @@ fn qsort3[T](lteq[T] compare_func_lt, lteq[T] compare_func_eq,
|
|||
break;
|
||||
}
|
||||
swap[T](arr, i as uint, j as uint);
|
||||
if (compare_func_eq(arr.(i), v)) {
|
||||
if (compare_func_eq({arr.(i)}, v)) {
|
||||
p += 1;
|
||||
swap[T](arr, p as uint, i as uint);
|
||||
}
|
||||
if (compare_func_eq(v, arr.(j))) {
|
||||
if (compare_func_eq(v, {arr.(j)})) {
|
||||
q -= 1;
|
||||
swap[T](arr, j as uint, q as uint);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ fn grow(&ufind ufnd, uint n) {
|
|||
fn find(&ufind ufnd, uint n) -> uint {
|
||||
alt (ufnd.nodes.(n)) {
|
||||
case (none) { ret n; }
|
||||
case (some(?m)) { be find(ufnd, m); }
|
||||
case (some(?m)) { auto m_ = m; be find(ufnd, m_); }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,7 @@ fn grow_init_fn_set[T](&array[T] v, uint index, fn()->T init_fn, &T val) {
|
|||
}
|
||||
|
||||
|
||||
fn map[T, U](&fn(&T) -> U f, &array[T] v) -> vec[U] {
|
||||
fn map[T, U](&fn(&T) -> U f, &vec[T] v) -> vec[U] {
|
||||
let vec[U] res = alloc[U](len[T](v));
|
||||
for (T ve in v) {
|
||||
res += [f(ve)];
|
||||
|
@ -249,8 +249,8 @@ fn map[T, U](&fn(&T) -> U f, &array[T] v) -> vec[U] {
|
|||
ret res;
|
||||
}
|
||||
|
||||
fn filter_map[T, U](&fn(&T) -> option::t[U] f, &array[T] v) -> vec[U] {
|
||||
let vec[U] res = []; //TODO does this work these days?
|
||||
fn filter_map[T, U](&fn(&T) -> option::t[U] f, &vec[T] v) -> vec[U] {
|
||||
let vec[U] res = [];
|
||||
for(T ve in v) {
|
||||
alt(f(ve)) {
|
||||
case (some(?elt)) { res += [elt]; }
|
||||
|
@ -260,7 +260,7 @@ fn filter_map[T, U](&fn(&T) -> option::t[U] f, &array[T] v) -> vec[U] {
|
|||
ret res;
|
||||
}
|
||||
|
||||
fn map2[T,U,V](&operator2[T,U,V] f, &array[T] v0, &array[U] v1) -> vec[V] {
|
||||
fn map2[T,U,V](&operator2[T,U,V] f, &vec[T] v0, &vec[U] v1) -> vec[V] {
|
||||
auto v0_len = len[T](v0);
|
||||
if (v0_len != len[U](v1)) {
|
||||
fail;
|
||||
|
@ -269,14 +269,14 @@ fn map2[T,U,V](&operator2[T,U,V] f, &array[T] v0, &array[U] v1) -> vec[V] {
|
|||
let vec[V] u = alloc[V](v0_len);
|
||||
auto i = 0u;
|
||||
while (i < v0_len) {
|
||||
u += [f(v0.(i), v1.(i))];
|
||||
u += [f({v0.(i)}, {v1.(i)})];
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
ret u;
|
||||
}
|
||||
|
||||
fn find[T](fn (&T) -> bool f, &array[T] v) -> option::t[T] {
|
||||
fn find[T](fn (&T) -> bool f, &vec[T] v) -> option::t[T] {
|
||||
for (T elt in v) {
|
||||
if (f(elt)) {
|
||||
ret some[T](elt);
|
||||
|
|
Loading…
Reference in a new issue