Skip to content

Commit 6450181

Browse files
authored
Replace safety_comment! with const blocks (#2483)
Replace: safety_comment! { /// SAFETY: /// ... foo!(); bar!(); } With: // SAFETY: ... const _: () = unsafe { foo!(); bar!(); }; Remove the `safety_comment!` macro. gherrit-pr-id: Id5df96f57c34a4e7e8d261399f01fd23cded339e
1 parent 85106c5 commit 6450181

File tree

11 files changed

+914
-975
lines changed

11 files changed

+914
-975
lines changed

src/byteorder.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -489,19 +489,19 @@ example of how it can be used for parsing UDP packets.
489489
#[cfg(not(any(feature = "derive", test)))]
490490
impl_known_layout!(O => $name<O>);
491491

492-
safety_comment! {
493-
/// SAFETY:
494-
/// `$name<O>` is `repr(transparent)`, and so it has the same layout
495-
/// as its only non-zero field, which is a `u8` array. `u8` arrays
496-
/// are `Immutable`, `TryFromBytes`, `FromZeros`, `FromBytes`,
497-
/// `IntoBytes`, and `Unaligned`.
492+
#[allow(unused_unsafe)] // Unused when `feature = "derive"`.
493+
// SAFETY: `$name<O>` is `repr(transparent)`, and so it has the same
494+
// layout as its only non-zero field, which is a `u8` array. `u8` arrays
495+
// are `Immutable`, `TryFromBytes`, `FromZeros`, `FromBytes`,
496+
// `IntoBytes`, and `Unaligned`.
497+
const _: () = unsafe {
498498
impl_or_verify!(O => Immutable for $name<O>);
499499
impl_or_verify!(O => TryFromBytes for $name<O>);
500500
impl_or_verify!(O => FromZeros for $name<O>);
501501
impl_or_verify!(O => FromBytes for $name<O>);
502502
impl_or_verify!(O => IntoBytes for $name<O>);
503503
impl_or_verify!(O => Unaligned for $name<O>);
504-
}
504+
};
505505

506506
impl<O> Default for $name<O> {
507507
#[inline(always)]

src/impls.rs

Lines changed: 523 additions & 569 deletions
Large diffs are not rendered by default.

src/lib.rs

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,45 +1010,45 @@ impl_known_layout!(
10101010
);
10111011
impl_known_layout!(const N: usize, T => [T; N]);
10121012

1013-
safety_comment! {
1014-
/// SAFETY:
1015-
/// `str` has the same representation as `[u8]`. `ManuallyDrop<T>` [1],
1016-
/// `UnsafeCell<T>` [2], and `Cell<T>` [3] have the same representation as
1017-
/// `T`.
1018-
///
1019-
/// [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
1020-
///
1021-
/// `ManuallyDrop<T>` is guaranteed to have the same layout and bit
1022-
/// validity as `T`
1023-
///
1024-
/// [2] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.UnsafeCell.html#memory-layout:
1025-
///
1026-
/// `UnsafeCell<T>` has the same in-memory representation as its inner
1027-
/// type `T`.
1028-
///
1029-
/// [3] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.Cell.html#memory-layout:
1030-
///
1031-
/// `Cell<T>` has the same in-memory representation as `T`.
1032-
unsafe_impl_known_layout!(#[repr([u8])] str);
1013+
// SAFETY: `str` has the same representation as `[u8]`. `ManuallyDrop<T>` [1],
1014+
// `UnsafeCell<T>` [2], and `Cell<T>` [3] have the same representation as `T`.
1015+
//
1016+
// [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
1017+
//
1018+
// `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
1019+
// `T`
1020+
//
1021+
// [2] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.UnsafeCell.html#memory-layout:
1022+
//
1023+
// `UnsafeCell<T>` has the same in-memory representation as its inner type
1024+
// `T`.
1025+
//
1026+
// [3] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.Cell.html#memory-layout:
1027+
//
1028+
// `Cell<T>` has the same in-memory representation as `T`.
1029+
const _: () = unsafe {
1030+
unsafe_impl_known_layout!(
1031+
#[repr([u8])]
1032+
str
1033+
);
10331034
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] ManuallyDrop<T>);
10341035
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] UnsafeCell<T>);
10351036
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] Cell<T>);
1036-
}
1037+
};
10371038

1038-
safety_comment! {
1039-
/// SAFETY:
1040-
/// - By consequence of the invariant on `T::MaybeUninit` that `T::LAYOUT`
1041-
/// and `T::MaybeUninit::LAYOUT` are equal, `T` and `T::MaybeUninit`
1042-
/// have the same:
1043-
/// - Fixed prefix size
1044-
/// - Alignment
1045-
/// - (For DSTs) trailing slice element size
1046-
/// - By consequence of the above, referents `T::MaybeUninit` and `T` have
1047-
/// the require the same kind of pointer metadata, and thus it is valid to
1048-
/// perform an `as` cast from `*mut T` and `*mut T::MaybeUninit`, and this
1049-
/// operation preserves referent size (ie, `size_of_val_raw`).
1050-
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T::MaybeUninit)] MaybeUninit<T>);
1051-
}
1039+
// SAFETY:
1040+
// - By consequence of the invariant on `T::MaybeUninit` that `T::LAYOUT` and
1041+
// `T::MaybeUninit::LAYOUT` are equal, `T` and `T::MaybeUninit` have the same:
1042+
// - Fixed prefix size
1043+
// - Alignment
1044+
// - (For DSTs) trailing slice element size
1045+
// - By consequence of the above, referents `T::MaybeUninit` and `T` have the
1046+
// require the same kind of pointer metadata, and thus it is valid to perform
1047+
// an `as` cast from `*mut T` and `*mut T::MaybeUninit`, and this operation
1048+
// preserves referent size (ie, `size_of_val_raw`).
1049+
const _: () = unsafe {
1050+
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T::MaybeUninit)] MaybeUninit<T>)
1051+
};
10521052

10531053
/// Analyzes whether a type is [`FromZeros`].
10541054
///

src/pointer/transmute.rs

Lines changed: 91 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,13 @@ where
217217
pub(crate) enum BecauseInvariantsEq {}
218218

219219
macro_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

226229
impl_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

438435
impl_transitive_transmute_from!(T: ?Sized => Cell<T> => T => UnsafeCell<T>);
439436
impl_transitive_transmute_from!(T: ?Sized => UnsafeCell<T> => T => Cell<T>);

0 commit comments

Comments
 (0)