Skip to content

Clarify that safe extern items do not require unsafe #1970

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/items/external-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ r[items.extern.allowed-kinds]
Two kinds of item _declarations_ are allowed in external blocks: [functions] and
[statics].

r[items.extern.fn-safety]
Calling functions or accessing statics that are declared in external blocks is only allowed in an `unsafe` context.
r[items.extern.safety]
Calling unsafe functions or accessing unsafe statics that are declared in external blocks is only allowed in an [`unsafe` context].

r[items.extern.namespace]
The external block defines its functions and statics in the [value namespace] of the module or block where it is located.
Expand Down Expand Up @@ -465,6 +465,7 @@ restrictions as [regular function parameters].
[WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html
[`bundle` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-bundle
[`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib
[`unsafe` context]: ../unsafe-keyword.md
[`verbatim` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-verbatim
[`whole-archive` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-whole-archive
[attributes]: ../attributes.md
Expand Down
22 changes: 17 additions & 5 deletions src/unsafe-keyword.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,27 @@ r[unsafe]
# The `unsafe` keyword

r[unsafe.intro]
The `unsafe` keyword can occur in several different contexts:
unsafe functions (`unsafe fn`), unsafe blocks (`unsafe {}`), unsafe traits (`unsafe trait`), unsafe trait implementations (`unsafe impl`), unsafe external blocks (`unsafe extern`), and unsafe attributes (`#[unsafe(attr)]`).
It plays several different roles, depending on where it is used and whether the `unsafe_op_in_unsafe_fn` lint is enabled:
- it is used to mark code that *defines* extra safety conditions (`unsafe fn`, `unsafe trait`)
- it is used to mark code that needs to *satisfy* extra safety conditions (`unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`, `#[unsafe(attr)]`)
The `unsafe` keyword is used to create or discharge the obligation to prove something safe. Specifically:

- It is used to mark code that *defines* extra safety conditions that must be upheld elsewhere.
- This includes `unsafe fn`, `unsafe static`, and `unsafe trait`.
- It is used to mark code that the programmer *asserts* satisfies safety conditions defined elsewhere.
- This includes `unsafe {}`, `unsafe impl`, `unsafe fn` without [`unsafe_op_in_unsafe_fn`], `unsafe extern`, and `#[unsafe(attr)]`.

The following discusses each of these cases.
See the [keyword documentation][keyword] for some illustrative examples.

r[unsafe.positions]
The `unsafe` keyword can occur in several different contexts:

- unsafe functions (`unsafe fn`)
- unsafe blocks (`unsafe {}`)
- unsafe traits (`unsafe trait`)
- unsafe trait implementations (`unsafe impl`)
- unsafe external blocks (`unsafe extern`)
- unsafe external statics (`unsafe static`)
- unsafe attributes (`#[unsafe(attr)]`)

r[unsafe.fn]
## Unsafe functions (`unsafe fn`)

Expand Down
4 changes: 2 additions & 2 deletions src/unsafety.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ r[safety.unsafe-deref]
- Dereferencing a [raw pointer].

r[safety.unsafe-static]
- Reading or writing a [mutable] or [external] static variable.
- Reading or writing a [mutable] or unsafe [external] static variable.

r[safety.unsafe-union-access]
- Accessing a field of a [`union`], other than to assign to it.

r[safety.unsafe-call]
- Calling an unsafe function (including an intrinsic or foreign function).
- Calling an unsafe function.

r[safety.unsafe-target-feature-call]
- Calling a safe function marked with a [`target_feature`][attributes.codegen.target_feature] from a function that does not have a `target_feature` attribute enabling the same features (see [attributes.codegen.target_feature.safety-restrictions]).
Expand Down