@@ -109,7 +109,7 @@ pub use intrinsics::transmute;
109109/// [`Clone`][clone]. You need the value's destructor to run only once,
110110/// because a double `free` is undefined behavior.
111111///
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:
113113///
114114/// ```
115115/// use std::mem;
@@ -447,18 +447,15 @@ pub unsafe fn uninitialized<T>() -> T {
447447#[ stable( feature = "rust1" , since = "1.0.0" ) ]
448448pub fn swap < T > ( x : & mut T , y : & mut T ) {
449449 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 ;
452452
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+ }
462459 }
463460}
464461
0 commit comments