Skip to content

Commit b1e720f

Browse files
committed
Make HashMap::take not corrupt the map. Fixes #19292
1 parent 4389ee3 commit b1e720f

File tree

1 file changed

+35
-1
lines changed
  • src/libstd/collections/hash

1 file changed

+35
-1
lines changed

src/libstd/collections/hash/map.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,7 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
13761376

13771377
/// Takes the value out of the entry, and returns it
13781378
pub fn take(self) -> V {
1379-
let (_, _, v) = self.elem.take();
1379+
let (_, v) = pop_internal(self.elem);
13801380
v
13811381
}
13821382
}
@@ -1433,6 +1433,7 @@ mod test_map {
14331433
use hash;
14341434
use iter::{Iterator,range_inclusive,range_step_inclusive};
14351435
use cell::RefCell;
1436+
use rand::{weak_rng, Rng};
14361437

14371438
struct KindaIntLike(int);
14381439

@@ -2062,4 +2063,37 @@ mod test_map {
20622063
assert_eq!(map.get(&10).unwrap(), &1000);
20632064
assert_eq!(map.len(), 6);
20642065
}
2066+
2067+
#[test]
2068+
fn test_entry_take_doesnt_corrupt() {
2069+
// Test for #19292
2070+
fn check(m: &HashMap<int, ()>) {
2071+
for k in m.keys() {
2072+
assert!(m.contains_key(k),
2073+
"{} is in keys() but not in the map?", k);
2074+
}
2075+
}
2076+
2077+
let mut m = HashMap::new();
2078+
let mut rng = weak_rng();
2079+
2080+
// Populate the map with some items.
2081+
for _ in range(0u, 50) {
2082+
let x = rng.gen_range(-10, 10);
2083+
m.insert(x, ());
2084+
}
2085+
2086+
for i in range(0u, 1000) {
2087+
let x = rng.gen_range(-10, 10);
2088+
match m.entry(x) {
2089+
Vacant(_) => {},
2090+
Occupied(e) => {
2091+
println!("{}: remove {}", i, x);
2092+
e.take();
2093+
},
2094+
}
2095+
2096+
check(&m);
2097+
}
2098+
}
20652099
}

0 commit comments

Comments
 (0)