@@ -560,15 +560,45 @@ impl<T> [T] {
560
560
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
561
561
#[ inline]
562
562
pub fn swap ( & mut self , a : usize , b : usize ) {
563
- // Can't take two mutable loans from one vector, so instead use raw pointers.
564
- let pa = ptr:: addr_of_mut!( self [ a] ) ;
565
- let pb = ptr:: addr_of_mut!( self [ b] ) ;
566
- // SAFETY: `pa` and `pb` have been created from safe mutable references and refer
567
- // to elements in the slice and therefore are guaranteed to be valid and aligned.
568
- // Note that accessing the elements behind `a` and `b` is checked and will
569
- // panic when out of bounds.
563
+ assert ! ( a < self . len( ) ) ;
564
+ assert ! ( b < self . len( ) ) ;
565
+ // SAFETY: we just checked that both `a` and `b` are in bounds
566
+ unsafe { self . swap_unchecked ( a, b) }
567
+ }
568
+
569
+ /// Swaps two elements in the slice, without doing bounds checking.
570
+ ///
571
+ /// For a safe alternative see [`swap`].
572
+ ///
573
+ /// # Arguments
574
+ ///
575
+ /// * a - The index of the first element
576
+ /// * b - The index of the second element
577
+ ///
578
+ /// # Safety
579
+ ///
580
+ /// Calling this method with an out-of-bounds index is *[undefined behavior]*.
581
+ /// The caller has to ensure that `a < self.len()` and `b < self.len()`.
582
+ ///
583
+ /// # Examples
584
+ ///
585
+ /// ```
586
+ /// let mut v = ["a", "b", "c", "d"];
587
+ /// // SAFETY: we know that 1 and 3 are both indices of the slice
588
+ /// unsafe { v.swap_unchecked(1, 3) };
589
+ /// assert!(v == ["a", "d", "c", "b"]);
590
+ /// ```
591
+ ///
592
+ /// [`swap`]: slice::swap
593
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
594
+ #[ unstable( feature = "slice_swap_unchecked" , issue = "88539" ) ]
595
+ pub unsafe fn swap_unchecked ( & mut self , a : usize , b : usize ) {
596
+ debug_assert ! ( a < self . len( ) ) ;
597
+ debug_assert ! ( b < self . len( ) ) ;
598
+ let ptr = self . as_mut_ptr ( ) ;
599
+ // SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()`
570
600
unsafe {
571
- ptr:: swap ( pa , pb ) ;
601
+ ptr:: swap ( ptr . add ( a ) , ptr . add ( b ) ) ;
572
602
}
573
603
}
574
604
0 commit comments