Skip to content

Commit aea2c58

Browse files
committed
fixes
1 parent 68ebd49 commit aea2c58

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

src/libstd/collections/hash/map.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ impl<K, V, S, H> HashMap<K, V, S>
10041004
reason = "matches collection reform specification, waiting for dust to settle")]
10051005
pub fn drain(&mut self) -> Drain<K, V> {
10061006
Drain {
1007-
inner: Bucket::at_index(&mut self.table, 0).unwrap()
1007+
inner: Bucket::at_index(&mut self.table, 0)
10081008
}
10091009
}
10101010

@@ -1295,7 +1295,7 @@ impl<'a, K, V> Clone for Values<'a, K, V> {
12951295
#[unstable(feature = "std_misc",
12961296
reason = "matches collection reform specification, waiting for dust to settle")]
12971297
pub struct Drain<'a, K: 'a, V: 'a> {
1298-
inner: table::Bucket<K, V, &'a mut RawTable<K, V>>,
1298+
inner: Option<table::Bucket<K, V, &'a mut RawTable<K, V>>>,
12991299
}
13001300

13011301
/// A view into a single occupied location in a HashMap.
@@ -1469,26 +1469,30 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
14691469
type Item = (K, V);
14701470

14711471
fn next(&mut self) -> Option<(K, V)> {
1472-
let cap = self.inner.table().capacity();
1473-
while self.inner.index() < cap {
1474-
if let Some(kv_pair) = self.inner.peek_take() {
1475-
return Some(kv_pair);
1472+
if let Some(ref mut bucket) = self.inner {
1473+
let cap = bucket.table().capacity();
1474+
while bucket.index() < cap {
1475+
if let Some(kv_pair) = bucket.peek_take() {
1476+
return Some(kv_pair);
1477+
}
1478+
bucket.next();
14761479
}
1477-
self.inner.next();
14781480
}
14791481

14801482
None
14811483
}
14821484

14831485
fn size_hint(&self) -> (usize, Option<usize>) {
1484-
let size = self.inner.table().size();
1485-
(size, Some(size))
1486+
self.inner.as_ref().map(|bucket| {
1487+
let size = bucket.table().size();
1488+
(size, Some(size))
1489+
}).unwrap_or((0, Some(0)))
14861490
}
14871491
}
14881492

14891493
#[stable(feature = "rust1", since = "1.0.0")]
14901494
impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
1491-
fn len(&self) -> usize { self.inner.table().size() }
1495+
fn len(&self) -> usize { self.inner.as_ref().map(|bucket| bucket.table().size()).unwrap_or(0) }
14921496
}
14931497

14941498
#[unsafe_destructor]
@@ -1879,14 +1883,14 @@ mod test_map {
18791883
#[test]
18801884
fn test_empty_entry() {
18811885
let mut m: HashMap<int, bool> = HashMap::new();
1882-
assert!(m.entry(0).is_err());
1886+
assert!(m.entry(0).get().is_err());
18831887
assert!(*m.entry(0).get().unwrap_or_else(|e| e.insert(true)));
18841888
assert_eq!(m.len(), 1);
18851889
}
18861890

18871891
#[test]
18881892
fn test_empty_iter() {
1889-
let m: HashMap<int, bool> = HashMap::new();
1893+
let mut m: HashMap<int, bool> = HashMap::new();
18901894
assert_eq!(m.drain().next(), None);
18911895
assert_eq!(m.keys().next(), None);
18921896
assert_eq!(m.values().next(), None);

src/libstd/collections/hash/table.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,18 @@ impl<K, V> RawTable<K, V> {
462462

463463
#[inline]
464464
fn first_bucket_raw<M>(&self) -> RawBucket<K, V, M> {
465-
RawBucket {
466-
hash: self.middle.0 as *mut Option<SafeHash>,
467-
kval: unsafe {
468-
self.middle.0.offset(-(self.capacity as isize))
469-
},
465+
if self.capacity() == 0 {
466+
RawBucket {
467+
hash: ptr::null_mut(),
468+
kval: ptr::null_mut(),
469+
}
470+
} else {
471+
RawBucket {
472+
hash: self.middle.0 as *mut Option<SafeHash>,
473+
kval: unsafe {
474+
self.middle.0.offset(-(self.capacity as isize))
475+
},
476+
}
470477
}
471478
}
472479

@@ -567,6 +574,7 @@ fn test_rounding() {
567574
assert_eq!(round_up_to_next(3, 4), 4);
568575
assert_eq!(round_up_to_next(4, 4), 4);
569576
assert_eq!(round_up_to_next(5, 4), 8);
577+
assert_eq!(round_up_to_next(5, 8), 8);
570578
}
571579

572580
#[inline]

0 commit comments

Comments
 (0)