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