@@ -451,22 +451,48 @@ mod unsafe_impls {
451
451
) ;
452
452
453
453
out. clear ( ) ;
454
- out. reserve_exact ( vec . len ( ) ) ;
454
+ out. reserve_exact ( inv . 0 . len ( ) ) ;
455
455
456
456
//------------------------------------------------
457
457
// You are now entering a PANIC FREE ZONE
458
458
459
- // Make a bunch of uninitialized elements indexable.
460
- unsafe { out. set_len ( vec. len ( ) ) ; }
461
-
462
- // a perm holds indices into the data vec, so the inverse holds indices into `out`.
463
- for ( vec_i, & out_i) in inv. 0 . iter ( ) . enumerate ( ) {
464
- let tmp = unsafe { ptr:: read ( & vec[ vec_i] ) } ;
465
- unsafe { ptr:: write ( & mut out[ out_i] , tmp) } ;
459
+ { // scope ptrs so we can reason about them
460
+ let vec_ptr = vec. as_ptr ( ) ;
461
+ let out_ptr = out. as_mut_ptr ( ) ;
462
+
463
+ // a perm holds indices into the data vec, so the inverse holds indices into `out`.
464
+ for ( vec_i, & out_i) in inv. 0 . iter ( ) . enumerate ( ) {
465
+ // SAFETY:
466
+ //
467
+ // * vec_i < vec.len() because:
468
+ // * vec_i comes from the standard library implementation of `impl Iterator for std::iter::Enumerate`,
469
+ // and is thus guaranteed to be `< inv.0.len()`.
470
+ // * We asserted earlier that `inv.0.len() == vec.len()`.
471
+ //
472
+ // * vec[vec_i] will not be double-dropped, because:
473
+ // * we perform `vec.set_len(0)` after this loop.
474
+ // * we cannot possibly panic before this occurs.
475
+ let value = unsafe { vec_ptr. offset ( vec_i as isize ) . read ( ) } ;
476
+
477
+ // SAFETY:
478
+ //
479
+ // * out_i < out.capacity() because:
480
+ // * A privacy-protected invariant of PermVec guarantees that `out_i < inv.0.len()`.
481
+ // * We called `Vec::reserve_exact` to ensure that `inv.0.len() <= out.capacity()`.
482
+ let dest_ptr = unsafe { out_ptr. offset ( out_i as isize ) } ;
483
+ unsafe { dest_ptr. write ( value) } ;
484
+ }
466
485
}
467
486
468
487
// Don't drop the original items, but do allow the original
469
488
// vec to fall out of scope so the memory can be freed.
489
+
490
+ // SAFETY:
491
+ //
492
+ // * All elements in out[0..vec.len()] are initialized because:
493
+ // * A privacy-protected invariant of PermVec guarantees that, in the above `for` loop,
494
+ // every index from 0..vec.len() will have appeared exactly once as `out_i`.
495
+ unsafe { out. set_len ( vec. len ( ) ) ; }
470
496
unsafe { vec. set_len ( 0 ) ; }
471
497
472
498
// Thank you for flying with us. You may now PANIC!
0 commit comments