@@ -102,8 +102,18 @@ unsafe impl const Allocator for ConstAllocator {
102102
103103 let new_ptr = self . allocate ( new_layout) ?;
104104 if new_layout. size ( ) > 0 {
105- new_ptr. as_mut_ptr ( ) . copy_from_nonoverlapping ( ptr. as_ptr ( ) , old_layout. size ( ) ) ;
106- self . deallocate ( ptr, old_layout) ;
105+ // Safety: `new_ptr` is valid for writes and `ptr` for reads of
106+ // `old_layout.size()`, because `new_layout.size() >=
107+ // old_layout.size()` (which is an invariant that must be upheld by
108+ // callers).
109+ unsafe {
110+ new_ptr. as_mut_ptr ( ) . copy_from_nonoverlapping ( ptr. as_ptr ( ) , old_layout. size ( ) ) ;
111+ }
112+ // Safety: `ptr` is never used again is also an invariant which must
113+ // be upheld by callers.
114+ unsafe {
115+ self . deallocate ( ptr, old_layout) ;
116+ }
107117 }
108118 Ok ( new_ptr)
109119 }
@@ -114,12 +124,21 @@ unsafe impl const Allocator for ConstAllocator {
114124 old_layout : Layout ,
115125 new_layout : Layout ,
116126 ) -> Result < NonNull < [ u8 ] > , AllocError > {
117- let new_ptr = self . grow ( ptr, old_layout, new_layout) ?;
127+ // Safety: Invariants of `grow_zeroed` and `grow` are the same, and must
128+ // be enforced by callers.
129+ let new_ptr = unsafe { self . grow ( ptr, old_layout, new_layout) ? } ;
118130 if new_layout. size ( ) > 0 {
119131 let old_size = old_layout. size ( ) ;
120132 let new_size = new_layout. size ( ) ;
121133 let raw_ptr = new_ptr. as_mut_ptr ( ) ;
122- raw_ptr. add ( old_size) . write_bytes ( 0 , new_size - old_size) ;
134+ // Safety:
135+ // - `grow` returned Ok, so the returned pointer must be valid for
136+ // `new_size` bytes
137+ // - `new_size` must be larger than `old_size`, which is an
138+ // invariant which must be upheld by callers.
139+ unsafe {
140+ raw_ptr. add ( old_size) . write_bytes ( 0 , new_size - old_size) ;
141+ }
123142 }
124143 Ok ( new_ptr)
125144 }
@@ -137,8 +156,18 @@ unsafe impl const Allocator for ConstAllocator {
137156
138157 let new_ptr = self . allocate ( new_layout) ?;
139158 if new_layout. size ( ) > 0 {
140- new_ptr. as_mut_ptr ( ) . copy_from_nonoverlapping ( ptr. as_ptr ( ) , new_layout. size ( ) ) ;
141- self . deallocate ( ptr, old_layout) ;
159+ // Safety: `new_ptr` and `ptr` are valid for reads/writes of
160+ // `new_layout.size()` because of the invariants of shrink, which
161+ // include `new_layout.size()` being smaller than (or equal to)
162+ // `old_layout.size()`.
163+ unsafe {
164+ new_ptr. as_mut_ptr ( ) . copy_from_nonoverlapping ( ptr. as_ptr ( ) , new_layout. size ( ) ) ;
165+ }
166+ // Safety: `ptr` is never used again is also an invariant which must
167+ // be upheld by callers.
168+ unsafe {
169+ self . deallocate ( ptr, old_layout) ;
170+ }
142171 }
143172 Ok ( new_ptr)
144173 }
0 commit comments