Skip to content

Commit 55175ca

Browse files
committed
Auto merge of #379 - stepancheg:fix-all-info, r=Amanieu
Fix RawTable::allocation_info for empty table Fixes #376
2 parents 09dc17e + 471c5a6 commit 55175ca

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/raw/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
531531
#[inline]
532532
#[cfg(feature = "raw")]
533533
pub fn allocation_info(&self) -> (NonNull<u8>, Layout) {
534-
self.table.allocation_info(Self::TABLE_LAYOUT)
534+
self.table.allocation_info_or_zero(Self::TABLE_LAYOUT)
535535
}
536536

537537
/// Returns the index of a bucket from a `Bucket`.
@@ -1589,6 +1589,11 @@ impl<A: Allocator + Clone> RawTableInner<A> {
15891589

15901590
#[inline]
15911591
fn allocation_info(&self, table_layout: TableLayout) -> (NonNull<u8>, Layout) {
1592+
debug_assert!(
1593+
!self.is_empty_singleton(),
1594+
"this function can only be called on non-empty tables"
1595+
);
1596+
15921597
// Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
15931598
let (layout, ctrl_offset) = match table_layout.calculate_layout_for(self.buckets()) {
15941599
Some(lco) => lco,
@@ -1600,6 +1605,15 @@ impl<A: Allocator + Clone> RawTableInner<A> {
16001605
)
16011606
}
16021607

1608+
#[cfg(feature = "raw")]
1609+
fn allocation_info_or_zero(&self, table_layout: TableLayout) -> (NonNull<u8>, Layout) {
1610+
if self.is_empty_singleton() {
1611+
(NonNull::dangling(), Layout::new::<()>())
1612+
} else {
1613+
self.allocation_info(table_layout)
1614+
}
1615+
}
1616+
16031617
/// Marks all table buckets as empty without dropping their contents.
16041618
#[inline]
16051619
fn clear_no_drop(&mut self) {

tests/raw.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![cfg(feature = "raw")]
2+
3+
use hashbrown::raw::RawTable;
4+
use std::mem;
5+
6+
#[test]
7+
fn test_allocation_info() {
8+
assert_eq!(RawTable::<()>::new().allocation_info().1.size(), 0);
9+
assert_eq!(RawTable::<u32>::new().allocation_info().1.size(), 0);
10+
assert!(RawTable::<u32>::with_capacity(1).allocation_info().1.size() > mem::size_of::<u32>());
11+
}

0 commit comments

Comments
 (0)