@@ -4,7 +4,7 @@ use core::alloc::LayoutError;
4
4
use core:: cmp;
5
5
use core:: hint;
6
6
use core:: mem:: { self , ManuallyDrop , MaybeUninit , SizedTypeProperties } ;
7
- use core:: ptr:: { self , Alignment , NonNull , Unique } ;
7
+ use core:: ptr:: { self , NonNull , Unique } ;
8
8
9
9
#[ cfg( not( no_global_oom_handling) ) ]
10
10
use crate :: alloc:: handle_alloc_error;
@@ -297,7 +297,20 @@ impl<T, A: Allocator> RawVec<T, A> {
297
297
}
298
298
299
299
fn current_memory ( & self ) -> Option < ( NonNull < u8 > , Layout ) > {
300
- if T :: IS_ZST || self . cap . 0 == 0 {
300
+ // Reduce the amount of code we need to monomorphize per `T`.
301
+ #[ inline]
302
+ #[ rustc_no_mir_inline]
303
+ unsafe fn inner ( size : usize , align : usize , cap : usize ) -> Layout {
304
+ // SAFETY: Precondition guaranteed by the caller
305
+ unsafe {
306
+ let size = size. unchecked_mul ( cap) ;
307
+ Layout :: from_size_align_unchecked ( size, align)
308
+ }
309
+ }
310
+
311
+ let cap = self . cap . 0 ;
312
+
313
+ if T :: IS_ZST || cap == 0 {
301
314
None
302
315
} else {
303
316
// We could use Layout::array here which ensures the absence of isize and usize overflows
@@ -306,10 +319,8 @@ impl<T, A: Allocator> RawVec<T, A> {
306
319
// support such types. So we can do better by skipping some checks and avoid an unwrap.
307
320
const { assert ! ( mem:: size_of:: <T >( ) % mem:: align_of:: <T >( ) == 0 ) } ;
308
321
unsafe {
309
- let align = Alignment :: of :: < T > ( ) ;
310
- let size = mem:: size_of :: < T > ( ) . unchecked_mul ( self . cap . 0 ) ;
311
- let layout = Layout :: from_size_alignment ( size, align) . unwrap_unchecked ( ) ;
312
- Some ( ( self . ptr . cast ( ) . into ( ) , layout) )
322
+ let layout = inner ( mem:: size_of :: < T > ( ) , mem:: align_of :: < T > ( ) , cap) ;
323
+ Some ( ( self . non_null ( ) . cast ( ) , layout) )
313
324
}
314
325
}
315
326
}
0 commit comments