Skip to content

Commit 070a55f

Browse files
committed
Merge PR #309: Add 2024 unsafe extern blocks
2 parents cb58c43 + 8de4fa0 commit 070a55f

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@
4949
- [Rustfmt: Combine all delimited exprs as last argument](rust-2024/rustfmt-overflow-delimited-expr.md)
5050
- [`gen` keyword](rust-2024/gen-keyword.md)
5151
- [Macro fragment specifiers](rust-2024/macro-fragment-specifiers.md)
52+
- [`unsafe extern` blocks](rust-2024/unsafe-extern.md)

src/rust-2024/unsafe-extern.md

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# `unsafe extern` blocks
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/123743>.
5+
6+
## Summary
7+
8+
- [`extern` blocks] must now be marked with the `unsafe` keyword.
9+
10+
[`extern` blocks]: ../../reference/items/external-blocks.html
11+
12+
## Details
13+
14+
Rust 1.xx <!--TODO--> 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.
15+
16+
The syntax for an unsafe `extern` block looks like this:
17+
18+
```rust
19+
# #![feature(unsafe_extern_blocks)]
20+
21+
unsafe extern "C" {
22+
// sqrt (from libm) may be called with any `f64`
23+
pub safe fn sqrt(x: f64) -> f64;
24+
25+
// strlen (from libc) requires a valid pointer,
26+
// so we mark it as being an unsafe fn
27+
pub unsafe fn strlen(p: *const std::ffi::c_char) -> usize;
28+
29+
// this function doesn't say safe or unsafe, so it defaults to unsafe
30+
pub fn free(p: *mut core::ffi::c_void);
31+
32+
pub safe static IMPORTANT_BYTES: [u8; 256];
33+
}
34+
```
35+
36+
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.
37+
38+
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.
39+
40+
[^RFC3484]: See [RFC 3484](https://github.com/rust-lang/rfcs/blob/master/text/3484-unsafe-extern-blocks.md) for the original proposal.
41+
42+
## Migration
43+
44+
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:
45+
46+
```sh
47+
cargo fix --edition
48+
```
49+
50+
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.
51+
52+
Alternatively, you can manually enable the lint to find places where there are `unsafe` blocks that need to be updated.
53+
54+
```rust
55+
// Add this to the root of your crate to do a manual migration.
56+
#![warn(missing_unsafe_on_extern)]
57+
```
58+
59+
[`missing_unsafe_on_extern`]: ../../rustc/lints/listing/allowed-by-default.html#missing-unsafe-on-extern

0 commit comments

Comments
 (0)