@@ -21,37 +21,38 @@ Two kinds of item _declarations_ are allowed in external blocks: [functions] and
21
21
[ statics] . Calling functions or accessing statics that are declared in external
22
22
blocks is only allowed in an ` unsafe ` context.
23
23
24
- The ` unsafe ` keyword is syntactically allowed to appear before the ` extern `
25
- keyword, but it is rejected at a semantic level. This allows macros to consume
26
- the syntax and make use of the ` unsafe ` keyword, before removing it from the
27
- token stream.
24
+ Starting in edition 2024, the ` unsafe ` keyword is required to appear before the
25
+ ` extern ` keyword. In previous editions is accepted but not required.
28
26
29
27
## Functions
30
28
31
29
Functions within external blocks are declared in the same way as other Rust
32
30
functions, with the exception that they must not have a body and are instead
33
31
terminated by a semicolon. Patterns are not allowed in parameters, only
34
- [ IDENTIFIER] or ` _ ` may be used. Function qualifiers (` const ` , ` async ` ,
35
- ` unsafe ` , and ` extern ` ) are not allowed.
32
+ [ IDENTIFIER] or ` _ ` may be used. Only safety funcion qualifiers are allowed
33
+ (` unsafe ` , ` safe ` ), other function qualifiers (` const ` , ` async ` , and ` extern ` )
34
+ are not allowed.
36
35
37
36
Functions within external blocks may be called by Rust code, just like
38
37
functions defined in Rust. The Rust compiler automatically translates between
39
38
the Rust ABI and the foreign ABI.
40
39
41
- A function declared in an extern block is implicitly ` unsafe ` . When coerced to
42
- a function pointer, a function declared in an extern block has type `unsafe
43
- extern "abi" for<'l1, ..., 'lm> fn(A1, ..., An) -> R` , where ` 'l1` , ... ` 'lm`
44
- are its lifetime parameters, ` A1 ` , ..., ` An ` are the declared types of its
45
- parameters and ` R ` is the declared return type.
40
+ A function declared with an explicit safety qualifier (` unsafe ` , ` safe ` ) would
41
+ take such safety qualification, if no qualifier is present is implicitly
42
+ ` unsafe ` . When coerced to a function pointer, a function declared in an extern
43
+ block has type ` unsafe extern "abi" for<'l1, ..., 'lm> fn(A1, ..., An) -> R ` ,
44
+ where ` 'l1 ` , ... ` 'lm ` are its lifetime parameters, ` A1 ` , ..., ` An ` are the
45
+ declared types of its parameters and ` R ` is the declared return type.
46
46
47
47
## Statics
48
48
49
49
Statics within external blocks are declared in the same way as [ statics] outside of external blocks,
50
50
except that they do not have an expression initializing their value.
51
- It is ` unsafe ` to access a static item declared in an extern block, whether or
52
- not it's mutable, because there is nothing guaranteeing that the bit pattern at the static's
53
- memory is valid for the type it is declared with, since some arbitrary (e.g. C) code is in charge
54
- of initializing the static.
51
+ It is ` unsafe ` by default or if the item is declared as ` unsafe ` to access a static item declared in
52
+ an extern block, unless the item was explicitly declared as ` safe ` .
53
+ It does not matter if it's mutable, because there is nothing guaranteeing that the bit pattern at
54
+ the static's memory is valid for the type it is declared with, since some arbitrary (e.g. C) code is
55
+ in charge of initializing the static.
55
56
56
57
Extern statics can be either immutable or mutable just like [ statics] outside of external blocks.
57
58
An immutable static * must* be initialized before any Rust code is executed. It is not enough for
@@ -67,34 +68,34 @@ standard C ABI on the specific platform. Other ABIs may be specified using an
67
68
68
69
``` rust
69
70
// Interface to the Windows API
70
- extern " stdcall" { }
71
+ unsafe extern " stdcall" { }
71
72
```
72
73
73
74
There are three ABI strings which are cross-platform, and which all compilers
74
75
are guaranteed to support:
75
76
76
- * ` extern "Rust" ` -- The default ABI when you write a normal ` fn foo() ` in any
77
+ * ` unsafe extern "Rust"` -- The default ABI when you write a normal ` fn foo() ` in any
77
78
Rust code.
78
- * ` extern "C" ` -- This is the same as ` extern fn foo() ` ; whatever the default
79
+ * ` unsafe extern "C"` -- This is the same as ` extern fn foo() ` ; whatever the default
79
80
your C compiler supports.
80
- * ` extern "system" ` -- Usually the same as ` extern "C" ` , except on Win32, in
81
+ * ` unsafe extern "system"` -- Usually the same as ` extern "C" ` , except on Win32, in
81
82
which case it's ` "stdcall" ` , or what you should use to link to the Windows
82
83
API itself
83
84
84
85
There are also some platform-specific ABI strings:
85
86
86
- * ` extern "cdecl" ` -- The default for x86\_ 32 C code.
87
- * ` extern "stdcall" ` -- The default for the Win32 API on x86\_ 32.
88
- * ` extern "win64" ` -- The default for C code on x86\_ 64 Windows.
89
- * ` extern "sysv64" ` -- The default for C code on non-Windows x86\_ 64.
90
- * ` extern "aapcs" ` -- The default for ARM.
91
- * ` extern "fastcall" ` -- The ` fastcall ` ABI -- corresponds to MSVC's
87
+ * ` unsafe extern "cdecl"` -- The default for x86\_ 32 C code.
88
+ * ` unsafe extern "stdcall"` -- The default for the Win32 API on x86\_ 32.
89
+ * ` unsafe extern "win64"` -- The default for C code on x86\_ 64 Windows.
90
+ * ` unsafe extern "sysv64"` -- The default for C code on non-Windows x86\_ 64.
91
+ * ` unsafe extern "aapcs"` -- The default for ARM.
92
+ * ` unsafe extern "fastcall"` -- The ` fastcall ` ABI -- corresponds to MSVC's
92
93
` __fastcall ` and GCC and clang's ` __attribute__((fastcall)) `
93
- * ` extern "vectorcall" ` -- The ` vectorcall ` ABI -- corresponds to MSVC's
94
+ * ` unsafe extern "vectorcall"` -- The ` vectorcall ` ABI -- corresponds to MSVC's
94
95
` __vectorcall ` and clang's ` __attribute__((vectorcall)) `
95
- * ` extern "thiscall" ` -- The default for C++ member functions on MSVC -- corresponds to MSVC's
96
+ * ` unsafe extern "thiscall"` -- The default for C++ member functions on MSVC -- corresponds to MSVC's
96
97
` __thiscall ` and GCC and clang's ` __attribute__((thiscall)) `
97
- * ` extern "efiapi" ` -- The ABI used for [ UEFI] functions.
98
+ * ` unsafe extern "efiapi"` -- The ABI used for [ UEFI] functions.
98
99
99
100
## Variadic functions
100
101
@@ -103,7 +104,7 @@ last argument. The variadic parameter may optionally be specified with an
103
104
identifier.
104
105
105
106
``` rust
106
- extern " C" {
107
+ unsafe extern " C" {
107
108
fn foo (... );
108
109
fn bar (x : i32 , ... );
109
110
fn with_name (format : * const u8 , args : ... );
@@ -150,17 +151,17 @@ not specified.
150
151
<!-- ignore: requires extern linking -->
151
152
``` rust,ignore
152
153
#[link(name = "crypto")]
153
- extern {
154
+ unsafe extern {
154
155
// …
155
156
}
156
157
157
158
#[link(name = "CoreFoundation", kind = "framework")]
158
- extern {
159
+ unsafe extern {
159
160
// …
160
161
}
161
162
162
163
#[link(wasm_import_module = "foo")]
163
- extern {
164
+ unsafe extern {
164
165
// …
165
166
}
166
167
```
@@ -275,7 +276,7 @@ block to indicate the symbol to import for the given function or static. It
275
276
uses the [ _ MetaNameValueStr_ ] syntax to specify the name of the symbol.
276
277
277
278
``` rust
278
- extern {
279
+ unsafe extern {
279
280
#[link_name = " actual_symbol_name" ]
280
281
fn name_in_rust ();
281
282
}
@@ -304,7 +305,7 @@ it, and that assigned ordinal may change between builds of the binary.
304
305
<!-- ignore: Only works on x86 Windows -->
305
306
``` rust,ignore
306
307
#[link(name = "exporter", kind = "raw-dylib")]
307
- extern "stdcall" {
308
+ unsafe extern "stdcall" {
308
309
#[link_ordinal(15)]
309
310
fn imported_function_stdcall(i: i32);
310
311
}
0 commit comments