@@ -369,6 +369,22 @@ where
369
369
// Instead of swapping one pair at the time, it is more efficient to perform a cyclic
370
370
// permutation. This is not strictly equivalent to swapping, but produces a similar
371
371
// result using fewer memory operations.
372
+
373
+ // SAFETY: The use of `ptr::read` is valid because there is at least one element in
374
+ // both `offsets_l` and `offsets_r`, so `left!` is a valid pointer to read from.
375
+ //
376
+ // The uses of `left!` involve calls to `offset` on `l`, which points to the
377
+ // beginning of `v`. All the offsets pointed-to by `start_l` are at most `block_l`, so
378
+ // these `offset` calls are safe as all reads are within the block. The same argument
379
+ // applies for the uses of `right!`.
380
+ //
381
+ // The calls to `start_l.offset` are valid because there are at most `count-1` of them,
382
+ // plus the final one at the end of the unsafe block, where `count` is the minimum number
383
+ // of collected offsets in `offsets_l` and `offsets_r`, so there is no risk of there not
384
+ // being enough elements. The same reasoning applies to the calls to `start_r.offset`.
385
+ //
386
+ // The calls to `copy_nonoverlapping` are safe because `left!` and `right!` are guaranteed
387
+ // not to overlap, and are valid because of the reasoning above.
372
388
unsafe {
373
389
let tmp = ptr:: read ( left ! ( ) ) ;
374
390
ptr:: copy_nonoverlapping ( right ! ( ) , left ! ( ) , 1 ) ;
@@ -389,11 +405,21 @@ where
389
405
390
406
if start_l == end_l {
391
407
// All out-of-order elements in the left block were moved. Move to the next block.
408
+
409
+ // block-width-guarantee
410
+ // SAFETY: if `!is_done` then the slice width is guaranteed to be at least `2*BLOCK` wide. There
411
+ // are at most `BLOCK` elements in `offsets_l` because of its size, so the `offset` operation is
412
+ // safe. Otherwise, the debug assertions in the `is_done` case guarantee that
413
+ // `width(l, r) == block_l + block_r`, namely, that the block sizes have been adjusted to account
414
+ // for the smaller number of remaining elements.
392
415
l = unsafe { l. offset ( block_l as isize ) } ;
393
416
}
394
417
395
418
if start_r == end_r {
396
419
// All out-of-order elements in the right block were moved. Move to the previous block.
420
+
421
+ // SAFETY: Same argument as [block-width-guarantee]. Either this is a full block `2*BLOCK`-wide,
422
+ // or `block_r` has been adjusted for the last handful of elements.
397
423
r = unsafe { r. offset ( -( block_r as isize ) ) } ;
398
424
}
399
425
0 commit comments