@@ -14,7 +14,7 @@ use core::ptr::NonNull;
1414
1515impl < A : Meta > DangleZst < A > {
1616 // TODO: replace with NonNull::new when that stabilizes as a const fn
17- const DANGLE : NonNull < MaybeUninit < u8 > > = unsafe { NonNull :: new_unchecked ( A :: MAX_ALIGN . as_usize ( ) as _ ) } ;
17+ const DANGLE : NonNull < MaybeUninit < u8 > > = match crate :: util :: nn :: from_usize ( A :: MAX_ALIGN . as_usize ( ) ) { Some ( nn ) => nn , None => panic ! ( "could not convert A::MAX_ALIGN to a NonNull" ) } ;
1818}
1919
2020impl < A > core:: ops:: Deref for DangleZst < A > { fn deref ( & self ) -> & Self :: Target { & self . 0 } type Target = A ; }
@@ -71,7 +71,21 @@ unsafe impl<A: thin::Realloc> thin::Realloc for DangleZst<A> {
7171 unsafe fn realloc_zeroed ( & self , ptr : NonNull < MaybeUninit < u8 > > , new_size : usize ) -> Result < NonNull < MaybeUninit < u8 > > , Self :: Error > {
7272 if ptr == Self :: DANGLE { return self . 0 . alloc_zeroed ( new_size) . map ( |a| a. cast ( ) ) }
7373 if new_size == 0 { unsafe { self . 0 . free ( ptr) } ; return Ok ( Self :: DANGLE ) }
74- unsafe { self . 0 . realloc_uninit ( ptr, new_size) }
74+ unsafe { self . 0 . realloc_zeroed ( ptr, new_size) }
75+ }
76+ }
77+
78+ unsafe impl < A : thin:: SizeOf > thin:: SizeOf for DangleZst < A > {
79+ unsafe fn size_of ( & self , ptr : NonNull < MaybeUninit < u8 > > ) -> usize {
80+ if ptr == Self :: DANGLE { return 0 }
81+ unsafe { self . 0 . size_of ( ptr) }
82+ }
83+ }
84+
85+ unsafe impl < A : thin:: SizeOfDebug > thin:: SizeOfDebug for DangleZst < A > {
86+ unsafe fn size_of_debug ( & self , ptr : NonNull < MaybeUninit < u8 > > ) -> Option < usize > {
87+ if ptr == Self :: DANGLE { return Some ( 0 ) }
88+ unsafe { self . 0 . size_of_debug ( ptr) }
7589 }
7690}
7791
@@ -114,42 +128,44 @@ unsafe impl<A: fat::Free> fat::Free for DangleZst<A> {
114128
115129unsafe impl < A : fat:: Realloc > fat:: Realloc for DangleZst < A > {
116130 unsafe fn realloc_uninit ( & self , ptr : NonNull < MaybeUninit < u8 > > , old_layout : Layout , new_layout : Layout ) -> Result < NonNull < MaybeUninit < u8 > > , Self :: Error > {
117- if old_layout. size ( ) > 0 && new_layout. size ( ) > 0 {
118- unsafe { self . 0 . realloc_uninit ( ptr, old_layout, new_layout) }
119- } else {
120- if cfg ! ( debug_assertions) && old_layout. size ( ) == 0 {
121- if ptr != Self :: DANGLE { bug:: ub:: invalid_ptr_for_allocator ( ptr) }
122- if old_layout. align ( ) > A :: MAX_ALIGN . as_usize ( ) { bug:: ub:: invalid_free_align_for_allocator ( old_layout. align ( ) ) }
123- }
124- let alloc = self . alloc_uninit ( new_layout) ?;
125- let n = old_layout. size ( ) . min ( new_layout. size ( ) ) ;
126- {
127- let src : & [ MaybeUninit < u8 > ] = unsafe { core:: slice:: from_raw_parts ( ptr . as_ptr ( ) , n) } ;
128- let dst : & mut [ MaybeUninit < u8 > ] = unsafe { core:: slice:: from_raw_parts_mut ( alloc. as_ptr ( ) , n) } ;
129- dst. copy_from_slice ( src) ;
130- }
131- unsafe { self . free ( ptr, old_layout) } ;
132- Ok ( alloc)
131+ let old_zst = old_layout. size ( ) == 0 ;
132+ let new_zst = new_layout. size ( ) == 0 ;
133+
134+ if old_zst && cfg ! ( debug_assertions) {
135+ if ptr != Self :: DANGLE { bug:: ub:: invalid_ptr_for_allocator ( ptr) }
136+ if old_layout. align ( ) > A :: MAX_ALIGN . as_usize ( ) { bug:: ub:: invalid_free_align_for_allocator ( old_layout. align ( ) ) }
137+ }
138+
139+ if new_zst && new_layout. align ( ) > A :: MAX_ALIGN . as_usize ( ) {
140+ return Err ( ExcessiveAlignmentRequestedError { requested : new_layout. into ( ) , supported : A :: MAX_ALIGN } . into ( ) )
141+ }
142+
143+ match ( old_zst, new_zst) {
144+ ( false , false ) => unsafe { self . 0 . realloc_uninit ( ptr, old_layout, new_layout) } ,
145+ ( false , true ) => unsafe { self . 0 . free ( ptr, old_layout) ; Ok ( Self :: DANGLE . cast ( ) ) } ,
146+ ( true , false ) => { self . 0 . alloc_uninit ( new_layout) } ,
147+ ( true , true ) => { Ok ( Self :: DANGLE . cast ( ) ) } ,
133148 }
134149 }
135150
136151 unsafe fn realloc_zeroed ( & self , ptr : NonNull < MaybeUninit < u8 > > , old_layout : Layout , new_layout : Layout ) -> Result < NonNull < MaybeUninit < u8 > > , Self :: Error > {
137- if old_layout. size ( ) > 0 && new_layout. size ( ) > 0 {
138- unsafe { self . 0 . realloc_zeroed ( ptr, old_layout, new_layout) }
139- } else {
140- if cfg ! ( debug_assertions) && old_layout. size ( ) == 0 {
141- if ptr != Self :: DANGLE { bug:: ub:: invalid_ptr_for_allocator ( ptr) }
142- if old_layout. align ( ) > A :: MAX_ALIGN . as_usize ( ) { bug:: ub:: invalid_free_align_for_allocator ( old_layout. align ( ) ) }
143- }
144- let alloc = self . alloc_zeroed ( new_layout) ?. cast ( ) ;
145- let n = old_layout. size ( ) . min ( new_layout. size ( ) ) ;
146- {
147- let src : & [ MaybeUninit < u8 > ] = unsafe { core:: slice:: from_raw_parts ( ptr . as_ptr ( ) , n) } ;
148- let dst : & mut [ MaybeUninit < u8 > ] = unsafe { core:: slice:: from_raw_parts_mut ( alloc. as_ptr ( ) , n) } ;
149- dst. copy_from_slice ( src) ;
150- }
151- unsafe { self . free ( ptr, old_layout) } ;
152- Ok ( alloc)
152+ let old_zst = old_layout. size ( ) == 0 ;
153+ let new_zst = new_layout. size ( ) == 0 ;
154+
155+ if old_zst && cfg ! ( debug_assertions) {
156+ if ptr != Self :: DANGLE { bug:: ub:: invalid_ptr_for_allocator ( ptr) }
157+ if old_layout. align ( ) > A :: MAX_ALIGN . as_usize ( ) { bug:: ub:: invalid_free_align_for_allocator ( old_layout. align ( ) ) }
158+ }
159+
160+ if new_zst && new_layout. align ( ) > A :: MAX_ALIGN . as_usize ( ) {
161+ return Err ( ExcessiveAlignmentRequestedError { requested : new_layout. into ( ) , supported : A :: MAX_ALIGN } . into ( ) )
162+ }
163+
164+ match ( old_zst, new_zst) {
165+ ( false , false ) => unsafe { self . 0 . realloc_zeroed ( ptr, old_layout, new_layout) } ,
166+ ( false , true ) => unsafe { self . 0 . free ( ptr, old_layout) ; Ok ( Self :: DANGLE . cast ( ) ) } ,
167+ ( true , false ) => { Ok ( self . 0 . alloc_zeroed ( new_layout) ?. cast ( ) ) } ,
168+ ( true , true ) => { Ok ( Self :: DANGLE . cast ( ) ) } ,
153169 }
154170 }
155171}
0 commit comments