@@ -15,6 +15,7 @@ use mem::{size_of, needs_drop};
15
15
use mem;
16
16
use ops:: { Deref , DerefMut } ;
17
17
use ptr:: { self , Unique , NonNull } ;
18
+ use hint;
18
19
19
20
use self :: BucketState :: * ;
20
21
@@ -655,7 +656,17 @@ impl<K, V, M> GapThenFull<K, V, M>
655
656
fn calculate_layout < K , V > ( capacity : usize ) -> Result < ( Layout , usize ) , LayoutErr > {
656
657
let hashes = Layout :: array :: < HashUint > ( capacity) ?;
657
658
let pairs = Layout :: array :: < ( K , V ) > ( capacity) ?;
658
- hashes. extend ( pairs)
659
+ hashes. extend ( pairs) . map ( |( layout, _) | {
660
+ // LLVM seems to have trouble properly const-propagating pairs.align(),
661
+ // possibly due to the use of NonZeroUsize. This little hack allows it
662
+ // to generate optimal code.
663
+ //
664
+ // See https://github.com/rust-lang/rust/issues/51346 for more details.
665
+ (
666
+ layout,
667
+ hashes. size ( ) + hashes. padding_needed_for ( mem:: align_of :: < ( K , V ) > ( ) ) ,
668
+ )
669
+ } )
659
670
}
660
671
661
672
pub ( crate ) enum Fallibility {
@@ -711,7 +722,8 @@ impl<K, V> RawTable<K, V> {
711
722
}
712
723
713
724
fn raw_bucket_at ( & self , index : usize ) -> RawBucket < K , V > {
714
- let ( _, pairs_offset) = calculate_layout :: < K , V > ( self . capacity ( ) ) . unwrap ( ) ;
725
+ let ( _, pairs_offset) = calculate_layout :: < K , V > ( self . capacity ( ) )
726
+ . unwrap_or_else ( |_| unsafe { hint:: unreachable_unchecked ( ) } ) ;
715
727
let buffer = self . hashes . ptr ( ) as * mut u8 ;
716
728
unsafe {
717
729
RawBucket {
@@ -1109,7 +1121,8 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
1109
1121
}
1110
1122
}
1111
1123
1112
- let ( layout, _) = calculate_layout :: < K , V > ( self . capacity ( ) ) . unwrap ( ) ;
1124
+ let ( layout, _) = calculate_layout :: < K , V > ( self . capacity ( ) )
1125
+ . unwrap_or_else ( |_| unsafe { hint:: unreachable_unchecked ( ) } ) ;
1113
1126
unsafe {
1114
1127
Global . dealloc ( NonNull :: new_unchecked ( self . hashes . ptr ( ) ) . as_opaque ( ) , layout) ;
1115
1128
// Remember how everything was allocated out of one buffer
0 commit comments