Skip to content

Commit 4684d53

Browse files
committed
Unwrap lines
This document had a mix of line wrapping styles. Let's consistently unwrap the lines.
1 parent 5cc4cc3 commit 4684d53

File tree

1 file changed

+23
-30
lines changed

1 file changed

+23
-30
lines changed

text/0000-unsafe-extern-blocks.md

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ In Edition 2024 it is `unsafe` to declare an `extern` function or static, but ex
1111
# Motivation
1212
[motivation]: #motivation
1313

14-
Simply declaring extern items, even without ever using them, can cause Undefined Behavior (see, e.g., issue [#46188][]).
15-
When performing cross-language compilation, attributes on one function declaration can flow to the foreign declaration elsewhere within LLVM and cause a miscompilation.
16-
In Rust we consider all sources of Undefined Behavior to be `unsafe`, and so we must make declaring extern blocks be `unsafe`.
17-
The up-side to this change is that in the new style it will be possible to declare an extern fn that's safe to call after the initial unsafe declaration.
14+
Simply declaring extern items, even without ever using them, can cause Undefined Behavior (see, e.g., issue [#46188][]). When performing cross-language compilation, attributes on one function declaration can flow to the foreign declaration elsewhere within LLVM and cause a miscompilation. In Rust we consider all sources of Undefined Behavior to be `unsafe`, and so we must make declaring extern blocks be `unsafe`. The up-side to this change is that in the new style it will be possible to declare an extern fn that's safe to call after the initial unsafe declaration.
1815

1916
[#46188]: https://github.com/rust-lang/rust/issues/46188
2017

@@ -25,20 +22,15 @@ Rust can utilize functions and statics from foreign code that are provided durin
2522

2623
An `extern` block can be placed anywhere a function declaration could appear (generally at the top level of a module).
2724

28-
* On editions >= 2024, you *must* write all `extern` blocks as `unsafe extern`.
29-
* On editions < 2024, you *may* write `unsafe extern`, or you can write an `extern` block without the `unsafe` keyword. Writing an `extern` block without the `unsafe` keyword is provided for compatibility only, and will eventually generate a warning.
30-
* `unsafe extern` interacts with the `unsafe_code` lint, and a `deny` or `forbid` with that lint will deny or forbid the unsafe external block.
25+
- On editions >= 2024, you *must* write all `extern` blocks as `unsafe extern`.
26+
- On editions < 2024, you *may* write `unsafe extern`, or you can write an `extern` block without the `unsafe` keyword. Writing an `extern` block without the `unsafe` keyword is provided for compatibility only, and will eventually generate a warning.
27+
- `unsafe extern` interacts with the `unsafe_code` lint, and a `deny` or `forbid` with that lint will deny or forbid the unsafe external block.
3128

32-
Within an `extern` block is zero or more declarations of external functions and/or external static values.
33-
An extern function is declared with a `;` instead of a function body (similar to a method of a trait).
34-
An extern static value is also declared with a `;` instead of an expression (similar to an associated const of a trait).
35-
In both cases, the actual function body or value is provided by whatever external source (which is probably not even written in Rust).
29+
Within an `extern` block is zero or more declarations of external functions and/or external static values. An extern function is declared with a `;` instead of a function body (similar to a method of a trait). An extern static value is also declared with a `;` instead of an expression (similar to an associated const of a trait). In both cases, the actual function body or value is provided by whatever external source (which is probably not even written in Rust).
3630

37-
When an `unsafe extern` block is used, all declarations within that `extern` block *must* have the `unsafe` or `safe` keywords as part of their signature.
38-
The `safe` keyword is a contextual keyword; it is currently allowed only within `extern` blocks.
31+
When an `unsafe extern` block is used, all declarations within that `extern` block *must* have the `unsafe` or `safe` keywords as part of their signature. The `safe` keyword is a contextual keyword; it is currently allowed only within `extern` blocks.
3932

40-
If an `extern` block is used in an older edition without the `unsafe` keyword, declarations *cannot* specify `safe` or `unsafe`.
41-
Code must update to `unsafe extern` style blocks if it wants to make `safe` declarations.
33+
If an `extern` block is used in an older edition without the `unsafe` keyword, declarations *cannot* specify `safe` or `unsafe`. Code must update to `unsafe extern` style blocks if it wants to make `safe` declarations.
4234

4335
```rust
4436
unsafe extern {
@@ -60,19 +52,17 @@ unsafe extern {
6052

6153
`extern` blocks are `unsafe` because if the declaration doesn't match the actual external function, or the actual external data, then the behavior of the resulting program may be undefined.
6254

63-
Once they are unsafely declared, a `safe` item can be used outside the `extern` block as if it were any other safe function or static value declared within rust.
64-
The unsafe obligation of ensuring that the correct items are being linked to is performed by the crate making the declaration, not the crate using that declaration.
55+
Once they are unsafely declared, a `safe` item can be used outside the `extern` block as if it were any other safe function or static value declared within rust. The unsafe obligation of ensuring that the correct items are being linked to is performed by the crate making the declaration, not the crate using that declaration.
6556

66-
Items declared as `unsafe` *must* still have a correctly matching signature at compile time, but they *also* have some sort of additional obligation for correct usage at runtime.
67-
They can only be used within an `unsafe` block.
57+
Items declared as `unsafe` *must* still have a correctly matching signature at compile time, but they *also* have some sort of additional obligation for correct usage at runtime. They can only be used within an `unsafe` block.
6858

6959
# Reference-level explanation
7060
[reference-level-explanation]: #reference-level-explanation
7161

7262
The grammar of the language is updated so that:
7363

74-
* Editions >= 2024 *must* prefix all `extern` blocks with `unsafe`.
75-
* Editions < 2024 *should* prefix `extern` blocks with `unsafe`, this will eventually be a warn-by-default compatibility lint when `unsafe` is missing.
64+
- Editions >= 2024 *must* prefix all `extern` blocks with `unsafe`.
65+
- Editions < 2024 *should* prefix `extern` blocks with `unsafe`, this will eventually be a warn-by-default compatibility lint when `unsafe` is missing.
7666

7767
This RFC replaces the *["functions"][]* and *["statics"][]* sections in the [external blocks][] chapter of the Rust Reference with the following:
7868

@@ -81,32 +71,35 @@ This RFC replaces the *["functions"][]* and *["statics"][]* sections in the [ext
8171
[external blocks]: https://doc.rust-lang.org/nightly/reference/items/external-blocks.html
8272

8373
### Functions
84-
Functions within external blocks are declared in the same way as other Rust functions, with the exception that they must not have a body and are instead terminated by a semicolon. Patterns are not allowed in parameters, only IDENTIFIER or _ may be used. The function qualifiers `const`, `async`, and `extern` are not allowed. If the function is unsafe to call, then the function should use the `unsafe` qualifier. If the function is safe to call, then the function should use the `safe` qualifier (a contextual keyword). Functions that are not qualified as `unsafe` or `safe` are assumed to be `unsafe`.
74+
75+
Functions within external blocks are declared in the same way as other Rust functions, with the exception that they must not have a body and are instead terminated by a semicolon. Patterns are not allowed in parameters, only IDENTIFIER or _ may be used. The function qualifiers `const`, `async`, and `extern` are not allowed. If the function is unsafe to call, then the function should use the `unsafe` qualifier. If the function is safe to call, then the function should use the `safe` qualifier (a contextual keyword). Functions that are not qualified as `unsafe` or `safe` are assumed to be `unsafe`.
8576

8677
If the function signature declared in Rust is incompatible with the function signature as declared in the foreign code, the behavior of the resulting program may be undefined.
8778

88-
Functions within external blocks may be called by Rust code, just like functions defined in Rust. The Rust compiler will automatically use the correct foreign ABI when making the call.
79+
Functions within external blocks may be called by Rust code, just like functions defined in Rust. The Rust compiler will automatically use the correct foreign ABI when making the call.
80+
81+
When coerced to a function pointer, a function declared in an extern block has type:
8982

90-
When coerced to a function pointer, a function declared in an extern block has type
9183
```rust
9284
extern "abi" for<'l1, ..., 'lm> fn(A1, ..., An) -> R
9385
```
94-
where `'l1`, ... `'lm` are its lifetime parameters, `A1`, ..., `An` are the declared types of its parameters and `R` is the declared return type.
86+
where `'l1`, ..., `'lm` are its lifetime parameters, `A1`, ..., `An` are the declared types of its parameters and `R` is the declared return type.
9587

9688
### Statics
97-
Statics within external blocks are declared in the same way as statics outside of external blocks, except that they do not have an expression initializing their value. If the static is unsafe to access, then the static should use the `unsafe` qualifier. If the static is safe to access (and immutable), then the static should use the `safe` qualifier (a contextual keyword). Statics that are not qualified as `unsafe` or `safe` are assumed to be `unsafe`.
9889

99-
Extern statics can be either immutable or mutable just like statics outside of external blocks. An immutable static must be initialized before any Rust code is executed. It is not enough for the static to be initialized before Rust code reads from it. A mutable extern static is always `unsafe` to access, the same as a Rust mutable static, and as such can not be marked with a `safe` qualifier.
90+
Statics within external blocks are declared in the same way as statics outside of external blocks, except that they do not have an expression initializing their value. If the static is unsafe to access, then the static should use the `unsafe` qualifier. If the static is safe to access (and immutable), then the static should use the `safe` qualifier (a contextual keyword). Statics that are not qualified as `unsafe` or `safe` are assumed to be `unsafe`.
91+
92+
Extern statics can be either immutable or mutable just like statics outside of external blocks. An immutable static must be initialized before any Rust code is executed. It is not enough for the static to be initialized before Rust code reads from it. A mutable extern static is always `unsafe` to access, the same as a Rust mutable static, and as such can not be marked with a `safe` qualifier.
10093

10194
# Drawbacks
10295
[drawbacks]: #drawbacks
10396

104-
This change will induce some churn. Hopefully, allowing people to safely call some foreign functions will make up for that.
97+
This change will induce some churn. Hopefully, allowing people to safely call some foreign functions will make up for that.
10598

10699
# Rationale and alternatives
107100
[rationale-and-alternatives]: #rationale-and-alternatives
108101

109-
Incorrect extern declarations can cause UB in current Rust, but we have no way to automatically check that all declarations are correct, nor is such a thing likely to be developed. Making the declarations `unsafe` so that programmers are aware of the dangers and can give extern blocks the attention they deserve is the minimum step.
102+
Incorrect extern declarations can cause UB in current Rust, but we have no way to automatically check that all declarations are correct, nor is such a thing likely to be developed. Making the declarations `unsafe` so that programmers are aware of the dangers and can give extern blocks the attention they deserve is the minimum step.
110103

111104
# Prior art
112105
[prior-art]: #prior-art
@@ -116,7 +109,7 @@ None we are aware of.
116109
# Unresolved questions
117110
[unresolved-questions]: #unresolved-questions
118111

119-
* Extern declarations are actually *always* unsafe and able to cause UB regardless of edition. This RFC doesn't have a specific answer on how to improve pre-2024 code.
112+
* Extern declarations are actually *always* unsafe and able to cause UB regardless of edition. This RFC doesn't have a specific answer on how to improve pre-2024 code.
120113

121114
# Future possibilities
122115
[future-possibilities]: #future-possibilities

0 commit comments

Comments
 (0)