[−][src]Attribute Macro require_unsafe_in_body::require_unsafe_in_bodies
#[require_unsafe_in_bodies]
impl
or trait
block attribute to require unsafe
in the associated
functions' bodies no matter the unsafe
-ness of their APIs.
Example
pub trait SwapKeys<Key> where Key : Copy + Eq, { fn contains_key (self: &'_ Self, key: Key) -> bool; /// Swaps two values within `self`, without checking that the keys are valid. /// /// # Safety /// /// The keys must be valid: /// /// - `self.contains_key(k1)`, /// /// - `self.contains_key(k2)`, /// /// - `k1 ≠ k2` unsafe fn swap_keys_unchecked (self: &'_ mut Self, k1: Key, k2: Key); } #[require_unsafe_in_bodies] impl<T> SwapKeys<usize> for [T] { #[inline] fn contains_key (self: &'_ Self, idx: usize) -> bool { idx < self.len() } #[inline] unsafe fn swap_keys_unchecked (self: &'_ mut Self, i: usize, j: usize) { let at_i: *mut T = unsafe { // Safety: `i < self.len()` debug_assert!(i < self.len()); self.get_unchecked_mut(i) }; let at_j: *mut T = unsafe { // Safety: `j < self.len()` debug_assert!(j < self.len()); self.get_unchecked_mut(j) }; unsafe { // Safety: `at_i` and `at_j` do not alias since `i ≠ j` debug_assert_ne!(i, j); ::core::ptr::swap_nonoverlapping(at_i, at_j, 1); } } }
How does the macro work? / what does it expand to?
struct Foo; #[require_unsafe_in_bodies] impl Foo { unsafe fn foo<T : Display> (&self, x: i32, y: &T) { // body of foo } fn bar (&self) { // body of bar } }
expands to:
struct Foo; impl Foo { unsafe fn foo<T : Display> (&self, arg_1: i32, arg_2: &T) { trait Helper { fn inner<T : Display> (&self, x: i32, y: &T); } impl Helper for Foo { #[inline(always)] fn inner<T : Display> (&self, x: i32, y: &T) { // body of foo } } <Self as Helper>::inner::<T>(self, arg_1, arg_2) } fn bar (&self) { // body of bar } }
-
foo()
The
inner
function can be marked non-unsafe
since it is private; and by not being markedunsafe
, thebody of foo
no longer hasunsafe
block hygiene. -
bar()
Since
bar()
is not markedunsafe
, it already naturally requiresunsafe
in its body, thus not requiring any change.