1 个不稳定版本
0.0.1 | 2023 年 2 月 9 日 |
---|
#15 in #prove
14KB
111 行
#[no_panics]
no-panic
的分支,支持异步函数
Rust 属性宏,要求编译器证明函数永远不会发生恐慌。
使用方法
使用别名
[dependencies]
no-panic = { package = "no-panic", version = "0.0" }
use no_panic::no_panic;
#[no_panic]
fn demo(s: &str) -> &str {
&s[1..]
}
fn main() {
println!("{}", demo("input string"));
}
如果函数发生恐慌(或编译器无法证明函数不会发生恐慌),则程序将因为链接器错误而无法编译,并标识出函数名称。让我们通过传递一个不能在第一个字节处分割的字符串来触发它
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] 部分,它提供了有问题的函数名称。
编译器支持:需要 rustc 1.39+
注意事项
-
可能需要某些优化来证明它们不会发生恐慌的函数在标记
#[no_panic]
后,在调试模式下可能无法编译。 -
恐慌检测在链接时发生在整个依赖图上,因此任何不调用链接器的 Cargo 命令都不会触发恐慌检测。这包括库包的
cargo build
和二进制包或库包的cargo check
。 -
在设置了
panic = "abort"
的代码中,此属性是无效的。
如果你发现代码需要优化才能通过 #[no_panic]
,则可以将 no-panic 设置为一个可选依赖项,仅在发布构建中启用,或者将以下部分添加到 Cargo.toml 中以在调试构建中启用非常基本的优化。
[profile.dev]
opt-level = 1
如果你需要证明的代码没有恐慌,但调用了来自不同包的非泛型非内联函数,你可能需要启用链接器的瘦 LTO 来推断这些函数不会恐慌。
[profile.release]
lto = "thin"
如果您想让no_panic假设您调用的某个函数不会panic,并在运行时发生panic时得到未定义行为,请参阅dtolnay/no-panic#16;尝试使用unsafe extern "C"
包装器来调用该函数。
致谢
基于:https://github.com/dtolnay/no-panic
链接器错误技术基于Kixunil的crate dont_panic
。查看该crate以获取其他要求panic不存在的方便方法。
许可协议
根据您的选择,在以下任一协议下授权:Apache License, Version 2.0或MIT许可证。除非您明确表示,否则根据Apache-2.0许可证定义,您有意提交以包含在本crate中的任何贡献都应按上述方式双授权,不附加任何额外条款或条件。
依赖项
~1.5MB
~35K SLoC