Skip to content

Commit ebe35f3

Browse files
committed
remove borrowck workarounds from the containers
1 parent 4b6864f commit ebe35f3

File tree

2 files changed

+87
-6
lines changed

2 files changed

+87
-6
lines changed

src/libcore/hashmap.rs

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,16 +347,27 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
347347
}
348348
349349
/// Return a mutable reference to the value corresponding to the key
350+
#[cfg(stage0)]
350351
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
351352
let idx = match self.bucket_for_key(k) {
352353
FoundEntry(idx) => idx,
353354
TableFull | FoundHole(_) => return None
354355
};
355-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
356+
unsafe {
356357
Some(::cast::transmute_mut_region(self.mut_value_for_bucket(idx)))
357358
}
358359
}
359360
361+
/// Return a mutable reference to the value corresponding to the key
362+
#[cfg(not(stage0))]
363+
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
364+
let idx = match self.bucket_for_key(k) {
365+
FoundEntry(idx) => idx,
366+
TableFull | FoundHole(_) => return None
367+
};
368+
Some(self.mut_value_for_bucket(idx))
369+
}
370+
360371
/// Insert a key-value pair into the map. An existing value for a
361372
/// key is replaced by the new value. Return true if the key did
362373
/// not already exist in the map.
@@ -429,6 +440,7 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
429440
430441
/// Return the value corresponding to the key in the map, or insert
431442
/// and return the value if it doesn't exist.
443+
#[cfg(stage0)]
432444
fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
433445
if self.size >= self.resize_at {
434446
// n.b.: We could also do this after searching, so
@@ -452,13 +464,43 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
452464
},
453465
};
454466
455-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
467+
unsafe {
456468
::cast::transmute_region(self.value_for_bucket(idx))
457469
}
458470
}
459471
472+
/// Return the value corresponding to the key in the map, or insert
473+
/// and return the value if it doesn't exist.
474+
#[cfg(not(stage0))]
475+
fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
476+
if self.size >= self.resize_at {
477+
// n.b.: We could also do this after searching, so
478+
// that we do not resize if this call to insert is
479+
// simply going to update a key in place. My sense
480+
// though is that it's worse to have to search through
481+
// buckets to find the right spot twice than to just
482+
// resize in this corner case.
483+
self.expand();
484+
}
485+
486+
let hash = k.hash_keyed(self.k0, self.k1) as uint;
487+
let idx = match self.bucket_for_key_with_hash(hash, &k) {
488+
TableFull => fail!(~"Internal logic error"),
489+
FoundEntry(idx) => idx,
490+
FoundHole(idx) => {
491+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
492+
value: v});
493+
self.size += 1;
494+
idx
495+
},
496+
};
497+
498+
self.value_for_bucket(idx)
499+
}
500+
460501
/// Return the value corresponding to the key in the map, or create,
461502
/// insert, and return a new value if it doesn't exist.
503+
#[cfg(stage0)]
462504
fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
463505
if self.size >= self.resize_at {
464506
// n.b.: We could also do this after searching, so
@@ -483,11 +525,41 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
483525
},
484526
};
485527
486-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
528+
unsafe {
487529
::cast::transmute_region(self.value_for_bucket(idx))
488530
}
489531
}
490532
533+
/// Return the value corresponding to the key in the map, or create,
534+
/// insert, and return a new value if it doesn't exist.
535+
#[cfg(not(stage0))]
536+
fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
537+
if self.size >= self.resize_at {
538+
// n.b.: We could also do this after searching, so
539+
// that we do not resize if this call to insert is
540+
// simply going to update a key in place. My sense
541+
// though is that it's worse to have to search through
542+
// buckets to find the right spot twice than to just
543+
// resize in this corner case.
544+
self.expand();
545+
}
546+
547+
let hash = k.hash_keyed(self.k0, self.k1) as uint;
548+
let idx = match self.bucket_for_key_with_hash(hash, &k) {
549+
TableFull => fail!(~"Internal logic error"),
550+
FoundEntry(idx) => idx,
551+
FoundHole(idx) => {
552+
let v = f(&k);
553+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
554+
value: v});
555+
self.size += 1;
556+
idx
557+
},
558+
};
559+
560+
self.value_for_bucket(idx)
561+
}
562+
491563
fn consume(&mut self, f: &fn(K, V)) {
492564
let mut buckets = ~[];
493565
self.buckets <-> buckets;

src/libcore/trie.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,9 @@ fn chunk(n: uint, idx: uint) -> uint {
276276
(n >> sh) & MASK
277277
}
278278

279-
fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint)
280-
-> Option<&'r mut T> {
281-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
279+
#[cfg(stage0)]
280+
fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r mut T> {
281+
unsafe {
282282
(match *child {
283283
External(_, ref value) => Some(cast::transmute_mut(value)),
284284
Internal(ref x) => find_mut(cast::transmute_mut(&x.children[chunk(key, idx)]),
@@ -288,6 +288,15 @@ fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint)
288288
}
289289
}
290290

291+
#[cfg(not(stage0))]
292+
fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r mut T> {
293+
match *child {
294+
External(_, ref mut value) => Some(value),
295+
Internal(ref mut x) => find_mut(&mut x.children[chunk(key, idx)], key, idx + 1),
296+
Nothing => None
297+
}
298+
}
299+
291300
fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
292301
idx: uint) -> bool {
293302
let mut tmp = Nothing;

0 commit comments

Comments
 (0)