Skip to content

Commit 96bc904

Browse files
committed
Implement traits for Cell
Closes #1253 gherrit-pr-id: I569b74086a5f98cda71b4a4131f9ce4f89dcc623
1 parent 5f3623e commit 96bc904

File tree

3 files changed

+60
-19
lines changed

3 files changed

+60
-19
lines changed

src/impls.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
// This file may not be copied, modified, or distributed except according to
88
// those terms.
99

10-
use core::{cell::UnsafeCell, mem::MaybeUninit as CoreMaybeUninit, ptr::NonNull};
10+
use core::{
11+
cell::{Cell, UnsafeCell},
12+
mem::MaybeUninit as CoreMaybeUninit,
13+
ptr::NonNull,
14+
};
1115

1216
use super::*;
1317

@@ -890,6 +894,21 @@ safety_comment! {
890894
}
891895
assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
892896

897+
impl_for_transmute_from!(T: ?Sized + TryFromBytes => TryFromBytes for Cell<T>[UnsafeCell<T>]);
898+
impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for Cell<T>[UnsafeCell<T>]);
899+
impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for Cell<T>[UnsafeCell<T>]);
900+
impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for Cell<T>[UnsafeCell<T>]);
901+
safety_comment! {
902+
/// SAFETY:
903+
/// `Cell<T>` has the same in-memory representation as `T` [1], and thus has
904+
/// the same alignment as `T`.
905+
///
906+
/// [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.Cell.html#memory-layout:
907+
///
908+
/// `Cell<T>` has the same in-memory representation as its inner type `T`.
909+
unsafe_impl!(T: ?Sized + Unaligned => Unaligned for Cell<T>);
910+
}
911+
893912
impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for UnsafeCell<T>[<T>]);
894913
impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for UnsafeCell<T>[<T>]);
895914
impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for UnsafeCell<T>[<T>]);

src/lib.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ pub use crate::r#ref::*;
357357
pub use crate::wrappers::*;
358358

359359
use core::{
360-
cell::UnsafeCell,
360+
cell::{Cell, UnsafeCell},
361361
cmp::Ordering,
362362
fmt::{self, Debug, Display, Formatter},
363363
hash::Hasher,
@@ -983,29 +983,27 @@ impl_known_layout!(const N: usize, T => [T; N]);
983983

984984
safety_comment! {
985985
/// SAFETY:
986-
/// `str`, `ManuallyDrop<[T]>` [1], and `UnsafeCell<T>` [2] have the same
987-
/// representations as `[u8]`, `[T]`, and `T` repsectively. `str` has
988-
/// different bit validity than `[u8]`, but that doesn't affect the
989-
/// soundness of this impl.
986+
/// `str` has the same representation as `[u8]`. `ManuallyDrop<T>` [1],
987+
/// `UnsafeCell<T>` [2], and `Cell<T>` [3] have the same representation as
988+
/// `T`.
990989
///
991-
/// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
990+
/// [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
992991
///
993992
/// `ManuallyDrop<T>` is guaranteed to have the same layout and bit
994993
/// validity as `T`
995994
///
996-
/// [2] Per https://doc.rust-lang.org/core/cell/struct.UnsafeCell.html#memory-layout:
995+
/// [2] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.UnsafeCell.html#memory-layout:
997996
///
998997
/// `UnsafeCell<T>` has the same in-memory representation as its inner
999998
/// type `T`.
1000999
///
1001-
/// TODO(#429):
1002-
/// - Add quotes from docs.
1003-
/// - Once [1] (added in
1004-
/// https://github.com/rust-lang/rust/pull/115522) is available on stable,
1005-
/// quote the stable docs instead of the nightly docs.
1000+
/// [3] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.Cell.html#memory-layout:
1001+
///
1002+
/// `Cell<T>` has the same in-memory representation as `T`.
10061003
unsafe_impl_known_layout!(#[repr([u8])] str);
10071004
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] ManuallyDrop<T>);
10081005
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] UnsafeCell<T>);
1006+
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] Cell<T>);
10091007
}
10101008

10111009
safety_comment! {

src/pointer/transmute.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// those terms.
88

99
use core::{
10-
cell::UnsafeCell,
10+
cell::{Cell, UnsafeCell},
1111
mem::{ManuallyDrop, MaybeUninit},
1212
num::Wrapping,
1313
ptr::NonNull,
@@ -405,20 +405,44 @@ safety_comment! {
405405
unsafe_impl_invariants_eq!(T => T, Wrapping<T>);
406406

407407
/// SAFETY:
408-
/// - `Unalign<T>` has the same size as `T` [1].
409-
/// - Per [1], `Unalign<T>` has the same bit validity as `T`. Technically
408+
/// - `UnsafeCell<T>` has the same size as `T` [1].
409+
/// - Per [1], `UnsafeCell<T>` has the same bit validity as `T`. Technically
410410
/// the term "representation" doesn't guarantee this, but the subsequent
411411
/// sentence in the documentation makes it clear that this is the
412412
/// intention.
413413
///
414414
/// [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
415415
///
416-
/// `UnsafeCell<T>` has the same in-memory representation as its inner type
417-
/// `T`. A consequence of this guarantee is that it is possible to convert
418-
/// between `T` and `UnsafeCell<T>`.
416+
/// `UnsafeCell<T>` has the same in-memory representation as its inner
417+
/// type `T`. A consequence of this guarantee is that it is possible to
418+
/// convert between `T` and `UnsafeCell<T>`.
419419
unsafe_impl_for_transparent_wrapper!(T: ?Sized => UnsafeCell<T>);
420+
421+
/// SAFETY:
422+
/// - `Cell<T>` has the same size as `T` [1].
423+
/// - Per [1], `Cell<T>` has the same bit validity as `T`. Technically the
424+
/// term "representation" doesn't guarantee this, but it does promise to
425+
/// have the "same memory layout and caveats as `UnsafeCell<T>`." The
426+
/// `UnsafeCell` docs [2] make it clear that bit validity is the intention
427+
/// even if that phrase isn't used.
428+
///
429+
/// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.Cell.html#memory-layout:
430+
///
431+
/// `Cell<T>` has the same memory layout and caveats as `UnsafeCell<T>`.
432+
/// In particular, this means that `Cell<T>` has the same in-memory
433+
/// representation as its inner type `T`.
434+
///
435+
/// [2] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
436+
///
437+
/// `UnsafeCell<T>` has the same in-memory representation as its inner
438+
/// type `T`. A consequence of this guarantee is that it is possible to
439+
/// convert between `T` and `UnsafeCell<T>`.
440+
unsafe_impl_for_transparent_wrapper!(T: ?Sized => Cell<T>);
420441
}
421442

443+
impl_transitive_transmute_from!(T: ?Sized => Cell<T> => T => UnsafeCell<T>);
444+
impl_transitive_transmute_from!(T: ?Sized => UnsafeCell<T> => T => Cell<T>);
445+
422446
// SAFETY: `MaybeUninit<T>` has no validity requirements. Currently this is not
423447
// explicitly guaranteed, but it's obvious from `MaybeUninit`'s documentation
424448
// that this is the intention:

0 commit comments

Comments
 (0)