File tree 1 file changed +7
-9
lines changed
1 file changed +7
-9
lines changed Original file line number Diff line number Diff line change @@ -174,26 +174,24 @@ macro_rules! impl_array {
174
174
where
175
175
F : FnMut ( T ) -> U ,
176
176
{
177
- fn map_array( mut values: [ T ; $size] , mut f: F ) -> Self {
177
+ fn map_array( values: [ T ; $size] , mut f: F ) -> Self {
178
178
use std:: {
179
- mem:: forget ,
179
+ mem:: { ManuallyDrop , MaybeUninit } ,
180
180
ptr:: { read, write} ,
181
181
} ;
182
182
183
+ // Use `ManuallyDrop<_>` to guard against panic safety issue.
184
+ // Upon panic in `f`, `values` isn't dropped
185
+ // and thus item copied by `read()` is dropped only once.
186
+ let mut values = ManuallyDrop :: new( values) ;
183
187
unsafe {
184
- // All elements of `result` is written.
185
- // Each element of `values` read once and then forgotten.
186
- // Hence safe in case `f` never panics.
187
- // TODO: Make it panic-safe.
188
- let mut result: :: std:: mem:: MaybeUninit <[ U ; $size] > =
189
- :: std:: mem:: MaybeUninit :: zeroed( ) ;
188
+ let mut result: MaybeUninit <[ U ; $size] > = MaybeUninit :: zeroed( ) ;
190
189
for i in 0 ..$size {
191
190
write(
192
191
result. as_mut_ptr( ) . cast:: <U >( ) . add( i) ,
193
192
f( read( & mut values[ i] ) ) ,
194
193
) ;
195
194
}
196
- forget( values) ;
197
195
result. assume_init( )
198
196
}
199
197
}
You can’t perform that action at this time.
0 commit comments