@@ -26,13 +26,12 @@ use crate::{
26
26
///
27
27
/// # Safety
28
28
///
29
- /// `T: TransparentWrapper` implies that:
30
- /// - `T` has the same size as [`T::Inner`]
31
- /// - `T` has `UnsafeCell`s covering the same byte ranges as `T::Inner`
32
- /// - `T` has zero-sized `UnsafeCell`s (e.g., `UnsafeCell<()>`,
33
- /// `[UnsafeCell<u8>; 0]`, etc) at the same byte offsets as `T::Inner`
34
- ///
29
+ /// `T: TransparentWrapper` implies that `T` has the same size as [`T::Inner`].
35
30
/// Further, `T: TransparentWrapper<I>` implies that:
31
+ /// - If `T::UnsafeCellVariance = Covariant`, then:
32
+ /// - `T` has `UnsafeCell`s covering the same byte ranges as `T::Inner`
33
+ /// - `T` has zero-sized `UnsafeCell`s (e.g., `UnsafeCell<()>`,
34
+ /// `[UnsafeCell<u8>; 0]`, etc) at the same byte offsets as `T::Inner`
36
35
/// - If a `T` pointer satisfies the alignment invariant `I::Alignment`, then
37
36
/// that same pointer, cast to `T::Inner`, satisfies the alignment invariant
38
37
/// `<T::AlignmentVariance as AlignmentVariance<I::Alignment>>::Applied`.
@@ -48,6 +47,7 @@ use crate::{
48
47
pub unsafe trait TransparentWrapper < I : Invariants > {
49
48
type Inner : ?Sized ;
50
49
50
+ type UnsafeCellVariance ;
51
51
type AlignmentVariance : AlignmentVariance < I :: Alignment > ;
52
52
type ValidityVariance : ValidityVariance < I :: Validity > ;
53
53
@@ -106,14 +106,17 @@ impl<I: invariant::Validity> ValidityVariance<I> for Invariant {
106
106
107
107
// SAFETY:
108
108
// - Per [1], `MaybeUninit<T>` has the same size as `T`.
109
- // - Per [1], `MaybeUninit<T>` has `UnsafeCell`s at the same byte ranges as
110
- // `Inner = T`, and `UnsafeCell`s at the same byte offsets as `T`.
111
109
// - See inline comments for other safety justifications.
112
110
//
113
111
// [1] TODO(#896): Write a safety proof before the next stable release.
114
112
unsafe impl < T , I : Invariants > TransparentWrapper < I > for MaybeUninit < T > {
115
113
type Inner = T ;
116
114
115
+ // SAFETY: Per [1], `MaybeUninit<T>` has `UnsafeCell`s at the same byte
116
+ // ranges as `Inner = T`, and `UnsafeCell`s at the same byte offsets as `T`.
117
+ //
118
+ // [1] TODO(#896): Write a safety proof before the next stable release.
119
+ type UnsafeCellVariance = Covariant ;
117
120
// SAFETY: Per [1], `MaybeUninit<T>` has the same layout as `T`, and thus
118
121
// has the same alignment as `T`.
119
122
//
@@ -145,14 +148,17 @@ unsafe impl<T, I: Invariants> TransparentWrapper<I> for MaybeUninit<T> {
145
148
146
149
// SAFETY:
147
150
// - Per [1], `ManuallyDrop<T>` has the same size as `T`.
148
- // - Per [1], `ManuallyDrop<T>` has `UnsafeCell`s at the same byte ranges as
149
- // `Inner = T`, and `UnsafeCell`s at the same byte offsets as `T`.
150
151
// - See inline comments for other safety justifications.
151
152
//
152
153
// [1] TODO(#896): Write a safety proof before the next stable release.
153
154
unsafe impl < T : ?Sized , I : Invariants > TransparentWrapper < I > for ManuallyDrop < T > {
154
155
type Inner = T ;
155
156
157
+ // SAFETY: Per [1], `ManuallyDrop<T>` has `UnsafeCell`s at the same byte
158
+ // ranges as `Inner = T`, and `UnsafeCell`s at the same byte offsets as `T`.
159
+ //
160
+ // [1] TODO(#896): Write a safety proof before the next stable release.
161
+ type UnsafeCellVariance = Covariant ;
156
162
// SAFETY: Per [1], `ManuallyDrop<T>` has the same layout as `T`, and thus
157
163
// has the same alignment as `T`.
158
164
//
@@ -187,14 +193,17 @@ unsafe impl<T: ?Sized, I: Invariants> TransparentWrapper<I> for ManuallyDrop<T>
187
193
188
194
// SAFETY:
189
195
// - Per [1], `Wrapping<T>` has the same size as `T`.
190
- // - Per [1], `Wrapping<T>` has `UnsafeCell`s at the same byte ranges as `Inner
191
- // = T`, and `UnsafeCell`s at the same byte offsets as `T`.
192
196
// - See inline comments for other safety justifications.
193
197
//
194
198
// [1] TODO(#896): Write a safety proof before the next stable release.
195
199
unsafe impl < T , I : Invariants > TransparentWrapper < I > for Wrapping < T > {
196
200
type Inner = T ;
197
201
202
+ // SAFETY: Per [1], `Wrapping<T>` has `UnsafeCell`s at the same byte ranges
203
+ // as `Inner = T`, and `UnsafeCell`s at the same byte offsets as `T`.
204
+ //
205
+ // [1] TODO(#896): Write a safety proof before the next stable release.
206
+ type UnsafeCellVariance = Covariant ;
198
207
// SAFETY: Per [1], `Wrapping<T>` has the same layout as `T`, and thus has
199
208
// the same alignment as `T`.
200
209
//
@@ -235,14 +244,17 @@ unsafe impl<T, I: Invariants> TransparentWrapper<I> for Wrapping<T> {
235
244
}
236
245
237
246
// SAFETY: We define `Unalign<T>` to be a `#[repr(C, packed)]` type wrapping a
238
- // single `T` field. Thus, `Unalign<T>` has the same size as `T`, has
239
- // `UnsafeCell`s at the same byte ranges as `T`, and has `UnsafeCell`s at the
240
- // same byte offsets as `T`.
247
+ // single `T` field. Thus, `Unalign<T>` has the same size as `T`.
241
248
//
242
249
// See inline comments for other safety justifications.
243
250
unsafe impl < T , I : Invariants > TransparentWrapper < I > for Unalign < T > {
244
251
type Inner = T ;
245
252
253
+ // SAFETY: `Unalign<T>` is a `#[repr(C, packed)]` type wrapping a single `T`
254
+ // field, and so has `UnsafeCell`s at the same byte ranges as `Inner = T`,
255
+ // and `UnsafeCell`s at the same byte offsets as `T`.
256
+ type UnsafeCellVariance = Covariant ;
257
+
246
258
// SAFETY: Since `Unalign<T>` is `repr(packed)`, it has the alignment 1
247
259
// regardless of `T`'s alignment. Thus, an aligned pointer to `Unalign<T>`
248
260
// is not necessarily an aligned pointer to `T`.
@@ -291,8 +303,19 @@ macro_rules! unsafe_impl_transparent_wrapper_for_atomic {
291
303
// native counterpart, respectively. Per [1], `$atomic` and `$native`
292
304
// have the same size.
293
305
//
294
- // It is "obvious" that each atomic type contains a single `UnsafeCell`
295
- // that covers all bytes of the type, but we can also prove it:
306
+ // [1] TODO(#896), TODO(https://github.com/rust-lang/rust/pull/121943):
307
+ // Cite docs once they've landed.
308
+ $( #[ $attr] ) *
309
+ unsafe impl <$tyvar, I : Invariants > TransparentWrapper <I > for $atomic {
310
+ unsafe_impl_transparent_wrapper_for_atomic!( @inner $atomic [ $native] ) ;
311
+ }
312
+ } ;
313
+ ( @inner $atomic: ty [ $native: ty] ) => {
314
+ type Inner = UnsafeCell <$native>;
315
+
316
+ // SAFETY: It is "obvious" that each atomic type contains a single
317
+ // `UnsafeCell` that covers all bytes of the type, but we can also prove
318
+ // it:
296
319
// - Since `$atomic` provides an API which permits loading and storing
297
320
// values of type `$native` via a `&self` (shared) reference, *some*
298
321
// interior mutation must be happening, and interior mutation can only
@@ -311,18 +334,9 @@ macro_rules! unsafe_impl_transparent_wrapper_for_atomic {
311
334
// set `type Inner = UnsafeCell<$native>`. Thus, `Self` and
312
335
// `Self::Inner` have `UnsafeCell`s covering the same byte ranges.
313
336
//
314
- // See inline comments for safety requirements regarding invariant
315
- // variance.
316
- //
317
337
// [1] TODO(#896), TODO(https://github.com/rust-lang/rust/pull/121943):
318
338
// Cite docs once they've landed.
319
- $( #[ $attr] ) *
320
- unsafe impl <$tyvar, I : Invariants > TransparentWrapper <I > for $atomic {
321
- unsafe_impl_transparent_wrapper_for_atomic!( @inner $atomic [ $native] ) ;
322
- }
323
- } ;
324
- ( @inner $atomic: ty [ $native: ty] ) => {
325
- type Inner = UnsafeCell <$native>;
339
+ type UnsafeCellVariance = Covariant ;
326
340
327
341
// SAFETY: No safety justification is required for an invariant
328
342
// variance.
0 commit comments