@@ -102,8 +102,18 @@ unsafe impl const Allocator for ConstAllocator {
102
102
103
103
let new_ptr = self . allocate ( new_layout) ?;
104
104
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
+ }
107
117
}
108
118
Ok ( new_ptr)
109
119
}
@@ -114,12 +124,21 @@ unsafe impl const Allocator for ConstAllocator {
114
124
old_layout : Layout ,
115
125
new_layout : Layout ,
116
126
) -> 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) ? } ;
118
130
if new_layout. size ( ) > 0 {
119
131
let old_size = old_layout. size ( ) ;
120
132
let new_size = new_layout. size ( ) ;
121
133
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
+ }
123
142
}
124
143
Ok ( new_ptr)
125
144
}
@@ -137,8 +156,18 @@ unsafe impl const Allocator for ConstAllocator {
137
156
138
157
let new_ptr = self . allocate ( new_layout) ?;
139
158
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
+ }
142
171
}
143
172
Ok ( new_ptr)
144
173
}
0 commit comments