@@ -15,6 +15,7 @@ use mem::{size_of, needs_drop};
1515use mem;
1616use ops:: { Deref , DerefMut } ;
1717use ptr:: { self , Unique , NonNull } ;
18+ use hint;
1819
1920use self :: BucketState :: * ;
2021
@@ -655,7 +656,17 @@ impl<K, V, M> GapThenFull<K, V, M>
655656fn calculate_layout < K , V > ( capacity : usize ) -> Result < ( Layout , usize ) , LayoutErr > {
656657 let hashes = Layout :: array :: < HashUint > ( capacity) ?;
657658 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+ } )
659670}
660671
661672pub ( crate ) enum Fallibility {
@@ -711,7 +722,8 @@ impl<K, V> RawTable<K, V> {
711722 }
712723
713724 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 ( ) } ) ;
715727 let buffer = self . hashes . ptr ( ) as * mut u8 ;
716728 unsafe {
717729 RawBucket {
@@ -1109,7 +1121,8 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
11091121 }
11101122 }
11111123
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 ( ) } ) ;
11131126 unsafe {
11141127 Global . dealloc ( NonNull :: new_unchecked ( self . hashes . ptr ( ) ) . as_opaque ( ) , layout) ;
11151128 // Remember how everything was allocated out of one buffer
0 commit comments