@@ -217,10 +217,13 @@ where
217217pub ( crate ) enum BecauseInvariantsEq { }
218218
219219macro_rules! unsafe_impl_invariants_eq {
220- ( $tyvar: ident => $t: ty, $u: ty) => {
220+ ( $tyvar: ident => $t: ty, $u: ty) => { {
221+ crate :: util:: macros:: __unsafe( ) ;
222+ // SAFETY: The caller promises that this is sound.
221223 unsafe impl <$tyvar> InvariantsEq <$t> for $u { }
224+ // SAFETY: The caller promises that this is sound.
222225 unsafe impl <$tyvar> InvariantsEq <$u> for $t { }
223- } ;
226+ } } ;
224227}
225228
226229impl_transitive_transmute_from ! ( T => MaybeUninit <T > => T => Wrapping <T >) ;
@@ -342,98 +345,92 @@ where
342345{
343346}
344347
345- safety_comment ! {
346- /// SAFETY:
347- /// - `ManuallyDrop<T>` has the same size as `T` [1]
348- /// - `ManuallyDrop<T>` has the same validity as `T` [1]
349- ///
350- /// [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
351- ///
352- /// `ManuallyDrop<T>` is guaranteed to have the same layout and bit
353- /// validity as `T`
354- unsafe_impl_for_transparent_wrapper!( T : ?Sized => ManuallyDrop <T >) ;
355-
356- /// SAFETY:
357- /// - `Unalign<T>` promises to have the same size as `T`.
358- /// - `Unalign<T>` promises to have the same validity as `T`.
359- unsafe_impl_for_transparent_wrapper!( T => Unalign <T >) ;
360- /// SAFETY:
361- /// `Unalign<T>` promises to have the same size and validity as `T`. Given
362- /// `u: &Unalign<T>`, it is already possible to obtain `let t =
363- /// u.try_deref().unwrap()`. Because `Unalign<T>` has the same size as `T`,
364- /// the returned `&T` must point to the same referent as `u`, and thus it
365- /// must be sound for these two references to exist at the same time since
366- /// it's already possible for safe code to get into this state.
367- unsafe_impl_invariants_eq!( T => T , Unalign <T >) ;
368-
369- /// SAFETY:
370- /// - `Wrapping<T>` has the same size as `T` [1].
371- /// - `Wrapping<T>` has only one field, which is `pub` [2]. We are also
372- /// guaranteed per that `Wrapping<T>` has the same layout as `T` [1]. The
373- /// only way for both of these to be true simultaneously is for
374- /// `Wrapping<T>` to have the same bit validity as `T`. In particular, in
375- /// order to change the bit validity, one of the following would need to
376- /// happen:
377- /// - `Wrapping` could change its `repr`, but this would violate the
378- /// layout guarantee.
379- /// - `Wrapping` could add or change its fields, but this would be a
380- /// stability-breaking change.
381- ///
382- /// [1] Per https://doc.rust-lang.org/1.85.0/core/num/struct.Wrapping.html#layout-1:
383- ///
384- /// `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
385- ///
386- /// [2] Definition from https://doc.rust-lang.org/1.85.0/core/num/struct.Wrapping.html:
387- ///
388- /// ```
389- /// #[repr(transparent)]
390- /// pub struct Wrapping<T>(pub T);
391- /// ```
392- unsafe_impl_for_transparent_wrapper!( T => Wrapping <T >) ;
393- /// SAFETY:
394- /// By the preceding safety proof, `Wrapping<T>` and `T` have the same
395- /// layout and bit validity. Since a `Wrapping<T>`'s `T` field is `pub`,
396- /// given `w: &Wrapping<T>`, it's possible to do `let t = &w.t`, which means
397- /// that it's already possible for safe code to obtain a `&Wrapping<T>` and
398- /// a `&T` pointing to the same referent at the same time. Thus, this must
399- /// be sound.
400- unsafe_impl_invariants_eq!( T => T , Wrapping <T >) ;
401-
402- /// SAFETY:
403- /// - `UnsafeCell<T>` has the same size as `T` [1].
404- /// - Per [1], `UnsafeCell<T>` has the same bit validity as `T`. Technically
405- /// the term "representation" doesn't guarantee this, but the subsequent
406- /// sentence in the documentation makes it clear that this is the
407- /// intention.
408- ///
409- /// [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
410- ///
411- /// `UnsafeCell<T>` has the same in-memory representation as its inner
412- /// type `T`. A consequence of this guarantee is that it is possible to
413- /// convert between `T` and `UnsafeCell<T>`.
414- unsafe_impl_for_transparent_wrapper!( T : ?Sized => UnsafeCell <T >) ;
415-
416- /// SAFETY:
417- /// - `Cell<T>` has the same size as `T` [1].
418- /// - Per [1], `Cell<T>` has the same bit validity as `T`. Technically the
419- /// term "representation" doesn't guarantee this, but it does promise to
420- /// have the "same memory layout and caveats as `UnsafeCell<T>`." The
421- /// `UnsafeCell` docs [2] make it clear that bit validity is the intention
422- /// even if that phrase isn't used.
423- ///
424- /// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.Cell.html#memory-layout:
425- ///
426- /// `Cell<T>` has the same memory layout and caveats as `UnsafeCell<T>`.
427- /// In particular, this means that `Cell<T>` has the same in-memory
428- /// representation as its inner type `T`.
429- ///
430- /// [2] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
431- ///
432- /// `UnsafeCell<T>` has the same in-memory representation as its inner
433- /// type `T`. A consequence of this guarantee is that it is possible to
434- /// convert between `T` and `UnsafeCell<T>`.
435- unsafe_impl_for_transparent_wrapper!( T : ?Sized => Cell <T >) ;
436- }
348+ // SAFETY:
349+ // - `ManuallyDrop<T>` has the same size as `T` [1]
350+ // - `ManuallyDrop<T>` has the same validity as `T` [1]
351+ //
352+ // [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
353+ //
354+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
355+ // `T`
356+ const _: ( ) = unsafe { unsafe_impl_for_transparent_wrapper ! ( T : ?Sized => ManuallyDrop <T >) } ;
357+
358+ // SAFETY:
359+ // - `Unalign<T>` promises to have the same size as `T`.
360+ // - `Unalign<T>` promises to have the same validity as `T`.
361+ const _: ( ) = unsafe { unsafe_impl_for_transparent_wrapper ! ( T => Unalign <T >) } ;
362+ // SAFETY: `Unalign<T>` promises to have the same size and validity as `T`.
363+ // Given `u: &Unalign<T>`, it is already possible to obtain `let t =
364+ // u.try_deref().unwrap()`. Because `Unalign<T>` has the same size as `T`, the
365+ // returned `&T` must point to the same referent as `u`, and thus it must be
366+ // sound for these two references to exist at the same time since it's already
367+ // possible for safe code to get into this state.
368+ const _: ( ) = unsafe { unsafe_impl_invariants_eq ! ( T => T , Unalign <T >) } ;
369+
370+ // SAFETY:
371+ // - `Wrapping<T>` has the same size as `T` [1].
372+ // - `Wrapping<T>` has only one field, which is `pub` [2]. We are also
373+ // guaranteed per that `Wrapping<T>` has the same layout as `T` [1]. The only
374+ // way for both of these to be true simultaneously is for `Wrapping<T>` to
375+ // have the same bit validity as `T`. In particular, in order to change the
376+ // bit validity, one of the following would need to happen:
377+ // - `Wrapping` could change its `repr`, but this would violate the layout
378+ // guarantee.
379+ // - `Wrapping` could add or change its fields, but this would be a
380+ // stability-breaking change.
381+ //
382+ // [1] Per https://doc.rust-lang.org/1.85.0/core/num/struct.Wrapping.html#layout-1:
383+ //
384+ // `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
385+ //
386+ // [2] Definition from https://doc.rust-lang.org/1.85.0/core/num/struct.Wrapping.html:
387+ //
388+ // ```
389+ // #[repr(transparent)]
390+ // pub struct Wrapping<T>(pub T);
391+ // ```
392+ const _: ( ) = unsafe { unsafe_impl_for_transparent_wrapper ! ( T => Wrapping <T >) } ;
393+
394+ // SAFETY: By the preceding safety proof, `Wrapping<T>` and `T` have the same
395+ // layout and bit validity. Since a `Wrapping<T>`'s `T` field is `pub`, given
396+ // `w: &Wrapping<T>`, it's possible to do `let t = &w.t`, which means that it's
397+ // already possible for safe code to obtain a `&Wrapping<T>` and a `&T` pointing
398+ // to the same referent at the same time. Thus, this must be sound.
399+ const _: ( ) = unsafe { unsafe_impl_invariants_eq ! ( T => T , Wrapping <T >) } ;
400+
401+ // SAFETY:
402+ // - `UnsafeCell<T>` has the same size as `T` [1].
403+ // - Per [1], `UnsafeCell<T>` has the same bit validity as `T`. Technically the
404+ // term "representation" doesn't guarantee this, but the subsequent sentence
405+ // in the documentation makes it clear that this is the intention.
406+ //
407+ // [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
408+ //
409+ // `UnsafeCell<T>` has the same in-memory representation as its inner type
410+ // `T`. A consequence of this guarantee is that it is possible to convert
411+ // between `T` and `UnsafeCell<T>`.
412+ const _: ( ) = unsafe { unsafe_impl_for_transparent_wrapper ! ( T : ?Sized => UnsafeCell <T >) } ;
413+
414+ // SAFETY:
415+ // - `Cell<T>` has the same size as `T` [1].
416+ // - Per [1], `Cell<T>` has the same bit validity as `T`. Technically the term
417+ // "representation" doesn't guarantee this, but it does promise to have the
418+ // "same memory layout and caveats as `UnsafeCell<T>`." The `UnsafeCell` docs
419+ // [2] make it clear that bit validity is the intention even if that phrase
420+ // isn't used.
421+ //
422+ // [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.Cell.html#memory-layout:
423+ //
424+ // `Cell<T>` has the same memory layout and caveats as `UnsafeCell<T>`. In
425+ // particular, this means that `Cell<T>` has the same in-memory representation
426+ // as its inner type `T`.
427+ //
428+ // [2] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
429+ //
430+ // `UnsafeCell<T>` has the same in-memory representation as its inner type
431+ // `T`. A consequence of this guarantee is that it is possible to convert
432+ // between `T` and `UnsafeCell<T>`.
433+ const _: ( ) = unsafe { unsafe_impl_for_transparent_wrapper ! ( T : ?Sized => Cell <T >) } ;
437434
438435impl_transitive_transmute_from ! ( T : ?Sized => Cell <T > => T => UnsafeCell <T >) ;
439436impl_transitive_transmute_from ! ( T : ?Sized => UnsafeCell <T > => T => Cell <T >) ;
0 commit comments