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
每月下载量 8,250
用于 30 个crate (直接使用26个)
17KB
155 行
#[no_panic]
一个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.0或MIT license下获得许可。除非你明确表示,否则,根据Apache-2.0许可,你故意提交给此crate的贡献,应如上所述双重许可,不附加任何额外条款或条件。
依赖
~260–710KB
~17K SLoC