#unsafe #nightly #cargo-subcommand #union

nightly app cargo-whynot

Cargo 子命令,用于发现函数为何不安全

3 个版本

0.1.2 2022 年 10 月 27 日
0.1.1 2022 年 10 月 27 日
0.1.0 2022 年 10 月 26 日

#494Cargo 插件

MIT/Apache

61KB
1.5K SLoC

为何不?

githubcrates-io

Cargo 子命令,用于发现函数为何不安全。

需要足够新的 nightly rust 工具链。

# Make sure you have the necessary components installed

$ rustup component add rustc-dev llvm-tools-preview --toolchain nightly

# Install `cargo-whynot` with the nightly toolchain

$ cargo +nightly install cargo-whynot

# Invoke the tool!

$ cargo whynot safe foo

不安全性是什么?

Nomicon 定义

  • 取消引用原始指针
  • 调用不安全函数(包括 C 函数、编译器内建函数和原始分配器)
  • 实现不安全特质
  • 修改静态变量
  • 访问联合体的字段

为何有这个工具?

因为它是一个有趣的实验,通过 hook 到 rustc 来查询驱动。你不应该使用这个工具,因为不安全代码通常很糟糕(它不是),但你可以用它来确定是否有机会使函数“安全”。

示例

以下代码

pub use unsafe_mod::unsafety;

pub unsafe fn foo() {
    let a = unsafety();
    eprintln!("a: {}", a);
}

pub mod unsafe_mod {
    pub unsafe fn unsafety() -> u32 {
        let mut a = 1;
        let a = std::ptr::addr_of_mut!(a);
        // this is the unsafe part
        let b = *a;
        b
    }
}

cargowhynot safe foo

将报告

note: Function is unsafe
  ┌─ src/lib.rs:3:1
  │
3 │ pub unsafe fn foo() {
  │ ^^^^^^^^^^^^^^^^^^^ function is unsafe because:
4 │     let a = unsafety();
  │             ---------- call to unsafe function `unsafe_mod::unsafety`

help:
   ┌─ src/lib.rs:9:5
   │
 9 │     pub unsafe fn unsafety() -> u32 {
   │     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function is unsafe because:
   ·
13 │         let b = *a;
   │                 ^^ dereference of raw pointer
   │
   = this function does a fundamentally unsafe operation
许可
根据您的选择,许可协议为 Apache License 2.0 或 MIT 许可证。
除非您明确说明,否则您根据 Apache-2.0 许可证定义的任何有意提交以包含在此软件包中的贡献,将根据上述许可协议双重许可,不附加任何其他条款或条件。

依赖关系

~11–21MB
~271K SLoC