Auto merge of #114795 - RalfJung:cell-swap, r=dtolnay · rust-lang/rust@f6faef4 (original) (raw)
`@@ -237,6 +237,7 @@
`
237
237
``
238
238
`use crate::cmp::Ordering;
`
239
239
`use crate::fmt::{self, Debug, Display};
`
``
240
`+
use crate::intrinsics::is_nonoverlapping;
`
240
241
`use crate:📑:{PhantomData, Unsize};
`
241
242
`use crate::mem;
`
242
243
`use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn};
`
`@@ -415,6 +416,12 @@ impl Cell {
`
415
416
`` /// Swaps the values of two Cell
s.
``
416
417
`` /// Difference with std::mem::swap
is that this function doesn't require &mut
reference.
``
417
418
`///
`
``
419
`+
/// # Panics
`
``
420
`+
///
`
``
421
`` +
/// This function will panic if self
and other
are different Cell
s that partially overlap.
``
``
422
`` +
/// (Using just standard library methods, it is impossible to create such partially overlapping Cell
s.
``
``
423
`` +
/// However, unsafe code is allowed to e.g. create two &Cell<[i32; 2]>
that partially overlap.)
``
``
424
`+
///
`
418
425
`/// # Examples
`
419
426
`///
`
420
427
```` /// ```
````
`@@ -430,14 +437,20 @@ impl Cell {
`
430
437
`#[stable(feature = "move_cell", since = "1.17.0")]
`
431
438
`pub fn swap(&self, other: &Self) {
`
432
439
`if ptr::eq(self, other) {
`
``
440
`+
// Swapping wouldn't change anything.
`
433
441
`return;
`
434
442
`}
`
``
443
`+
if !is_nonoverlapping(self, other, 1) {
`
``
444
`+
// See https://github.com/rust-lang/rust/issues/80778 for why we need to stop here.
`
``
445
`` +
panic!("Cell::swap
on overlapping non-identical Cell
s");
``
``
446
`+
}
`
435
447
`` // SAFETY: This can be risky if called from separate threads, but Cell
``
436
448
`` // is !Sync
so this won't happen. This also won't invalidate any
``
437
449
`` // pointers since Cell
makes sure nothing else will be pointing into
``
438
``
`` -
// either of these Cell
s.
``
``
450
`` +
// either of these Cell
s. We also excluded shenanigans like partially overlapping Cell
s,
``
``
451
`` +
// so swap
will just properly copy two full values of type T
back and forth.
``
439
452
`unsafe {
`
440
``
`-
ptr::swap(self.value.get(), other.value.get());
`
``
453
`+
mem::swap(&mut *self.value.get(), &mut *other.value.get());
`
441
454
`}
`
442
455
`}
`
443
456
``