From 8de4fa045ca4a5270e55f9ba5d6d57bc14504add Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 20 Jun 2024 11:24:20 -0700 Subject: [PATCH] Add 2024 unsafe extern blocks. --- src/SUMMARY.md | 1 + src/rust-2024/unsafe-extern.md | 59 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/rust-2024/unsafe-extern.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 0a31f2c..77764f9 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -49,3 +49,4 @@ - [Rustfmt: Combine all delimited exprs as last argument](rust-2024/rustfmt-overflow-delimited-expr.md) - [`gen` keyword](rust-2024/gen-keyword.md) - [Macro fragment specifiers](rust-2024/macro-fragment-specifiers.md) + - [`unsafe extern` blocks](rust-2024/unsafe-extern.md) diff --git a/src/rust-2024/unsafe-extern.md b/src/rust-2024/unsafe-extern.md new file mode 100644 index 0000000..01e6b0c --- /dev/null +++ b/src/rust-2024/unsafe-extern.md @@ -0,0 +1,59 @@ +# `unsafe extern` blocks + +🚧 The 2024 Edition has not yet been released and hence this section is still "under construction". +More information may be found in the tracking issue at . + +## Summary + +- [`extern` blocks] must now be marked with the `unsafe` keyword. + +[`extern` blocks]: ../../reference/items/external-blocks.html + +## Details + +Rust 1.xx added the ability in all editions to mark [`extern` blocks] with the `unsafe` keyword.[^RFC3484] Adding the `unsafe` keyword helps to emphasize that it is the responsibility of the author of the `extern` block to ensure that the signatures are correct. If the signatures are not correct, then it may result in undefined behavior. + +The syntax for an unsafe `extern` block looks like this: + +```rust +# #![feature(unsafe_extern_blocks)] + +unsafe extern "C" { + // sqrt (from libm) may be called with any `f64` + pub safe fn sqrt(x: f64) -> f64; + + // strlen (from libc) requires a valid pointer, + // so we mark it as being an unsafe fn + pub unsafe fn strlen(p: *const std::ffi::c_char) -> usize; + + // this function doesn't say safe or unsafe, so it defaults to unsafe + pub fn free(p: *mut core::ffi::c_void); + + pub safe static IMPORTANT_BYTES: [u8; 256]; +} +``` + +In addition to being able to mark an `extern` block as `unsafe`, you can also specify if individual items in the `extern` block are `safe` or `unsafe`. Items marked as `safe` can be used without an `unsafe` block. + +Starting with the 2024 Edition, it is now required to include the `unsafe` keyword on an `extern` block. This is intended to make it very clear that there are safety requirements that must be upheld by the extern definitions. + +[^RFC3484]: See [RFC 3484](https://github.com/rust-lang/rfcs/blob/master/text/3484-unsafe-extern-blocks.md) for the original proposal. + +## Migration + +The [`missing_unsafe_on_extern`] lint can update `extern` blocks to add the `unsafe` keyword. 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: + +```sh +cargo fix --edition +``` + +Just beware that this automatic migration will not be able to verify that the signatures in the `extern` block are correct. It is still your responsibility to manually review their definition. + +Alternatively, you can manually enable the lint to find places where there are `unsafe` blocks that need to be updated. + +```rust +// Add this to the root of your crate to do a manual migration. +#![warn(missing_unsafe_on_extern)] +``` + +[`missing_unsafe_on_extern`]: ../../rustc/lints/listing/allowed-by-default.html#missing-unsafe-on-extern