@@ -237,11 +237,15 @@ struct TableLayout {
237237
238238impl 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
430424impl < 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
20382036impl < 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