diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index bd9cb9ca7..4bce2f221 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -11,7 +11,6 @@
- [Comments](comments.md)
- [Whitespace](whitespace.md)
- [Tokens](tokens.md)
- - [Paths](paths.md)
- [Macros](macros.md)
- [Macros By Example](macros-by-example.md)
@@ -37,7 +36,6 @@
- [External blocks](items/external-blocks.md)
- [Generic parameters](items/generics.md)
- [Associated Items](items/associated-items.md)
- - [Visibility and Privacy](visibility-and-privacy.md)
- [Attributes](attributes.md)
- [Testing](attributes/testing.md)
@@ -103,6 +101,14 @@
- [Special types and traits](special-types-and-traits.md)
+- [Names](names.md)
+ - [Namespaces](names/namespaces.md)
+ - [Scopes](names/scopes.md)
+ - [Preludes](names/preludes.md)
+ - [Paths](paths.md)
+ - [Name resolution](names/name-resolution.md)
+ - [Visibility and privacy](visibility-and-privacy.md)
+
- [Memory model](memory-model.md)
- [Memory allocation and lifetime](memory-allocation-and-lifetime.md)
- [Memory ownership](memory-ownership.md)
diff --git a/src/attributes.md b/src/attributes.md
index d00653073..d6ce2531b 100644
--- a/src/attributes.md
+++ b/src/attributes.md
@@ -150,9 +150,9 @@ active. All other attributes are inert.
## Tool attributes
The compiler may allow attributes for external tools where each tool resides
-in its own namespace. The first segment of the attribute path is the name of
-the tool, with one or more additional segments whose interpretation is up to
-the tool.
+in its own namespace in the [tool prelude]. The first segment of the attribute
+path is the name of the tool, with one or more additional segments whose
+interpretation is up to the tool.
When a tool is not in use, the tool's attributes are accepted without a
warning. When the tool is in use, the tool is responsible for processing and
@@ -279,11 +279,11 @@ The following is an index of all built-in attributes.
[`macro_use`]: macros-by-example.md#the-macro_use-attribute
[`must_use`]: attributes/diagnostics.md#the-must_use-attribute
[`no_builtins`]: attributes/codegen.md#the-no_builtins-attribute
-[`no_implicit_prelude`]: items/modules.md#prelude-items
+[`no_implicit_prelude`]: names/preludes.md#the-no_implicit_prelude-attribute
[`no_link`]: items/extern-crates.md#the-no_link-attribute
[`no_main`]: crates-and-source-files.md#the-no_main-attribute
[`no_mangle`]: abi.md#the-no_mangle-attribute
-[`no_std`]: crates-and-source-files.md#preludes-and-no_std
+[`no_std`]: names/preludes.md#the-no_std-attribute
[`non_exhaustive`]: attributes/type_system.md#the-non_exhaustive-attribute
[`panic_handler`]: runtime.md#the-panic_handler-attribute
[`path`]: items/modules.md#the-path-attribute
@@ -315,6 +315,7 @@ The following is an index of all built-in attributes.
[modules]: items/modules.md
[statements]: statements.md
[struct]: items/structs.md
+[tool prelude]: names/preludes.md#tool-prelude
[union]: items/unions.md
[closure]: expressions/closure-expr.md
[function pointer]: types/function-pointer.md
diff --git a/src/crates-and-source-files.md b/src/crates-and-source-files.md
index ffb2ba60c..fe1d214f6 100644
--- a/src/crates-and-source-files.md
+++ b/src/crates-and-source-files.md
@@ -95,27 +95,8 @@ not treated as a shebang, but instead as the start of an attribute.
## Preludes and `no_std`
-All crates have a *prelude* that automatically inserts names from a specific
-module, the *prelude module*, into scope of each [module] and an [`extern
-crate`] into the crate root module. By default, the *standard prelude* is used.
-The linked crate is [`std`] and the prelude module is [`std::prelude::v1`].
-
-The prelude can be changed to the *core prelude* by using the `no_std`
-[attribute] on the root crate module. The linked crate is [`core`] and the
-prelude module is [`core::prelude::v1`]. Using the core prelude over the
-standard prelude is useful when either the crate is targeting a platform that
-does not support the standard library or is purposefully not using the
-capabilities of the standard library. Those capabilities are mainly dynamic
-memory allocation (e.g. `Box` and `Vec`) and file and network capabilities (e.g.
-`std::fs` and `std::io`).
-
-
-
-Warning: Using `no_std` does not prevent the standard library from being linked
-in. It is still valid to put `extern crate std;` into the crate and dependencies
-can also link it in.
-
-
+This section has been moved to the [Preludes chapter](names/preludes.md).
+
## Main Functions
@@ -168,11 +149,6 @@ or `-` (U+002D) characters.
[_shebang_]: https://en.wikipedia.org/wiki/Shebang_(Unix)
[_utf8 byte order mark_]: https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
[`Termination`]: ../std/process/trait.Termination.html
-[`core`]: ../core/index.html
-[`core::prelude::v1`]: ../core/prelude/index.html
-[`extern crate`]: items/extern-crates.md
-[`std`]: ../std/index.html
-[`std::prelude::v1`]: ../std/prelude/index.html
[attribute]: attributes.md
[attributes]: attributes.md
[comments]: comments.md
@@ -182,3 +158,17 @@ or `-` (U+002D) characters.
[trait or lifetime bounds]: trait-bounds.md
[where clauses]: items/generics.md#where-clauses
[whitespace]: whitespace.md
+
+
diff --git a/src/glossary.md b/src/glossary.md
index fd204c29d..03155170c 100644
--- a/src/glossary.md
+++ b/src/glossary.md
@@ -61,6 +61,13 @@ through a mechanism called ‘trait objects’.
A dynamically sized type (DST) is a type without a statically known size or alignment.
+### Entity
+
+An [*entity*] is a language construct that can be referred to in some way
+within the source program, usually via a [path][paths]. Entities include
+[types], [items], [generic parameters], [variable bindings], [loop labels],
+[lifetimes], [fields], [attributes], and [lints].
+
### Expression
An expression is a combination of values, constants, variables, operators
@@ -123,6 +130,28 @@ This is not affected by applied type arguments. `struct Foo` is considered local
`Vec` is not. `LocalType` is local. Type aliases do not
affect locality.
+### Name
+
+A [*name*] is an [identifier] or [lifetime or loop label] that refers to an
+[entity](#entity). A *name binding* is when an entity declaration introduces
+an identifier or label associated with that entity. [Paths],
+identifiers, and labels are used to refer to an entity.
+
+### Name resolution
+
+[*Name resolution*] is the compile-time process of tying [paths],
+[identifiers], and [labels] to [entity](#entity) declarations.
+
+### Namespace
+
+A *namespace* is a logical grouping of declared [names](#name) based on the
+kind of [entity](#entity) the name refers to. Namespaces allow the occurrence
+of a name in one namespace to not conflict with the same name in another
+namespace.
+
+Within a namespace, names are organized in a hierarchy, where each level of
+the hierarchy has its own collection of named entities.
+
### Nominal types
Types that can be referred to by a path directly. Specifically [enums],
@@ -133,11 +162,22 @@ Types that can be referred to by a path directly. Specifically [enums],
[Traits] that can be used as [trait objects]. Only traits that follow specific
[rules][object safety] are object safe.
+### Path
+
+A [*path*] is a sequence of one or more path segments used to refer to an
+[entity](#entity) in the current scope or other levels of a
+[namespace](#namespace) hierarchy.
+
### Prelude
Prelude, or The Rust Prelude, is a small collection of items - mostly traits - that are
imported into every module of every crate. The traits in the prelude are pervasive.
+### Scope
+
+A [*scope*] is the region of source text where a named [entity](#entity) may
+be referenced with that name.
+
### Scrutinee
A scrutinee is the expression that is matched on in `match` expressions and
@@ -216,17 +256,37 @@ example of an uninhabited type is the [never type] `!`, or an enum with no varia
[alignment]: type-layout.md#size-and-alignment
[associated item]: #associated-item
+[attributes]: attributes.md
+[*entity*]: names.md
[enums]: items/enumerations.md
+[fields]: expressions/field-expr.md
[free item]: #free-item
+[generic parameters]: items/generics.md
+[identifier]: identifiers.md
+[identifiers]: identifiers.md
[implementation]: items/implementations.md
[implementations]: items/implementations.md
[inherent implementation]: items/implementations.md#inherent-implementations
[item]: items.md
+[items]: items.md
+[labels]: tokens.md#lifetimes-and-loop-labels
+[lifetime or loop label]: tokens.md#lifetimes-and-loop-labels
+[lifetimes]: tokens.md#lifetimes-and-loop-labels
+[lints]: attributes/diagnostics.md#lint-check-attributes
+[loop labels]: tokens.md#lifetimes-and-loop-labels
[method]: items/associated-items.md#methods
+[*Name resolution*]: names/name-resolution.md
+[*name*]: names.md
+[*namespace*]: names/namespaces.md
[never type]: types/never.md
[object safety]: items/traits.md#object-safety
+[*path*]: paths.md
+[Paths]: paths.md
+[*scope*]: names/scopes.md
[structs]: items/structs.md
[trait objects]: types/trait-object.md
[traits]: items/traits.md
+[types]: types.md
[undefined-behavior]: behavior-considered-undefined.md
[unions]: items/unions.md
+[variable bindings]: patterns.md
diff --git a/src/items/extern-crates.md b/src/items/extern-crates.md
index e7dc3228b..7c2f9ad76 100644
--- a/src/items/extern-crates.md
+++ b/src/items/extern-crates.md
@@ -12,8 +12,10 @@
An _`extern crate` declaration_ specifies a dependency on an external crate.
The external crate is then bound into the declaring scope as the [identifier]
-provided in the `extern crate` declaration. The `as` clause can be used to
-bind the imported crate to a different name.
+provided in the `extern crate` declaration. Additionally, if the `extern
+crate` appears in the crate root, then the crate name is also added to the
+[extern prelude], making it automatically in scope in all modules. The `as`
+clause can be used to bind the imported crate to a different name.
The external crate is resolved to a specific `soname` at compile time, and a
runtime linkage requirement to that `soname` is passed to the linker for
@@ -52,39 +54,8 @@ extern crate hello_world; // hyphen replaced with an underscore
## Extern Prelude
-External crates imported with `extern crate` in the root module or provided to
-the compiler (as with the `--extern` flag with `rustc`) are added to the
-"extern prelude". Crates in the extern prelude are in scope in the entire
-crate, including inner modules. If imported with `extern crate orig_name as
-new_name`, then the symbol `new_name` is instead added to the prelude.
-
-The `core` crate is always added to the extern prelude. The `std` crate
-is added as long as the [`no_std`] attribute is not specified in the crate root.
-
-The [`no_implicit_prelude`] attribute can be used on a module to disable
-prelude lookups within that module.
-
-> **Edition Differences**: In the 2015 edition, crates in the extern prelude
-> cannot be referenced via [use declarations], so it is generally standard
-> practice to include `extern crate` declarations to bring them into scope.
->
-> Beginning in the 2018 edition, [use declarations] can reference crates in
-> the extern prelude, so it is considered unidiomatic to use `extern crate`.
-
-> **Note**: Additional crates that ship with `rustc`, such as [`alloc`], and
-> [`test`], are not automatically included with the `--extern` flag when using
-> Cargo. They must be brought into scope with an `extern crate` declaration,
-> even in the 2018 edition.
->
-> ```rust
-> extern crate alloc;
-> use alloc::rc::Rc;
-> ```
-
-
+This section has been moved to [Preludes — Extern Prelude](../names/preludes.md#extern-prelude).
+
## Underscore Imports
@@ -94,7 +65,7 @@ useful for crates that only need to be linked, but are never referenced, and
will avoid being reported as unused.
The [`macro_use` attribute] works as usual and import the macro names
-into the macro-use prelude.
+into the [`macro_use` prelude].
## The `no_link` attribute
@@ -105,8 +76,19 @@ crate to access only its macros.
[IDENTIFIER]: ../identifiers.md
[RFC 940]: https://github.com/rust-lang/rfcs/blob/master/text/0940-hyphens-considered-harmful.md
[`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute
-[`alloc`]: https://doc.rust-lang.org/alloc/
-[`no_implicit_prelude`]: modules.md#prelude-items
-[`no_std`]: ../crates-and-source-files.md#preludes-and-no_std
-[`test`]: https://doc.rust-lang.org/test/
-[use declarations]: use-declarations.md
+[extern prelude]: ../names/preludes.md#extern-prelude
+[`macro_use` prelude]: ../names/preludes.md#macro_use-prelude
+
+
diff --git a/src/items/modules.md b/src/items/modules.md
index b688665c0..ff9cae078 100644
--- a/src/items/modules.md
+++ b/src/items/modules.md
@@ -128,15 +128,6 @@ mod thread {
}
```
-## Prelude Items
-
-Modules implicitly have some names in scope. These name are to built-in types,
-macros imported with [`#[macro_use]`][macro_use] on an extern crate, and by the crate's
-[prelude]. These names are all made of a single identifier. These names are not
-part of the module, so for example, any name `name`, `self::name` is not a
-valid path. The names added by the [prelude] can be removed by placing the
-`no_implicit_prelude` [attribute] onto the module or one of its ancestor modules.
-
## Attributes on Modules
Modules, like all items, accept outer attributes. They also accept inner
@@ -144,18 +135,32 @@ attributes: either after `{` for a module with a body, or at the beginning of th
source file, after the optional BOM and shebang.
The built-in attributes that have meaning on a module are [`cfg`],
-[`deprecated`], [`doc`], [the lint check attributes], `path`, and
-`no_implicit_prelude`. Modules also accept macro attributes.
+[`deprecated`], [`doc`], [the lint check attributes], [`path`], and
+[`no_implicit_prelude`]. Modules also accept macro attributes.
[_InnerAttribute_]: ../attributes.md
[_Item_]: ../items.md
-[macro_use]: ../macros-by-example.md#the-macro_use-attribute
[`cfg`]: ../conditional-compilation.md
[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute
[`doc`]: ../../rustdoc/the-doc-attribute.html
+[`no_implicit_prelude`]: ../names/preludes.md#the-no_implicit_prelude-attribute
+[`path`]: #the-path-attribute
[IDENTIFIER]: ../identifiers.md
[attribute]: ../attributes.md
[items]: ../items.md
[module path]: ../paths.md
-[prelude]: ../crates-and-source-files.md#preludes-and-no_std
[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
+
+
diff --git a/src/items/use-declarations.md b/src/items/use-declarations.md
index 8dc5848d8..b29ddcb18 100644
--- a/src/items/use-declarations.md
+++ b/src/items/use-declarations.md
@@ -202,5 +202,5 @@ m!(use std as _;);
[IDENTIFIER]: ../identifiers.md
[_SimplePath_]: ../paths.md#simple-paths
[`extern crate`]: extern-crates.md
-[extern prelude]: extern-crates.md#extern-prelude
+[extern prelude]: ../names/preludes.md#extern-prelude
[path qualifiers]: ../paths.md#path-qualifiers
diff --git a/src/keywords.md b/src/keywords.md
index 9df5b2a58..e303b449e 100644
--- a/src/keywords.md
+++ b/src/keywords.md
@@ -97,8 +97,8 @@ is possible to declare a variable or method with the name `union`.
* `union` is used to declare a [union] and is only a keyword when used in a
union declaration.
-* `'static` is used for the static lifetime and cannot be used as a generic
- lifetime parameter
+* `'static` is used for the static lifetime and cannot be used as a [generic
+ lifetime parameter] or [loop label]
```compile_fail
// error[E0262]: invalid lifetime parameter name: `'static`
@@ -127,3 +127,5 @@ is possible to declare a variable or method with the name `union`.
[union]: items/unions.md
[variants]: items/enumerations.md
[`dyn`]: types/trait-object.md
+[loop label]: expressions/loop-expr.md#loop-labels
+[generic lifetime parameter]: items/generics.md
diff --git a/src/macros-by-example.md b/src/macros-by-example.md
index 78c271403..e97455d0b 100644
--- a/src/macros-by-example.md
+++ b/src/macros-by-example.md
@@ -301,7 +301,7 @@ m!();
Second, it can be used to import macros from another crate, by attaching it to
an `extern crate` declaration appearing in the crate's root module. Macros
-imported this way are imported into the prelude of the crate, not textually,
+imported this way are imported into the [`macro_use` prelude], not textually,
which means that they can be shadowed by any other name. While macros imported
by `#[macro_use]` can be used before the import statement, in case of a
conflict, the last macro imported wins. Optionally, a list of macros to import
@@ -497,3 +497,4 @@ For more detail, see the [formal specification].
[_Visibility_]: visibility-and-privacy.md
[formal specification]: macro-ambiguity.md
[token]: tokens.md
+[`macro_use` prelude]: names/preludes.md#macro_use-prelude
diff --git a/src/names.md b/src/names.md
new file mode 100644
index 000000000..fd8f50cd0
--- /dev/null
+++ b/src/names.md
@@ -0,0 +1,143 @@
+# Names
+
+An *entity* is a language construct that can be referred to in some way within
+the source program, usually via a [path]. Entities include [types], [items],
+[generic parameters], [variable bindings], [loop labels], [lifetimes],
+[fields], [attributes], and [lints].
+
+A *declaration* is a syntactical construct that can introduce a *name* to
+refer to an entity. Entity names are valid within a [*scope*] — a region of
+source text where that name may be referenced.
+
+Some entities are [explicitly declared](#explicitly-declared-entities) in the
+source code, and some are [implicitly declared](#implicitly-declared-entities)
+as part of the language or compiler extensions.
+
+[*Paths*] are used to refer to an entity, possibly in another scope. Lifetimes
+and loop labels use a [dedicated syntax][lifetimes-and-loop-labels] using a
+leading quote.
+
+Names are segregated into different [*namespaces*], allowing entities in
+different namespaces to share the same name without conflict.
+
+[*Name resolution*] is the compile-time process of tying paths, identifiers,
+and labels to entity declarations.
+
+Access to certain names may be restricted based on their [*visibility*].
+
+## Explicitly declared entities
+
+Entities that explicitly introduce a name in the source code are:
+
+* [Items]:
+ * [Module declarations]
+ * [External crate declarations]
+ * [Use declarations]
+ * [Function declarations] and [function parameters]
+ * [Type aliases]
+ * [struct], [union], [enum], enum variant declarations, and their named
+ fields
+ * [Constant item declarations]
+ * [Static item declarations]
+ * [Trait item declarations] and their [associated items]
+ * [External block items]
+ * [`macro_rules` declarations] and [matcher metavariables]
+ * [Implementation] associated items
+* [Expressions]:
+ * [Closure] parameters
+ * [`while let`] pattern bindings
+ * [`for`] pattern bindings
+ * [`if let`] pattern bindings
+ * [`match`] pattern bindings
+ * [Loop labels]
+* [Generic parameters]
+* [Higher ranked trait bounds]
+* [`let` statement] pattern bindings
+* The [`macro_use` attribute] can introduce macro names from another crate
+* The [`macro_export` attribute] can introduce an alias for the macro into the crate root
+
+Additionally, [macro invocations] and [attributes] can introduce names by
+expanding to one of the above items.
+
+## Implicitly declared entities
+
+The following entities are implicitly defined by the language, or are
+introduced by compiler options and extensions:
+
+* [Language prelude]:
+ * [Boolean type] — `bool`
+ * [Textual types] — `char` and `str`
+ * [Integer types] — `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128`
+ * [Machine-dependent integer types] — `usize` and `isize`
+ * [floating-point types] — `f32` and `f64`
+* [Built-in attributes]
+* [Standard library prelude] items, attributes, and macros
+* [Standard library][extern-prelude] crates in the root module
+* [External crates][extern-prelude] linked by the compiler
+* [Tool attributes]
+* [Lints] and [tool lint attributes]
+* [Derive helper attributes] are valid within an item without being explicitly imported
+* The [`'static`] lifetime
+
+Additionally, the crate root module does not have a name, but can be referred
+to with certain [path qualifiers] or aliases.
+
+
+[*Name resolution*]: names/name-resolution.md
+[*namespaces*]: names/namespaces.md
+[*paths*]: paths.md
+[*scope*]: names/scopes.md
+[*visibility*]: visibility-and-privacy.md
+[`'static`]: keywords.md#weak-keywords
+[`for`]: expressions/loop-expr.md#iterator-loops
+[`if let`]: expressions/if-expr.md#if-let-expressions
+[`let` statement]: statements.md#let-statements
+[`macro_export` attribute]: macros-by-example.md#path-based-scope
+[`macro_rules` declarations]: macros-by-example.md
+[`macro_use` attribute]: macros-by-example.md#the-macro_use-attribute
+[`match`]: expressions/match-expr.md
+[`while let`]: expressions/loop-expr.md#predicate-pattern-loops
+[associated items]: items/associated-items.md
+[attributes]: attributes.md
+[Boolean type]: types/boolean.md
+[Built-in attributes]: attributes.md#built-in-attributes-index
+[Closure]: expressions/closure-expr.md
+[Constant item declarations]: items/constant-items.md
+[Derive helper attributes]: procedural-macros.md#derive-macro-helper-attributes
+[enum]: items/enumerations.md
+[Expressions]: expressions.md
+[extern-prelude]: names/preludes.md#extern-prelude
+[External block items]: items/external-blocks.md
+[External crate declarations]: items/extern-crates.md
+[fields]: expressions/field-expr.md
+[floating-point types]: types/numeric.md#floating-point-types
+[Function declarations]: items/functions.md
+[function parameters]: items/functions.md#function-parameters
+[Generic parameters]: items/generics.md
+[Higher ranked trait bounds]: trait-bounds.md#higher-ranked-trait-bounds
+[Implementation]: items/implementations.md
+[Integer types]: types/numeric.md#integer-types
+[Items]: items.md
+[Language prelude]: names/preludes.md#language-prelude
+[lifetimes-and-loop-labels]: tokens.md#lifetimes-and-loop-labels
+[lifetimes]: tokens.md#lifetimes-and-loop-labels
+[Lints]: attributes/diagnostics.md#lint-check-attributes
+[Loop labels]: expressions/loop-expr.md#loop-labels
+[Machine-dependent integer types]: types/numeric.md#machine-dependent-integer-types
+[macro invocations]: macros.md#macro-invocation
+[matcher metavariables]: macros-by-example.md#metavariables
+[Module declarations]: items/modules.md
+[path]: paths.md
+[path qualifiers]: paths.md#path-qualifiers
+[Standard library prelude]: names/preludes.md#standard-library-prelude
+[Static item declarations]: items/static-items.md
+[struct]: items/structs.md
+[Textual types]: types/textual.md
+[Tool attributes]: attributes.md#tool-attributes
+[tool lint attributes]: attributes/diagnostics.md#tool-lint-attributes
+[Trait item declarations]: items/traits.md
+[Type aliases]: items/type-aliases.md
+[types]: types.md
+[union]: items/unions.md
+[Use declarations]: items/use-declarations.md
+[variable bindings]: patterns.md
diff --git a/src/names/name-resolution.md b/src/names/name-resolution.md
new file mode 100644
index 000000000..0f70697a6
--- /dev/null
+++ b/src/names/name-resolution.md
@@ -0,0 +1,3 @@
+# Name resolution
+
+> **Note**: This is a placeholder for future expansion.
diff --git a/src/names/namespaces.md b/src/names/namespaces.md
new file mode 100644
index 000000000..8d2419b39
--- /dev/null
+++ b/src/names/namespaces.md
@@ -0,0 +1,158 @@
+# Namespaces
+
+A *namespace* is a logical grouping of declared [names]. Names are segregated
+into separate namespaces based on the kind of entity the name refers to.
+Namespaces allow the occurrence of a name in one namespace to not conflict
+with the same name in another namespace.
+
+Within a namespace, names are organized in a hierarchy, where each level of
+the hierarchy has its own collection of named entities.
+
+There are several different namespaces that each contain different kinds of
+entities. The usage of a name will look for the declaration of that name in
+different namespaces, based on the context, as described in the [name
+resolution] chapter.
+
+The following is a list of namespaces, with their corresponding entities:
+
+* Type Namespace
+ * [Module declarations]
+ * [External crate declarations]
+ * [External crate prelude] items
+ * [Struct], [union], [enum], enum variant declarations
+ * [Trait item declarations]
+ * [Type aliases]
+ * [Associated type declarations]
+ * Built-in types: [boolean], [numeric], and [textual]
+ * [Generic type parameters]
+ * [`Self` type]
+ * [Tool attribute modules]
+* Value Namespace
+ * [Function declarations]
+ * [Constant item declarations]
+ * [Static item declarations]
+ * [Struct constructors]
+ * [Enum variant constructors]
+ * [`Self` constructors]
+ * [Generic const parameters]
+ * [Associated const declarations]
+ * [Associated function declarations]
+ * Local bindings — [`let`], [`if let`], [`while let`], [`for`], [`match`]
+ arms, [function parameters], [closure parameters]
+ * Captured [closure] variables
+* Macro Namespace
+ * [`macro_rules` declarations]
+ * [Built-in attributes]
+ * [Tool attributes]
+ * [Function-like procedural macros]
+ * [Derive macros]
+ * [Derive macro helpers]
+ * [Attribute macros]
+* Lifetime Namespace
+ * [Generic lifetime parameters]
+* Label Namespace[^rustc-lifetime-shadow]
+ * [Loop labels]
+
+An example of how overlapping names in different namespaces can be used unambiguously:
+
+```rust
+// Foo introduces a type in the type namespace and a constructor in the value
+// namespace.
+struct Foo(u32);
+
+// The `Foo` macro is declared in the macro namespace.
+macro_rules! Foo {
+ () => {};
+}
+
+// `Foo` in the `f` parameter type refers to `Foo` in the type namespace.
+// `'Foo` introduces a new lifetime in the lifetime namespace.
+fn example<'Foo>(f: Foo) {
+ // `Foo` refers to the `Foo` constructor in the value namespace.
+ let ctor = Foo;
+ // `Foo` refers to the `Foo` macro in the macro namespace.
+ Foo!{}
+ // `'Foo` introduces a label in the label namespace.
+ 'Foo: loop {
+ // `'Foo` refers to the `'Foo` lifetime parameter, and `Foo`
+ // refers to the type namespace.
+ let x: &'Foo Foo;
+ // `'Foo` refers to the label.
+ break 'Foo;
+ }
+}
+```
+
+## Named entities without a namespace
+
+The following entities have explicit names, but the names are not a part of
+any specific namespace.
+
+### Fields
+
+Even though struct, enum, and union fields are named, the named fields do not
+live in an explicit namespace. They can only be accessed via a [field
+expression], which only inspects the field names of the specific type being
+accessed.
+
+### Use declarations
+
+A [use declaration] has named aliases that it imports into scope, but the
+`use` item itself does not belong to a specific namespace. Instead, it can
+introduce aliases into multiple namespaces, depending on the item kind being
+imported.
+
+
+
+[^rustc-lifetime-shadow]: `rustc` currently warns about shadowing when using
+ the same name for a label and lifetime in the same scope, but it still
+ treats them independently. This is intended as a future-compatibility
+ warning about a possible extension to the language. See [PR
+ #24162](https://github.com/rust-lang/rust/pull/24162).
+
+[`for`]: ../expressions/loop-expr.md#iterator-loops
+[`if let`]: ../expressions/if-expr.md#if-let-expressions
+[`let`]: ../statements.md#let-statements
+[`macro_rules` declarations]: ../macros-by-example.md
+[`match`]: ../expressions/match-expr.md
+[`Self` constructors]: ../paths.md#self-1
+[`Self` type]: ../paths.md#self-1
+[`while let`]: ../expressions/loop-expr.md#predicate-pattern-loops
+[Associated const declarations]: ../items/associated-items.md#associated-constants
+[Associated function declarations]: ../items/associated-items.md#associated-functions-and-methods
+[Associated type declarations]: ../items/associated-items.md#associated-types
+[Attribute macros]: ../procedural-macros.md#attribute-macros
+[boolean]: ../types/boolean.md
+[Built-in attributes]: ../attributes.md#built-in-attributes-index
+[closure parameters]: ../expressions/closure-expr.md
+[closure]: ../expressions/closure-expr.md
+[Constant item declarations]: ../items/constant-items.md
+[Derive macro helpers]: ../procedural-macros.md#derive-macro-helper-attributes
+[Derive macros]: ../procedural-macros.md#derive-macros
+[entity]: ../glossary.md#entity
+[Enum variant constructors]: ../items/enumerations.md
+[enum]: ../items/enumerations.md
+[External crate declarations]: ../items/extern-crates.md
+[External crate prelude]: preludes.md#extern-prelude
+[field expression]: ../expressions/field-expr.md
+[Function declarations]: ../items/functions.md
+[function parameters]: ../items/functions.md#function-parameters
+[Function-like procedural macros]: ../procedural-macros.md#function-like-procedural-macros
+[Generic const parameters]: ../items/generics.md#const-generics
+[Generic lifetime parameters]: ../items/generics.md
+[Generic type parameters]: ../items/generics.md
+[Loop labels]: ../expressions/loop-expr.md#loop-labels
+[Module declarations]: ../items/modules.md
+[name resolution]: name-resolution.md
+[names]: ../names.md
+[numeric]: ../types/numeric.md
+[Static item declarations]: ../items/static-items.md
+[Struct constructors]: ../items/structs.md
+[Struct]: ../items/structs.md
+[textual]: ../types/textual.md
+[Tool attribute modules]: ../attributes.md#tool-attributes
+[Tool attributes]: ../attributes.md#tool-attributes
+[Trait item declarations]: ../items/traits.md
+[Type aliases]: ../items/type-aliases.md
+[union]: ../items/unions.md
+[use declaration]: ../items/use-declarations.md
diff --git a/src/names/preludes.md b/src/names/preludes.md
new file mode 100644
index 000000000..602776315
--- /dev/null
+++ b/src/names/preludes.md
@@ -0,0 +1,157 @@
+# Preludes
+
+A *prelude* is a collection of names that are automatically brought into scope
+of every module in a crate.
+
+These prelude names are not part of the module itself, they are implicitly
+queried during [name resolution]. For example, even though something like
+[`Box`] is in scope in every module, you cannot refer to it as `self::Box`
+because it is not a member of the current module.
+
+There are several different preludes:
+
+- [Standard library prelude]
+- [Extern prelude]
+- [Language prelude]
+- [`macro_use` prelude]
+- [Tool prelude]
+
+## Standard library prelude
+
+The standard library prelude includes names from the [`std::prelude::v1`]
+module. If the [`no_std` attribute] is used, then it instead uses the names
+from the [`core::prelude::v1`] module.
+
+## Extern prelude
+
+External crates imported with [`extern crate`] in the root module or provided
+to the compiler (as with the `--extern` flag with `rustc`) are added to the
+*extern prelude*. If imported with an alias such as `extern crate orig_name as
+new_name`, then the symbol `new_name` is instead added to the prelude.
+
+The [`core`] crate is always added to the extern prelude. The [`std`] crate is
+added as long as the [`no_std` attribute] is not specified in the crate root.
+
+> **Edition Differences**: In the 2015 edition, crates in the extern prelude
+> cannot be referenced via [use declarations], so it is generally standard
+> practice to include `extern crate` declarations to bring them into scope.
+>
+> Beginning in the 2018 edition, [use declarations] can reference crates in
+> the extern prelude, so it is considered unidiomatic to use `extern crate`.
+
+> **Note**: Additional crates that ship with `rustc`, such as [`alloc`], and
+> [`test`], are not automatically included with the `--extern` flag when using
+> Cargo. They must be brought into scope with an `extern crate` declaration,
+> even in the 2018 edition.
+>
+> ```rust
+> extern crate alloc;
+> use alloc::rc::Rc;
+> ```
+>
+> Cargo does bring in `proc_macro` to the extern prelude for proc-macro crates
+> only.
+
+
+
+### The `no_std` attribute
+
+By default, the standard library is automatically included in the crate root
+module. The [`std`] crate is added to the root, along with an implicit
+[`macro_use` attribute] pulling in all macros exported from `std` into the
+[`macro_use` prelude]. Both [`core`] and [`std`] are added to the [extern
+prelude]. The [standard library prelude] includes everything from the
+[`std::prelude::v1`] module.
+
+The *`no_std` [attribute]* may be applied at the crate level to prevent the
+[`std`] crate from being automatically added into scope. It does three things:
+
+* Prevents `std` from being added to the [extern prelude](#extern-prelude).
+* Uses [`core::prelude::v1`] in the [standard library prelude] instead of
+ [`std::prelude::v1`].
+* Injects the [`core`] crate into the crate root instead of [`std`], and pulls
+ in all macros exported from `core` in the [`macro_use` prelude].
+
+> **Note**: Using the core prelude over the standard prelude is useful when
+> either the crate is targeting a platform that does not support the standard
+> library or is purposefully not using the capabilities of the standard
+> library. Those capabilities are mainly dynamic memory allocation (e.g. `Box`
+> and `Vec`) and file and network capabilities (e.g. `std::fs` and `std::io`).
+
+
+
+Warning: Using `no_std` does not prevent the standard library from being
+linked in. It is still valid to put `extern crate std;` into the crate and
+dependencies can also link it in.
+
+
+
+## Language prelude
+
+The language prelude includes names of types and attributes that are built-in
+to the language. The language prelude is always in scope. It includes the following:
+
+* [Type namespace]
+ * [Boolean type] — `bool`
+ * [Textual types] — `char` and `str`
+ * [Integer types] — `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128`
+ * [Machine-dependent integer types] — `usize` and `isize`
+ * [floating-point types] — `f32` and `f64`
+* [Macro namespace]
+ * [Built-in attributes]
+
+## `macro_use` prelude
+
+The `macro_use` prelude includes macros from external crates that were
+imported by the [`macro_use` attribute] applied to an [`extern crate`].
+
+## Tool prelude
+
+The tool prelude includes tool names for external tools in the [type
+namespace]. See the [tool attributes] section for more details.
+
+## The `no_implicit_prelude` attribute
+
+The *`no_implicit_prelude` [attribute]* may be applied at the crate level or
+on a module to indicate that it should not automatically bring the [standard
+library prelude], [extern prelude], or [tool prelude] into scope for that
+module or any of its descendants.
+
+This attribute does not affect the [language prelude].
+
+> **Edition Differences**: In the 2015 edition, the `no_implicit_prelude`
+> attribute does not affect the [`macro_use` prelude], and all macros exported
+> from the standard library are still included in the `macro_use` prelude.
+> Starting in the 2018 edition, it will remove the `macro_use` prelude.
+
+[`alloc`]: ../../alloc/index.html
+[`Box`]: ../../std/boxed/struct.Box.html
+[`core::prelude::v1`]: ../../core/prelude/index.html
+[`core`]: ../../core/index.html
+[`extern crate`]: ../items/extern-crates.md
+[`macro_use` attribute]: ../macros-by-example.md#the-macro_use-attribute
+[`macro_use` prelude]: #macro_use-prelude
+[`no_std` attribute]: #the-no_std-attribute
+[`no_std` attribute]: #the-no_std-attribute
+[`std::prelude::v1`]: ../../std/prelude/index.html
+[`std`]: ../../std/index.html
+[`test`]: ../../test/index.html
+[attribute]: ../attributes.md
+[Boolean type]: ../types/boolean.md
+[Built-in attributes]: ../attributes.md#built-in-attributes-index
+[extern prelude]: #extern-prelude
+[floating-point types]: ../types/numeric.md#floating-point-types
+[Integer types]: ../types/numeric.md#integer-types
+[Language prelude]: #language-prelude
+[Machine-dependent integer types]: ../types/numeric.md#machine-dependent-integer-types
+[Macro namespace]: namespaces.md
+[name resolution]: name-resolution.md
+[Standard library prelude]: #standard-library-prelude
+[Textual types]: ../types/textual.md
+[tool attributes]: ../attributes.md#tool-attributes
+[Tool prelude]: #tool-prelude
+[Type namespace]: namespaces.md
+[use declarations]: ../items/use-declarations.md
diff --git a/src/names/scopes.md b/src/names/scopes.md
new file mode 100644
index 000000000..288781bd3
--- /dev/null
+++ b/src/names/scopes.md
@@ -0,0 +1,3 @@
+# Scopes
+
+> **Note**: This is a placeholder for future expansion.
diff --git a/src/paths.md b/src/paths.md
index 29d2475b5..c0b2e6ff3 100644
--- a/src/paths.md
+++ b/src/paths.md
@@ -164,10 +164,11 @@ start being resolved from the crate root. Each identifier in the path must resol
item.
> **Edition Differences**: In the 2015 Edition, the crate root contains a variety of
-> different items, including external crates, default crates such as `std` and `core`, and
+> different items, including external crates, default crates such as `std` or `core`, and
> items in the top level of the crate (including `use` imports).
>
-> Beginning with the 2018 Edition, paths starting with `::` can only reference crates.
+> Beginning with the 2018 Edition, paths starting with `::` can only reference
+> crates in the [extern prelude].
```rust
mod a {
@@ -380,6 +381,7 @@ mod without { // ::without
[`use`]: items/use-declarations.md
[attributes]: attributes.md
[expressions]: expressions.md
+[extern prelude]: names/preludes.md#extern-prelude
[macro transcribers]: macros-by-example.md
[macros]: macros-by-example.md
[patterns]: patterns.md