[−][src]Attribute Macro safety_guard::safety
#[safety]
Adds a # Safety
section to the documentation of the function and tests the given constraints
in debug builds.
The attribute has four different forms:
#[safety("Description")]
: Only the description is added to the documentation#[safety(assert(constraint), "Description")]
:constraint
must evaluate totrue
.#[safety(eq(lhs, rhs), "Description")]
:lhs
andrhs
needs to be equal#[safety(ne(lhs, rhs), "Description")]
:lhs
andrhs
must not be equal
A function with a #[safety]
attribute must be marked as unsafe
. Otherwise a compile error
is generated.
If # Safety
already exists in the documentation, the heading is not added.
Examples
use safety_guard::safety; #[safety(assert(lhs.checked_add(rhs).is_some()), "`lhs` + `rhs` must not overflow")] unsafe fn add_unchecked(lhs: usize, rhs: usize) -> usize { lhs + rhs }
generates
/// # Safety /// - `lhs` + `rhs` must not overflow unsafe fn add_unchecked(lhs: usize, rhs: usize) -> usize { debug_assert!(lhs.checked_add(rhs).is_some(), "`lhs` + `rhs` must not overflow"); lhs + rhs }
Without a constraint, only the documentation is added:
use safety_guard::safety; #[safety("`hash` must correspond to the `string`s hash value")] unsafe fn add_string_with_hash(string: &str, hash: u64) -> u64 { // ... }
generates
/// # Safety /// - `hash` must correspond to the `string`s hash value unsafe fn add_string_with_hash(string: &str, hash: u64) -> u64 { // ... }
It is also possible to use multiple #[safety]
attributes:
use safety_guard::safety; #[safety(eq(ptr as usize % layout.align(), 0), "`layout` must *fit* the `ptr`")] #[safety(assert(new_size > 0), "`new_size` must be greater than zero")] #[safety( "`new_size`, when rounded up to the nearest multiple of `layout.align()`, must not \ overflow (i.e., the rounded value must be less than `usize::MAX`)." )] unsafe fn realloc( ptr: *mut u8, layout: Layout, new_size: usize, ) -> *mut u8 { // ... }
However, the documentation is generated in reversed order:
/// # Safety /// - `new_size`, when rounded up to the nearest multiple of `layout.align()`, must not /// overflow (i.e., the rounded value must be less than `usize::MAX`). /// - `new_size` must be greater than zero /// - `layout` must *fit* the `ptr` unsafe fn realloc( ptr: *mut u8, layout: Layout, new_size: usize, ) -> *mut u8 { debug_assert!(new_size > 0, "`new_size` must be greater than zero"); debug_assert_eq!(ptr as usize % layout.align(), 0, "`layout` must *fit* the `ptr`"); // ... }