|
| 1 | +# Unsafe attributes |
| 2 | + |
| 3 | +🚧 The 2024 Edition has not yet been released and hence this section is still "under construction". |
| 4 | +More information may be found in the tracking issue at <https://github.com/rust-lang/rust/issues/123757>. |
| 5 | + |
| 6 | +## Summary |
| 7 | + |
| 8 | +- The following attributes must now be marked as `unsafe`: |
| 9 | + - [`export_name`] |
| 10 | + - [`link_section`] |
| 11 | + - [`no_mangle`] |
| 12 | + |
| 13 | +[`export_name`]: ../../reference/abi.html#the-export_name-attribute |
| 14 | +[`link_section`]: ../../reference/abi.html#the-link_section-attribute |
| 15 | +[`no_mangle`]: ../../reference/abi.html#the-no_mangle-attribute |
| 16 | + |
| 17 | +## Details |
| 18 | + |
| 19 | +Rust 1.xx <!--TODO--> added the ability in all editions to mark certain attributes as `unsafe` to indicate that they have soundness requirements that must be upheld.[^RFC3325] The syntax for an unsafe attribute looks like this: |
| 20 | + |
| 21 | +```rust |
| 22 | +# #![feature(unsafe_attributes)] |
| 23 | +// SAFETY: there is no other global function of this name |
| 24 | +#[unsafe(no_mangle)] |
| 25 | +pub fn example() {} |
| 26 | +``` |
| 27 | + |
| 28 | +Marking the attribute with `unsafe` highlights that there are safety requirements that must be upheld that the compiler cannot verify on its own. |
| 29 | + |
| 30 | +Starting with the 2024 Edition, it is now required to mark these attributes as `unsafe`. The following section describes the safety requirements for these attributes. |
| 31 | + |
| 32 | +[^RFC3325]: See [RFC 3325](https://rust-lang.github.io/rfcs/3325-unsafe-attributes.html) for the original proposal. |
| 33 | + |
| 34 | +### Safety requirements |
| 35 | + |
| 36 | +The [`no_mangle`], [`export_name`], and [`link_section`] attributes influence the symbol names and linking behavior of items. Care must be taken to ensure that these attributes are used correctly. |
| 37 | + |
| 38 | +Because the set of symbols across all linked libraries is a global namespace, there can be issues if there is a symbol name collision between libraries. Typically this isn't an issue for normally defined functions because [symbol mangling] helps ensure that the symbol name is unique. However, attributes like `export_name` can upset that assumption of uniqueness. |
| 39 | + |
| 40 | +For example, in previous editions the following crashes on most Unix-like platforms despite containing only safe code: |
| 41 | + |
| 42 | +```rust,no_run,edition2021 |
| 43 | +fn main() { |
| 44 | + println!("Hello, world!"); |
| 45 | +} |
| 46 | +
|
| 47 | +#[export_name = "malloc"] |
| 48 | +fn foo() -> usize { 1 } |
| 49 | +``` |
| 50 | + |
| 51 | +In the 2024 Edition, it is now required to mark these attributes as unsafe to emphasize that it is required to ensure that the symbol is defined correctly: |
| 52 | + |
| 53 | +<!-- TODO: edition2024 --> |
| 54 | +```rust |
| 55 | +# #![feature(unsafe_attributes)] |
| 56 | +// SAFETY: There should only be a single definition of the loop symbol. |
| 57 | +#[unsafe(export_name="loop")] |
| 58 | +fn arduino_loop() { |
| 59 | + // ... |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +[symbol mangling]: ../../rustc/symbol-mangling/index.html |
| 64 | +[`unsafe_attr_outside_unsafe`]: ../../rustc/lints/listing/allowed-by-default.html#unsafe-attr-outside-unsafe |
| 65 | + |
| 66 | +## Migration |
| 67 | + |
| 68 | +The [`unsafe_attr_outside_unsafe`] lint can update these attributes to use the `unsafe(...)` format. The lint is part of the `rust-2024-compatibility` lint group which is included in the automatic edition migration. In order to migrate your code to be Rust 2024 Edition compatible, run: |
| 69 | + |
| 70 | +```sh |
| 71 | +cargo fix --edition |
| 72 | +``` |
| 73 | + |
| 74 | +Just beware that this automatic migration will not be able to verify that these attributes are being used correctly. It is still your responsibility to manually review their usage. |
| 75 | + |
| 76 | +Alternatively, you can manually enable the lint to find places where these attributes need to be updated. |
| 77 | + |
| 78 | +```rust |
| 79 | +// Add this to the root of your crate to do a manual migration. |
| 80 | +#![warn(unsafe_attr_outside_unsafe)] |
| 81 | +``` |
0 commit comments