@@ -4,7 +4,7 @@ use core::alloc::LayoutError;
44use core:: cmp;
55use core:: hint;
66use core:: mem:: { self , ManuallyDrop , MaybeUninit , SizedTypeProperties } ;
7- use core:: ptr:: { self , Alignment , NonNull , Unique } ;
7+ use core:: ptr:: { self , NonNull , Unique } ;
88
99#[ cfg( not( no_global_oom_handling) ) ]
1010use crate :: alloc:: handle_alloc_error;
@@ -297,7 +297,20 @@ impl<T, A: Allocator> RawVec<T, A> {
297297 }
298298
299299 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 {
301314 None
302315 } else {
303316 // 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> {
306319 // support such types. So we can do better by skipping some checks and avoid an unwrap.
307320 const { assert ! ( mem:: size_of:: <T >( ) % mem:: align_of:: <T >( ) == 0 ) } ;
308321 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) )
313324 }
314325 }
315326 }
0 commit comments