Skip to content

Commit 77c1b96

Browse files
committed
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
1 parent bd90c7a commit 77c1b96

File tree

5 files changed

+27
-20
lines changed

5 files changed

+27
-20
lines changed

src/comp/back/link.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ fn crate_meta_extras_hash(sha1 sha, &ast::crate crate) -> str {
339339
}
340340
sort::quick_sort(lteq, v);
341341
sha.reset();
342-
for (@ast::meta_item m in v) {
342+
for (@ast::meta_item m_ in v) {
343+
auto m = m_;
343344
sha.input_str(len_and_str(m.node.name));
344345
sha.input_str(len_and_str(m.node.value));
345346
}

src/lib/map.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,10 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
7676
let uint j = hash(h, nbkts, i);
7777
alt (bkts.(j)) {
7878
case (some(?k, _)) {
79-
if (eqer(key, k)) {
80-
bkts.(j) = some[K, V](k, val);
79+
// Copy key to please alias analysis.
80+
auto k_ = k;
81+
if (eqer(key, k_)) {
82+
bkts.(j) = some[K, V](k_, val);
8183
ret false;
8284
}
8385
i += 1u;
@@ -104,8 +106,11 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
104106
let uint j = (hash(h, nbkts, i));
105107
alt (bkts.(j)) {
106108
case (some(?k, ?v)) {
107-
if (eqer(key, k)) {
108-
ret option::some[V](v);
109+
// Copy to please alias analysis.
110+
auto k_ = k;
111+
auto v_ = v;
112+
if (eqer(key, k_)) {
113+
ret option::some[V](v_);
109114
}
110115
}
111116
case (nil) {
@@ -190,10 +195,11 @@ fn mk_hashmap[K, V](&hashfn[K] hasher, &eqfn[K] eqer) -> hashmap[K, V] {
190195
let uint j = (hash(h, nbkts, i));
191196
alt (bkts.(j)) {
192197
case (some(?k, ?v)) {
193-
if (eqer(key, k)) {
198+
auto k_ = k; auto vo = option::some(v);
199+
if (eqer(key, k_)) {
194200
bkts.(j) = deleted[K, V];
195201
nelts -= 1u;
196-
ret option::some[V](v);
202+
ret vo;
197203
}
198204
}
199205
case (deleted) { }

src/lib/sort.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn part[T](lteq[T] compare_func, vec[mutable T] arr, uint left,
5858
let uint storage_index = left;
5959
let uint i = left;
6060
while (i<right) {
61-
if (compare_func(arr.(i), pivot_value)) {
61+
if (compare_func({arr.(i)}, pivot_value)) {
6262
swap[T](arr, i, storage_index);
6363
storage_index += 1u;
6464
}
@@ -97,7 +97,7 @@ fn quick_sort[T](lteq[T] compare_func, vec[mutable T] arr) {
9797
// 'randomly ordered keys, abstract compare' & 'small number of key values'
9898

9999
fn qsort3[T](lteq[T] compare_func_lt, lteq[T] compare_func_eq,
100-
vec[mutable T] arr, int left, int right) {
100+
vec[mutable T] arr, int left, int right) {
101101

102102
if (right <= left) {
103103
ret;
@@ -111,11 +111,11 @@ fn qsort3[T](lteq[T] compare_func_lt, lteq[T] compare_func_eq,
111111

112112
while (true) {
113113
i += 1;
114-
while (compare_func_lt(arr.(i), v)) {
114+
while (compare_func_lt({arr.(i)}, v)) {
115115
i += 1;
116116
}
117117
j -= 1;
118-
while (compare_func_lt(v, arr.(j))) {
118+
while (compare_func_lt(v, {arr.(j)})) {
119119
if (j == left) {
120120
break;
121121
}
@@ -125,11 +125,11 @@ fn qsort3[T](lteq[T] compare_func_lt, lteq[T] compare_func_eq,
125125
break;
126126
}
127127
swap[T](arr, i as uint, j as uint);
128-
if (compare_func_eq(arr.(i), v)) {
128+
if (compare_func_eq({arr.(i)}, v)) {
129129
p += 1;
130130
swap[T](arr, p as uint, i as uint);
131131
}
132-
if (compare_func_eq(v, arr.(j))) {
132+
if (compare_func_eq(v, {arr.(j)})) {
133133
q -= 1;
134134
swap[T](arr, j as uint, q as uint);
135135
}

src/lib/ufind.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn grow(&ufind ufnd, uint n) {
2929
fn find(&ufind ufnd, uint n) -> uint {
3030
alt (ufnd.nodes.(n)) {
3131
case (none) { ret n; }
32-
case (some(?m)) { be find(ufnd, m); }
32+
case (some(?m)) { auto m_ = m; be find(ufnd, m_); }
3333
}
3434
}
3535

src/lib/vec.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,16 @@ fn grow_init_fn_set[T](&array[T] v, uint index, fn()->T init_fn, &T val) {
241241
}
242242

243243

244-
fn map[T, U](&fn(&T) -> U f, &array[T] v) -> vec[U] {
244+
fn map[T, U](&fn(&T) -> U f, &vec[T] v) -> vec[U] {
245245
let vec[U] res = alloc[U](len[T](v));
246246
for (T ve in v) {
247247
res += [f(ve)];
248248
}
249249
ret res;
250250
}
251251

252-
fn filter_map[T, U](&fn(&T) -> option::t[U] f, &array[T] v) -> vec[U] {
253-
let vec[U] res = []; //TODO does this work these days?
252+
fn filter_map[T, U](&fn(&T) -> option::t[U] f, &vec[T] v) -> vec[U] {
253+
let vec[U] res = [];
254254
for(T ve in v) {
255255
alt(f(ve)) {
256256
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] {
260260
ret res;
261261
}
262262

263-
fn map2[T,U,V](&operator2[T,U,V] f, &array[T] v0, &array[U] v1) -> vec[V] {
263+
fn map2[T,U,V](&operator2[T,U,V] f, &vec[T] v0, &vec[U] v1) -> vec[V] {
264264
auto v0_len = len[T](v0);
265265
if (v0_len != len[U](v1)) {
266266
fail;
@@ -269,14 +269,14 @@ fn map2[T,U,V](&operator2[T,U,V] f, &array[T] v0, &array[U] v1) -> vec[V] {
269269
let vec[V] u = alloc[V](v0_len);
270270
auto i = 0u;
271271
while (i < v0_len) {
272-
u += [f(v0.(i), v1.(i))];
272+
u += [f({v0.(i)}, {v1.(i)})];
273273
i += 1u;
274274
}
275275

276276
ret u;
277277
}
278278

279-
fn find[T](fn (&T) -> bool f, &array[T] v) -> option::t[T] {
279+
fn find[T](fn (&T) -> bool f, &vec[T] v) -> option::t[T] {
280280
for (T elt in v) {
281281
if (f(elt)) {
282282
ret some[T](elt);

0 commit comments

Comments
 (0)