Crates.io | safety-guard |
lib.rs | safety-guard |
version | 0.1.9 |
source | src |
created_at | 2019-03-12 19:21:03.330022 |
updated_at | 2019-04-06 17:49:41.810612 |
description | #[safety] attribute to generate a corresponding doc entry and a debug assertion if a constraint is specified. |
homepage | |
repository | https://gitlab.com/tdiekmann/safety-guard |
max_upload_size | |
id | 120337 |
size | 25,603 |
Adds a #[safety]
attribute for functions. The attribute 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 included in the documentation.#[safety(assert(constraint), "Description")]
: constraint
must evaluate to true
.#[safety(eq(lhs, rhs), "Description")]
: lhs
and rhs
needs to be equal#[safety(ne(lhs, rhs), "Description")]
: lhs
and rhs
must not be equalA 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.
#[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:
#[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:
#[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`");
// ...
}