Skip to content

Commit 4e39290

Browse files
committed
Make TableLayout::new::<T>() and mem::needs_drop::<T>() const
1 parent f3fa266 commit 4e39290

File tree

1 file changed

+25
-25
lines changed

1 file changed

+25
-25
lines changed

src/raw/mod.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,15 @@ struct TableLayout {
237237

238238
impl TableLayout {
239239
#[inline]
240-
fn new<T>() -> Self {
240+
const fn new<T>() -> Self {
241241
let layout = Layout::new::<T>();
242242
Self {
243243
size: layout.size(),
244-
ctrl_align: usize::max(layout.align(), Group::WIDTH),
244+
ctrl_align: if layout.align() > Group::WIDTH {
245+
layout.align()
246+
} else {
247+
Group::WIDTH
248+
},
245249
}
246250
}
247251

@@ -268,16 +272,6 @@ impl TableLayout {
268272
}
269273
}
270274

271-
/// Returns a Layout which describes the allocation required for a hash table,
272-
/// and the offset of the control bytes in the allocation.
273-
/// (the offset is also one past last element of buckets)
274-
///
275-
/// Returns `None` if an overflow occurs.
276-
#[cfg_attr(feature = "inline-more", inline)]
277-
fn calculate_layout<T>(buckets: usize) -> Option<(Layout, usize)> {
278-
TableLayout::new::<T>().calculate_layout_for(buckets)
279-
}
280-
281275
/// A reference to a hash table bucket containing a `T`.
282276
///
283277
/// This is usually just a pointer to the element itself. However if the element
@@ -428,6 +422,9 @@ impl<T> RawTable<T, Global> {
428422
}
429423

430424
impl<T, A: Allocator + Clone> RawTable<T, A> {
425+
const TABLE_LAYOUT: TableLayout = TableLayout::new::<T>();
426+
const DATA_NEEDS_DROP: bool = mem::needs_drop::<T>();
427+
431428
/// Creates a new empty hash table without allocating any memory, using the
432429
/// given allocator.
433430
///
@@ -456,7 +453,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
456453
Ok(Self {
457454
table: RawTableInner::new_uninitialized(
458455
alloc,
459-
TableLayout::new::<T>(),
456+
Self::TABLE_LAYOUT,
460457
buckets,
461458
fallibility,
462459
)?,
@@ -474,7 +471,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
474471
Ok(Self {
475472
table: RawTableInner::fallible_with_capacity(
476473
alloc,
477-
TableLayout::new::<T>(),
474+
Self::TABLE_LAYOUT,
478475
capacity,
479476
fallibility,
480477
)?,
@@ -508,7 +505,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
508505
/// Deallocates the table without dropping any entries.
509506
#[cfg_attr(feature = "inline-more", inline)]
510507
unsafe fn free_buckets(&mut self) {
511-
self.table.free_buckets(TableLayout::new::<T>());
508+
self.table.free_buckets(Self::TABLE_LAYOUT);
512509
}
513510

514511
/// Returns pointer to one past last element of data table.
@@ -608,7 +605,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
608605
}
609606

610607
unsafe fn drop_elements(&mut self) {
611-
if mem::needs_drop::<T>() && !self.is_empty() {
608+
if Self::DATA_NEEDS_DROP && !self.is_empty() {
612609
for item in self.iter() {
613610
item.drop();
614611
}
@@ -696,8 +693,8 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
696693
additional,
697694
&|table, index| hasher(table.bucket::<T>(index).as_ref()),
698695
fallibility,
699-
TableLayout::new::<T>(),
700-
if mem::needs_drop::<T>() {
696+
Self::TABLE_LAYOUT,
697+
if Self::DATA_NEEDS_DROP {
701698
Some(mem::transmute(ptr::drop_in_place::<T> as unsafe fn(*mut T)))
702699
} else {
703700
None
@@ -719,7 +716,7 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
719716
capacity,
720717
&|table, index| hasher(table.bucket::<T>(index).as_ref()),
721718
fallibility,
722-
TableLayout::new::<T>(),
719+
Self::TABLE_LAYOUT,
723720
)
724721
}
725722
}
@@ -1036,10 +1033,11 @@ impl<T, A: Allocator + Clone> RawTable<T, A> {
10361033
None
10371034
} else {
10381035
// Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
1039-
let (layout, ctrl_offset) = match calculate_layout::<T>(self.table.buckets()) {
1040-
Some(lco) => lco,
1041-
None => unsafe { hint::unreachable_unchecked() },
1042-
};
1036+
let (layout, ctrl_offset) =
1037+
match Self::TABLE_LAYOUT.calculate_layout_for(self.table.buckets()) {
1038+
Some(lco) => lco,
1039+
None => unsafe { hint::unreachable_unchecked() },
1040+
};
10431041
Some((
10441042
unsafe { NonNull::new_unchecked(self.table.ctrl.as_ptr().sub(ctrl_offset)) },
10451043
layout,
@@ -1748,7 +1746,7 @@ impl<T: Clone, A: Allocator + Clone> RawTable<T, A> {
17481746
// to make sure we drop only the elements that have been
17491747
// cloned so far.
17501748
let mut guard = guard((0, &mut *self), |(index, self_)| {
1751-
if mem::needs_drop::<T>() && !self_.is_empty() {
1749+
if Self::DATA_NEEDS_DROP && !self_.is_empty() {
17521750
for i in 0..=*index {
17531751
if self_.is_bucket_full(i) {
17541752
self_.bucket(i).drop();
@@ -2036,6 +2034,8 @@ pub struct RawIter<T> {
20362034
}
20372035

20382036
impl<T> RawIter<T> {
2037+
const DATA_NEEDS_DROP: bool = mem::needs_drop::<T>();
2038+
20392039
/// Refresh the iterator so that it reflects a removal from the given bucket.
20402040
///
20412041
/// For the iterator to remain valid, this method must be called once
@@ -2153,7 +2153,7 @@ impl<T> RawIter<T> {
21532153
}
21542154

21552155
unsafe fn drop_elements(&mut self) {
2156-
if mem::needs_drop::<T>() && self.len() != 0 {
2156+
if Self::DATA_NEEDS_DROP && self.len() != 0 {
21572157
for item in self {
21582158
item.drop();
21592159
}

0 commit comments

Comments
 (0)