diff --git a/src/abi.md b/src/abi.md
index f244ead5d..2e9e969ac 100644
--- a/src/abi.md
+++ b/src/abi.md
@@ -88,7 +88,7 @@ pub fn name_in_rust() { }
[_MetaNameValueStr_]: attributes.md#meta-item-attribute-syntax
[`static` items]: items/static-items.md
[attribute]: attributes.md
-[extern functions]: items/functions.md#extern-functions
+[extern functions]: items/functions.md#extern-function-qualifier
[external blocks]: items/external-blocks.md
[function]: items/functions.md
[item]: items.md
diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md
index 9c69ad0ed..f3e692ac9 100644
--- a/src/items/external-blocks.md
+++ b/src/items/external-blocks.md
@@ -29,9 +29,13 @@
> _NamedFunctionParametersWithVariadics_ :\
> ( _NamedFunctionParam_ `,` )\* _NamedFunctionParam_ `,` `...`
-External blocks form the basis for Rust's foreign function interface.
-Declarations in an external block describe symbols in external, non-Rust
-libraries.
+External blocks provide _declarations_ of items that are not _defined_ in the
+current crate and are the basis of Rust's foreign function interface. These are
+akin to unchecked imports.
+
+Two kind of item _declarations_ are allowed in external blocks: [functions] and
+[statics]. Calling functions or accessing statics that are declared in external
+blocks is only allowed in an `unsafe` context.
Functions within external blocks are declared in the same way as other Rust
functions, with the exception that they may not have a body and are instead
@@ -48,6 +52,8 @@ extern "abi" for<'l1, ..., 'lm> fn(A1, ..., An) -> R`, where `'l1`, ... `'lm`
are its lifetime parameters, `A1`, ..., `An` are the declared types of its
parameters and `R` is the declared return type.
+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.
It is `unsafe` to access a static item declared in an extern block, whether or
not it's mutable.
@@ -85,13 +91,6 @@ There are also some platform-specific ABI strings:
* `extern "vectorcall"` -- The `vectorcall` ABI -- corresponds to MSVC's
`__vectorcall` and clang's `__attribute__((vectorcall))`
-Finally, there are some rustc-specific ABI strings:
-
-* `extern "rust-intrinsic"` -- The ABI of rustc intrinsics.
-* `extern "rust-call"` -- The ABI of the Fn::call trait functions.
-* `extern "platform-intrinsic"` -- Specific platform intrinsics -- like, for
- example, `sqrt` -- have this ABI. You should never have to deal with it.
-
## Variadic functions
Functions within external blocks may be variadic by specifying `...` after one
@@ -165,6 +164,8 @@ extern {
[IDENTIFIER]: ../identifiers.md
[WebAssembly module]: https://webassembly.github.io/spec/core/syntax/modules.html
+[functions]: functions.md
+[statics]: static-items.md
[_Abi_]: functions.md
[_FunctionReturnType_]: functions.md
[_Generics_]: generics.md
diff --git a/src/items/functions.md b/src/items/functions.md
index bae5b8eff..7c93dc423 100644
--- a/src/items/functions.md
+++ b/src/items/functions.md
@@ -107,35 +107,73 @@ component after the function name. This might be necessary if there is not
sufficient context to determine the type parameters. For example,
`mem::size_of::() == 4`.
-## Extern functions
+## Extern function qualifier
-Extern functions are part of Rust's foreign function interface, providing the
-opposite functionality to [external blocks]. Whereas external
-blocks allow Rust code to call foreign code, extern functions with bodies
-defined in Rust code _can be called by foreign code_. They are defined in the
-same way as any other Rust function, except that they have the `extern`
-qualifier.
+The `extern` function qualifier allows providing function _definitions_ that can
+be called with a particular ABI:
+
+```rust,ignore
+extern "ABI" fn foo() { ... }
+```
+
+These are often used in combination with [external block] items which provide
+function _declarations_ that can be used to call functions without providing
+their _definition_:
+
+```rust,ignore
+extern "ABI" {
+ fn foo(); /* no body */
+}
+unsafe { foo() }
+```
+
+When `"extern" Abi?*` is omitted from `FunctionQualifiers` in function items,
+the ABI `"Rust"` is assigned. For example:
```rust
-// Declares an extern fn, the ABI defaults to "C"
-extern fn new_i32() -> i32 { 0 }
+fn foo() {}
+```
+
+is equivalent to:
-// Declares an extern fn with "stdcall" ABI
+```rust
+extern "Rust" fn foo() {}
+```
+
+Functions in Rust can be called by foreign code, and using an ABI that
+differs from Rust allows, for example, to provide functions that can be
+called from other programming languages like C:
+
+```rust
+// Declares a function with the "C" ABI
+extern "C" fn new_i32() -> i32 { 0 }
+
+// Declares a function with the "stdcall" ABI
# #[cfg(target_arch = "x86_64")]
extern "stdcall" fn new_i32_stdcall() -> i32 { 0 }
```
-Unlike normal functions, extern fns have type `extern "ABI" fn()`. This is the
-same type as the functions declared in an extern block.
+Just as with [external block], when the `extern` keyword is used and the `"ABI`
+is omitted, the ABI used defaults to `"C"`. That is, this:
```rust
-# extern fn new_i32() -> i32 { 0 }
+extern fn new_i32() -> i32 { 0 }
+let fptr: extern fn() -> i32 = new_i32;
+```
+
+is equivalent to:
+
+```rust
+extern "C" fn new_i32() -> i32 { 0 }
let fptr: extern "C" fn() -> i32 = new_i32;
```
-As non-Rust calling conventions do not support unwinding, unwinding past the end
-of an extern function will cause the process to abort. In LLVM, this is
-implemented by executing an illegal instruction.
+Functions with an ABI that differs from `"Rust"` do not support unwinding in the
+exact same way that Rust does. Therefore, unwinding past the end of functions
+with such ABIs causes the process to abort.
+
+> **Note**: The LLVM backend of the `rustc` implementation
+aborts the process by executing an illegal instruction.
## Const functions
@@ -243,3 +281,4 @@ attributes macros.
[`export_name`]: ../abi.md#the-export_name-attribute
[`link_section`]: ../abi.md#the-link_section-attribute
[`no_mangle`]: ../abi.md#the-no_mangle-attribute
+[external_block_abi]: external-blocks.md#abi
diff --git a/src/types/function-pointer.md b/src/types/function-pointer.md
index 44da3ccbd..88ef50c24 100644
--- a/src/types/function-pointer.md
+++ b/src/types/function-pointer.md
@@ -51,6 +51,6 @@ x = bo(5,7);
[_Type_]: ../types.md#type-expressions
[`extern`]: ../items/external-blocks.md
[closures]: closure.md
-[extern function]: ../items/functions.md#extern-functions
+[extern function]: ../items/functions.md#extern-function-qualifier
[function items]: function-item.md
[unsafe function]: ../unsafe-functions.md