#安全 #文档 #不安全 #proc-macro

safety-guard

#[safety] 属性生成相应的文档条目和调试断言,如果指定了约束条件

9 个版本

0.1.9 2019 年 4 月 6 日
0.1.8 2019 年 4 月 6 日
0.1.6 2019 年 3 月 19 日

调试 类别中排名 #590

Download history 1/week @ 2024-04-21 6/week @ 2024-06-02 5/week @ 2024-06-09 1/week @ 2024-06-16 7/week @ 2024-06-30 115/week @ 2024-07-28

每月下载 115

MIT/Apache

12KB
131

为函数添加 #[safety] 属性。该属性将添加一个 # Safety 部分,并在调试构建中测试给定的约束条件。

属性有四种不同的形式

  • #[safety("描述")]:仅在文档中包含描述。
  • #[safety(assert(constraint), "描述")]:必须将 constraint 评估为 true
  • #[safety(eq(lhs, rhs), "描述")]:需要将 lhsrhs 设置为相等
  • #[safety]#[safety]#[safety]]: lhsrhs 必须不相等

具有 #[safety] 属性的函数必须标记为 unsafe。否则将生成编译错误。

如果文档中已存在 # 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
}

生成

/// # 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
}

没有约束,仅添加文档

#[safety("`hash` must correspond to the `string`s hash value")]
unsafe fn add_string_with_hash(string: &str, hash: u64) -> u64 {
    // ...
}

生成

/// # Safety
/// - `hash` must correspond to the `string`s hash value
unsafe fn add_string_with_hash(string: &str, hash: u64) -> u64 {
    // ...
}

也可以使用多个 #[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 {
    // ...
}

但是,生成的文档顺序是相反的

/// # 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`");
    // ...
}

依赖关系

~2MB
~46K SLoC