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 Cells.

``

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 Cells that partially overlap.

``

``

422

`` +

/// (Using just standard library methods, it is impossible to create such partially overlapping Cells.

``

``

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 Cells");

``

``

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 Cells.

``

``

450

`` +

// either of these Cells. We also excluded shenanigans like partially overlapping Cells,

``

``

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

``