Skip to content

Commit 8b454f6

Browse files
committed
Implement traits for Cell
Closes #1253 gherrit-pr-id: I569b74086a5f98cda71b4a4131f9ce4f89dcc623
1 parent dff5d0c commit 8b454f6

11 files changed

+74
-33
lines changed

src/impls.rs

+20-1
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

@@ -861,6 +865,21 @@ safety_comment! {
861865
}
862866
assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
863867

868+
impl_for_transmute_from!(T: ?Sized + TryFromBytes => TryFromBytes for Cell<T>[UnsafeCell<T>]);
869+
impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for Cell<T>[UnsafeCell<T>]);
870+
impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for Cell<T>[UnsafeCell<T>]);
871+
impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for Cell<T>[UnsafeCell<T>]);
872+
safety_comment! {
873+
/// SAFETY:
874+
/// `Cell<T>` has the same in-memory representation as `T` [1], and thus has
875+
/// the same alignment as `T`.
876+
///
877+
/// [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.Cell.html#memory-layout:
878+
///
879+
/// `Cell<T>` has the same in-memory representation as its inner type `T`.
880+
unsafe_impl!(T: ?Sized + Unaligned => Unaligned for Cell<T>);
881+
}
882+
864883
impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for UnsafeCell<T>[<T>]);
865884
impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for UnsafeCell<T>[<T>]);
866885
impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for UnsafeCell<T>[<T>]);

src/lib.rs

+10-12
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

+30-6
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:

tests/ui-nightly/diagnostic-not-implemented-unaligned.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ error[E0277]: the trait bound `NotZerocopy: zerocopy::Unaligned` is not satisfie
1010
AtomicBool
1111
AtomicI8
1212
AtomicU8
13+
Cell<T>
1314
F32<O>
1415
F64<O>
1516
I128<O>
16-
I16<O>
1717
and $N others
1818
note: required by a bound in `takes_unaligned`
1919
--> tests/ui-nightly/diagnostic-not-implemented-unaligned.rs:21:23

tests/ui-stable/diagnostic-not-implemented-unaligned.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ error[E0277]: the trait bound `NotZerocopy: zerocopy::Unaligned` is not satisfie
1010
AtomicBool
1111
AtomicI8
1212
AtomicU8
13+
Cell<T>
1314
F32<O>
1415
F64<O>
1516
I128<O>
16-
I16<O>
1717
and $N others
1818
note: required by a bound in `takes_unaligned`
1919
--> tests/ui-stable/diagnostic-not-implemented-unaligned.rs:21:23

zerocopy-derive/tests/ui-nightly/derive_transparent.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ error[E0277]: the trait bound `NotZerocopy: zerocopy::Unaligned` is not satisfie
126126
AtomicBool
127127
AtomicI8
128128
AtomicU8
129+
Cell<T>
129130
F32<O>
130131
F64<O>
131132
I128<O>
132-
I16<O>
133133
and $N others
134134
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::Unaligned`
135135
--> tests/ui-nightly/derive_transparent.rs:24:32

zerocopy-derive/tests/ui-nightly/late_compile_pass.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
186186
AtomicBool
187187
AtomicI8
188188
AtomicU8
189+
Cell<T>
189190
F32<O>
190191
F64<O>
191192
I128<O>
192-
I16<O>
193193
and $N others
194194
= help: see issue #48214
195195
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -210,10 +210,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
210210
AtomicBool
211211
AtomicI8
212212
AtomicU8
213+
Cell<T>
213214
F32<O>
214215
F64<O>
215216
I128<O>
216-
I16<O>
217217
and $N others
218218
= help: see issue #48214
219219
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -234,10 +234,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
234234
AtomicBool
235235
AtomicI8
236236
AtomicU8
237+
Cell<T>
237238
F32<O>
238239
F64<O>
239240
I128<O>
240-
I16<O>
241241
and $N others
242242
= help: see issue #48214
243243
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)

zerocopy-derive/tests/ui-nightly/struct.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
284284
AtomicBool
285285
AtomicI8
286286
AtomicU8
287+
Cell<T>
287288
F32<O>
288289
F64<O>
289290
I128<O>
290-
I16<O>
291291
and $N others
292292
= help: see issue #48214
293293
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -386,10 +386,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
386386
AtomicBool
387387
AtomicI8
388388
AtomicU8
389+
Cell<T>
389390
F32<O>
390391
F64<O>
391392
I128<O>
392-
I16<O>
393393
and $N others
394394
note: required for `IntoBytes11<AU16>` to implement `zerocopy::IntoBytes`
395395
--> tests/ui-nightly/struct.rs:150:10

zerocopy-derive/tests/ui-stable/derive_transparent.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ error[E0277]: the trait bound `NotZerocopy: zerocopy::Unaligned` is not satisfie
126126
AtomicBool
127127
AtomicI8
128128
AtomicU8
129+
Cell<T>
129130
F32<O>
130131
F64<O>
131132
I128<O>
132-
I16<O>
133133
and $N others
134134
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::Unaligned`
135135
--> tests/ui-stable/derive_transparent.rs:24:32

zerocopy-derive/tests/ui-stable/late_compile_pass.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
158158
AtomicBool
159159
AtomicI8
160160
AtomicU8
161+
Cell<T>
161162
F32<O>
162163
F64<O>
163164
I128<O>
164-
I16<O>
165165
and $N others
166166
= help: see issue #48214
167167
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -178,10 +178,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
178178
AtomicBool
179179
AtomicI8
180180
AtomicU8
181+
Cell<T>
181182
F32<O>
182183
F64<O>
183184
I128<O>
184-
I16<O>
185185
and $N others
186186
= help: see issue #48214
187187
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -198,10 +198,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
198198
AtomicBool
199199
AtomicI8
200200
AtomicU8
201+
Cell<T>
201202
F32<O>
202203
F64<O>
203204
I128<O>
204-
I16<O>
205205
and $N others
206206
= help: see issue #48214
207207
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)

zerocopy-derive/tests/ui-stable/struct.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
257257
AtomicBool
258258
AtomicI8
259259
AtomicU8
260+
Cell<T>
260261
F32<O>
261262
F64<O>
262263
I128<O>
263-
I16<O>
264264
and $N others
265265
= help: see issue #48214
266266
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -347,10 +347,10 @@ error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
347347
AtomicBool
348348
AtomicI8
349349
AtomicU8
350+
Cell<T>
350351
F32<O>
351352
F64<O>
352353
I128<O>
353-
I16<O>
354354
and $N others
355355
note: required for `IntoBytes11<AU16>` to implement `zerocopy::IntoBytes`
356356
--> tests/ui-stable/struct.rs:150:10

0 commit comments

Comments
 (0)