@@ -109,7 +109,7 @@ pub use intrinsics::transmute;
109
109
/// [`Clone`][clone]. You need the value's destructor to run only once,
110
110
/// because a double `free` is undefined behavior.
111
111
///
112
- /// An example is the definition of [`mem::swap`][swap] in this module:
112
+ /// An example is the (old) definition of [`mem::swap`][swap] in this module:
113
113
///
114
114
/// ```
115
115
/// use std::mem;
@@ -447,18 +447,15 @@ pub unsafe fn uninitialized<T>() -> T {
447
447
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
448
448
pub fn swap < T > ( x : & mut T , y : & mut T ) {
449
449
unsafe {
450
- // Give ourselves some scratch space to work with
451
- let mut t : T = uninitialized ( ) ;
450
+ let x = x as * mut T as * mut u8 ;
451
+ let y = y as * mut T as * mut u8 ;
452
452
453
- // Perform the swap, `&mut` pointers never alias
454
- ptr:: copy_nonoverlapping ( & * x, & mut t, 1 ) ;
455
- ptr:: copy_nonoverlapping ( & * y, x, 1 ) ;
456
- ptr:: copy_nonoverlapping ( & t, y, 1 ) ;
457
-
458
- // y and t now point to the same thing, but we need to completely
459
- // forget `t` because we do not want to run the destructor for `T`
460
- // on its value, which is still owned somewhere outside this function.
461
- forget ( t) ;
453
+ // use an xor-swap as x & y are guaranteed to never alias
454
+ for i in 0 ..size_of :: < T > ( ) as isize {
455
+ * x. offset ( i) ^= * y. offset ( i) ;
456
+ * y. offset ( i) ^= * x. offset ( i) ;
457
+ * x. offset ( i) ^= * y. offset ( i) ;
458
+ }
462
459
}
463
460
}
464
461
0 commit comments