[−][src]Crate safe
A custom attribute for declaring why an unsafe
block is correct.
Examples
The most basic way this attribute can be used is by annotating an unsafe
block and providing a reason
for why it is valid.
let mut x: u32 = 42; let x_ptr = &mut x as *mut u32; #[safe(reason = "This is the only reference to x")] unsafe { x_ptr.write(7); }
Unsafe code often has constraints that must be valid before or after the code is run.
You can provide an assertion which will be executed with debug_assert!()
immediately before the block executes by adding a requires = "..."
to
the attribute.
let x: u32 = 42; let x_ptr = &x as *const u32; #[safe( reason = "The pointer points to a valid integer", requires = "!x_ptr.is_null()" )] unsafe { assert_eq!(42, x_ptr.read()); }
Likewise, for conditions which must be upheld after the unsafe
block, you
can provide an ensures
assertion.
let mut allocated: *mut u32; #[safe( reason = "Malloc will always return a non-null pointer unless there is an out-of-memory error", ensures = "!allocated.is_null()" )] unsafe { allocated = libc::malloc(std::mem::size_of::<u32>()) as *mut u32; }
Nightly Feature Flags
Applying custom attributes to unsafe
blocks currently requires two
nightly
features:
stmt_expr_attributes
- becauseunsafe {}
is technically an expression (tracking issue)proc_macro_hygiene
- the result of expanding the#[safe]
macro is an expression which, in general (but not in our case), can result in possible hygiene issues (tracking issue)
Attribute Macros
safe | A custom attribute for explaining why an |