Skip to content

Document that "extern blocks must be unsafe" in Rust 2024 #140216

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 1 commit into from
Apr 26, 2025

Conversation

t5kd
Copy link
Contributor

@t5kd t5kd commented Apr 23, 2025

The documentation on extern contains the following code sample:

#[link(name = "my_c_library")]
extern "C" {
    fn my_c_function(x: i32) -> bool;
}

Due to #123743, attempting to compile such code with the 2024 edition of Rust fails:

error: extern blocks must be unsafe

This PR extends the extern documentation with a brief explanation of the new requirement. It also adds the missing unsafe keyword to the code sample, which should be compatible with rustc since v1.82.

Related docs:

@rustbot
Copy link
Collaborator

rustbot commented Apr 23, 2025

r? @ibraheemdev

rustbot has assigned @ibraheemdev.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 23, 2025
@rustbot

This comment has been minimized.

@rustbot rustbot added has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 23, 2025
@rustbot rustbot removed has-merge-commits PR has merge commits, merge with caution. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 23, 2025
@tgross35
Copy link
Contributor

Since this is unsafe, it would be good to document what makes usage sound. Could you do that, and add an example // SAFETY: comment?

There is more at https://github.com/rust-lang/rfcs/blob/master/text/3484-unsafe-extern-blocks.md but mainly you have to assert that the function exists with that signature, since the compiler has no way to verify it.

@tgross35
Copy link
Contributor

It's probably actually okay to drop the mention of edition differences. unsafe extern can be used in all editions so it's not something the user needs to worry about, always using unsafe extern should be preferred.

@t5kd
Copy link
Contributor Author

t5kd commented Apr 24, 2025

Since this is unsafe, it would be good to document what makes usage sound. Could you do that, and add an example // SAFETY: comment?

Sure, thank you for your feedback. I came up with two possible options.

Option 1 (more compact):

This use of extern is unsafe, since we are asserting to the compiler that all declared signatures are correct. If they are not, using these items may lead to undefined behavior.

// SAFETY: It is our responsibility to ensure that the following
// external block contains correct function signatures.
#[link(name = "my_c_library")]
unsafe extern "C" {
    fn my_c_function(x: i32) -> bool;
}

Option 2 (more verbose):

This use of extern is unsafe, since we are asserting to the compiler that all declared signatures are correct. If they are not, using these items may lead to undefined behavior. In addition, if it is possible to prove that calling certain external functions will not lead to undefined behavior, their declarations can be marked as safe. Such functions are directly usable from safe Rust code.

// SAFETY: It is our responsibility to ensure that the following
// external block contains correct function signatures.
#[link(name = "my_c_library")]
unsafe extern "C" {
    fn first_c_function(x: i32) -> bool;
    // SAFETY: We need to ensure that calling the following
    // function will not cause undefined behavior.
    safe fn second_c_function() -> bool;
}

Do you mean something like that?

@tgross35
Copy link
Contributor

I think the first option is fine, the reference has more details about the caveats here. The safety comment should be adjusted though, it's describing what needs to be done rather than that we have done it.

Something like "SAFETY: below function definitions match the headers for my_c_library" would be more accurate.

@t5kd
Copy link
Contributor Author

t5kd commented Apr 25, 2025

Got it, I just committed a possible wording. For consistency with the corresponding Reference item, I went for the term "function declarations" rather than "function signatures" or "function definitions". Please let me know if there is something to improve. Otherwise, the PR is complete from my side.

Copy link
Contributor

@tgross35 tgross35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Please squash

@tgross35
Copy link
Contributor

Thanks for adding this clarification.

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Apr 25, 2025

📌 Commit 1862feb has been approved by tgross35

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 25, 2025
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Apr 25, 2025
Document that "extern blocks must be unsafe" in Rust 2024

The [documentation on `extern`](https://doc.rust-lang.org/std/keyword.extern.html) contains the following code sample:
```rust
#[link(name = "my_c_library")]
extern "C" {
    fn my_c_function(x: i32) -> bool;
}
```

Due to rust-lang#123743, attempting to compile such code with the 2024 edition of Rust fails:
```
error: extern blocks must be unsafe
```

This PR extends the `extern` documentation with a brief explanation of the new requirement. It also adds the missing `unsafe` keyword to the code sample, which should be compatible with rustc since v1.82.

**Related docs:**
- https://doc.rust-lang.org/reference/items/external-blocks.html
- https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 26, 2025
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#139865 (Stabilize proc_macro::Span::{start,end,line,column}.)
 - rust-lang#140086 (If creating a temporary directory fails with permission denied then retry with backoff)
 - rust-lang#140216 (Document that "extern blocks must be unsafe" in Rust 2024)
 - rust-lang#140220 (Fix detection of main function if there are expressions around it)
 - rust-lang#140253 (Add XtensaAsmPrinter)
 - rust-lang#140272 (Improve error message for `||` (or) in let chains)
 - rust-lang#140305 (Track per-obligation recursion depth only if there is inference in the new solver)
 - rust-lang#140306 (handle specialization in the new trait solver)
 - rust-lang#140308 (stall generator witness obligations: add regression test)

r? `@ghost`
`@rustbot` modify labels: rollup
jhpratt added a commit to jhpratt/rust that referenced this pull request Apr 26, 2025
Document that "extern blocks must be unsafe" in Rust 2024

The [documentation on `extern`](https://doc.rust-lang.org/std/keyword.extern.html) contains the following code sample:
```rust
#[link(name = "my_c_library")]
extern "C" {
    fn my_c_function(x: i32) -> bool;
}
```

Due to rust-lang#123743, attempting to compile such code with the 2024 edition of Rust fails:
```
error: extern blocks must be unsafe
```

This PR extends the `extern` documentation with a brief explanation of the new requirement. It also adds the missing `unsafe` keyword to the code sample, which should be compatible with rustc since v1.82.

**Related docs:**
- https://doc.rust-lang.org/reference/items/external-blocks.html
- https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 26, 2025
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#139865 (Stabilize proc_macro::Span::{start,end,line,column}.)
 - rust-lang#140086 (If creating a temporary directory fails with permission denied then retry with backoff)
 - rust-lang#140216 (Document that "extern blocks must be unsafe" in Rust 2024)
 - rust-lang#140253 (Add XtensaAsmPrinter)
 - rust-lang#140272 (Improve error message for `||` (or) in let chains)
 - rust-lang#140305 (Track per-obligation recursion depth only if there is inference in the new solver)
 - rust-lang#140306 (handle specialization in the new trait solver)
 - rust-lang#140308 (stall generator witness obligations: add regression test)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 806260e into rust-lang:master Apr 26, 2025
6 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 26, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 26, 2025
Rollup merge of rust-lang#140216 - t5kd:master, r=tgross35

Document that "extern blocks must be unsafe" in Rust 2024

The [documentation on `extern`](https://doc.rust-lang.org/std/keyword.extern.html) contains the following code sample:
```rust
#[link(name = "my_c_library")]
extern "C" {
    fn my_c_function(x: i32) -> bool;
}
```

Due to rust-lang#123743, attempting to compile such code with the 2024 edition of Rust fails:
```
error: extern blocks must be unsafe
```

This PR extends the `extern` documentation with a brief explanation of the new requirement. It also adds the missing `unsafe` keyword to the code sample, which should be compatible with rustc since v1.82.

**Related docs:**
- https://doc.rust-lang.org/reference/items/external-blocks.html
- https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants