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