不安全属性

概述

详情

Rust 1.82 在所有版本中添加了将某些属性标记为 unsafe 的能力,以表明它们具有必须遵守的健全性要求。1 不安全属性的语法如下所示

#![allow(unused)]
fn main() {
// SAFETY: there is no other global function of this name
#[unsafe(no_mangle)]
pub fn example() {}
}

unsafe 标记属性强调了存在必须遵守的安全要求,而编译器自身无法验证这些要求。

从 2024 版本开始,现在要求将这些属性标记为 unsafe。以下部分描述了这些属性的安全要求。

1

请参阅 RFC 3325 以了解原始提案。

安全要求

no_mangleexport_namelink_section 属性会影响项目的符号名称和链接行为。 必须小心谨慎,以确保这些属性被正确使用。

由于所有链接库中的符号集合是一个全局命名空间,因此如果库之间存在符号名称冲突,则可能会出现问题。 通常,这对于正常定义的函数来说不是问题,因为 符号修饰 有助于确保符号名称的唯一性。 然而,像 export_name 这样的属性可能会破坏这种唯一性假设。

例如,在之前的版本中,尽管仅包含安全代码,但以下代码在大多数类 Unix 平台上都会崩溃

fn main() {
    println!("Hello, world!");
}

#[export_name = "malloc"]
fn foo() -> usize { 1 }

在 2024 版本中,现在要求将这些属性标记为 unsafe,以强调必须确保符号被正确定义

#![allow(unused)]
fn main() {
// SAFETY: There should only be a single definition of the loop symbol.
#[unsafe(export_name="loop")]
fn arduino_loop() {
    // ...
}
}

迁移

unsafe_attr_outside_unsafe lint 可以更新这些属性以使用 unsafe(...) 格式。 该 lint 是 rust-2024-compatibility lint 组的一部分,该组包含在自动版本迁移中。 为了迁移您的代码以兼容 Rust 2024 版本,请运行

cargo fix --edition

请注意,此自动迁移将无法验证这些属性是否被正确使用。 仍然需要您手动审查它们的使用情况。

或者,您可以手动启用该 lint 以查找需要更新这些属性的位置。

#![allow(unused)]
fn main() {
// Add this to the root of your crate to do a manual migration.
#![warn(unsafe_attr_outside_unsafe)]
}