From 77c1b9650f055932bcad5983b9847517eba6c516 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 9 Jun 2011 09:30:46 +0200 Subject: [PATCH] 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 --- src/comp/back/link.rs | 3 ++- src/lib/map.rs | 18 ++++++++++++------ src/lib/sort.rs | 12 ++++++------ src/lib/ufind.rs | 2 +- src/lib/vec.rs | 12 ++++++------ 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index b637b7e41b8..81c0f5a265a 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -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)); } diff --git a/src/lib/map.rs b/src/lib/map.rs index 3b7f01acbe1..396835bc1d6 100644 --- a/src/lib/map.rs +++ b/src/lib/map.rs @@ -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) { } diff --git a/src/lib/sort.rs b/src/lib/sort.rs index ede8d229fa5..8a16c1858be 100644 --- a/src/lib/sort.rs +++ b/src/lib/sort.rs @@ -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 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_); } } } diff --git a/src/lib/vec.rs b/src/lib/vec.rs index 2f82f330446..3cc4db83b54 100644 --- a/src/lib/vec.rs +++ b/src/lib/vec.rs @@ -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);