#panic #attributes #error #macro #prove #compiler #compile

macro no-std no-panic

属性宏,要求编译器证明一个函数永远不会panic

31个版本

0.1.30 2024年5月7日
0.1.29 2024年1月20日
0.1.27 2023年11月22日
0.1.26 2023年7月21日
0.1.6 2018年11月3日

过程宏 中排名 #331

Download history 2634/week @ 2024-05-01 1321/week @ 2024-05-08 2080/week @ 2024-05-15 1207/week @ 2024-05-22 1064/week @ 2024-05-29 1874/week @ 2024-06-05 3521/week @ 2024-06-12 2004/week @ 2024-06-19 2196/week @ 2024-06-26 1035/week @ 2024-07-03 1651/week @ 2024-07-10 1784/week @ 2024-07-17 1768/week @ 2024-07-24 2056/week @ 2024-07-31 2112/week @ 2024-08-07 1898/week @ 2024-08-14

每月下载量 8,250
用于 30 个crate (直接使用26个)

MIT/Apache

17KB
155

#[no_panic]

github crates.io docs.rs build status

一个Rust属性宏,要求编译器证明一个函数永远不会panic。

[dependencies]
no-panic = "0.1"
use no_panic::no_panic;

#[no_panic]
fn demo(s: &str) -> &str {
    &s[1..]
}

fn main() {
    println!("{}", demo("input string"));
}

如果函数panic了(或者编译器无法证明该函数不会panic),程序将无法编译,并出现一个链接器错误,该错误会识别出函数名称。让我们通过传递一个不能在第一个字节处切割的字符串来触发它

fn main() {
    println!("{}", demo("\u{1f980}input string"));
}
   Compiling no-panic-demo v0.0.1
error: linking with `cc` failed: exit code: 1
  |
  = note: /no-panic-demo/target/release/deps/no_panic_demo-7170785b672ae322.no_p
anic_demo1-cba7f4b666ccdbcbbf02b7348e5df1b2.rs.rcgu.o: In function `_$LT$no_pani
c_demo..demo..__NoPanic$u20$as$u20$core..ops..drop..Drop$GT$::drop::h72f8f423002
b8d9f':
          no_panic_demo1-cba7f4b666ccdbcbbf02b7348e5df1b2.rs:(.text._ZN72_$LT$no
_panic_demo..demo..__NoPanic$u20$as$u20$core..ops..drop..Drop$GT$4drop17h72f8f42
3002b8d9fE+0x2): undefined reference to `

          ERROR[no-panic]: detected panic in function `demo`
          '
          collect2: error: ld returned 1 exit status

错误并不突出,但请注意错误末尾的 ERROR[no-panic] 部分,它提供了违规函数的名称。


注意事项

  • 可能需要某些优化来证明函数不会panic的函数,在被标记 #[no_panic] 后可能不再能在调试模式下编译。

  • panic检测在链接时在整个依赖图中发生,因此任何不调用链接器的Cargo命令都不会触发panic检测。这包括库crate的 cargo build 以及二进制和库crate的 cargo check

  • 当使用 panic = "abort" 构建代码时,该属性没有用。

如果你发现代码需要优化才能通过 #[no_panic],要么将no_panic作为一个可选依赖,仅在你启用发布构建时才启用,或者在你的Cargo.toml或.cargo/config.toml中添加以下内容以在调试构建中启用非常基本的优化。

[profile.dev]
opt-level = 1

如果你需要证明不发生panic的代码调用来自不同crate的非泛型非内联函数,你可能需要启用薄LTO(Link Time Optimization),以便链接器推断这些函数不发生panic。

[profile.release]
lto = "thin"

如果薄LTO不够用,下一个尝试的选项将是带有单个代码生成单元的胖LTO。

[profile.release]
lto = "fat"
codegen-units = 1

如果你想让no_panic假设你调用的某些函数不会panic,如果它在运行时发生panic,则得到未定义行为,请参阅dtolnay/no-panic#16;尝试将那个调用包装在一个unsafe extern "C"包装器中。


致谢

链接器错误技术基于Kixunil的cratedont_panic。查看该crate以获取其他方便的要求panic缺失的方法。


许可

根据您的选择,在Apache License, Version 2.0MIT license下获得许可。
除非你明确表示,否则,根据Apache-2.0许可,你故意提交给此crate的贡献,应如上所述双重许可,不附加任何额外条款或条件。

依赖

~260–710KB
~17K SLoC