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:
Marijn Haverbeke 2011-06-09 09:30:46 +02:00
parent bd90c7a3cb
commit 77c1b9650f
5 changed files with 27 additions and 20 deletions

View file

@ -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));
}

View file

@ -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) { }

View file

@ -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);
}

View file

@ -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_); }
}
}

View file

@ -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);