@@ -560,15 +560,45 @@ impl<T> [T] {
560560 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
561561 #[ inline]
562562 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()`
570600 unsafe {
571- ptr:: swap ( pa , pb ) ;
601+ ptr:: swap ( ptr . add ( a ) , ptr . add ( b ) ) ;
572602 }
573603 }
574604
0 commit comments