From eabdf09207bf3563ae96db9d576de0758c413d5d Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 17 Jun 2019 11:01:01 -0700 Subject: [PATCH 1/7] Start documenting name resolution. --- src/SUMMARY.md | 10 ++- src/attributes.md | 11 +-- src/crates-and-source-files.md | 42 ++++------ src/glossary.md | 53 ++++++++++++ src/items/extern-crates.md | 61 +++++--------- src/items/modules.md | 31 ++++--- src/items/use-declarations.md | 2 +- src/keywords.md | 6 +- src/macros-by-example.md | 3 +- src/names.md | 133 +++++++++++++++++++++++++++++ src/names/name-resolution.md | 3 + src/names/namespaces.md | 148 +++++++++++++++++++++++++++++++++ src/names/preludes.md | 144 ++++++++++++++++++++++++++++++++ src/names/scopes.md | 3 + src/paths.md | 6 +- 15 files changed, 564 insertions(+), 92 deletions(-) create mode 100644 src/names.md create mode 100644 src/names/name-resolution.md create mode 100644 src/names/namespaces.md create mode 100644 src/names/preludes.md create mode 100644 src/names/scopes.md 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..7f0d58549 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -61,6 +61,11 @@ 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 [type], [item], [generic parameter], [variable binding], +[loop label], [lifetime], [field], or [attribute]. + ### Expression An expression is a combination of values, constants, variables, operators @@ -123,6 +128,24 @@ 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 collection of uniquely named [entities](#entity). +Namespaces can be 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 +156,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 +250,36 @@ 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 +[attribute]: attributes.md +[*entity*]: names.md [enums]: items/enumerations.md +[field]: expressions/field-expr.md [free item]: #free-item +[generic parameter]: 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 +[item]: items.md +[labels]: tokens.md#lifetimes-and-loop-labels +[lifetime or loop label]: tokens.md#lifetimes-and-loop-labels +[lifetime]: tokens.md#lifetimes-and-loop-labels +[loop label]: 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 +[type]: types.md [undefined-behavior]: behavior-considered-undefined.md [unions]: items/unions.md +[variable binding]: patterns.md diff --git a/src/items/extern-crates.md b/src/items/extern-crates.md index e7dc3228b..784a401c3 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 @@ -105,8 +76,18 @@ 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 + + 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..775821e74 --- /dev/null +++ b/src/names.md @@ -0,0 +1,133 @@ +# Names + +Entities declare a *name* to refer to that entity. Some entities are +[explicitly declared](#explicit-entities) in the source code, and some are +[implicitly declared](#implicit-entities) as part of the language or compiler +extensions. + +Entity names are valid within a [*scope*] — a region of source text where that +name may be referenced. + +[*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*]. + +## Explicit 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. + +## Implicit 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]. + + +[*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 +[path qualifiers]: paths.md#path-qualifiers +[`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 +[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 +[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 +[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 +[union]: items/unions.md +[Use declarations]: items/use-declarations.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..62b5584da --- /dev/null +++ b/src/names/namespaces.md @@ -0,0 +1,148 @@ +# Namespaces + +Entity names are segregated into separate *namespaces* based on the kind of +entity that declared the name. 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 +[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 +[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..7bf47af98 --- /dev/null +++ b/src/names/preludes.md @@ -0,0 +1,144 @@ +# 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 + +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`. + +> **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] or [`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 From c7f564802c04040c9e665bb6b2f25b07090b206b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 18 Jan 2021 09:30:01 -0800 Subject: [PATCH 2/7] List formatting nit. --- src/names.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/names.md b/src/names.md index 775821e74..bb3b3a6a5 100644 --- a/src/names.md +++ b/src/names.md @@ -24,7 +24,7 @@ Access to certain names may be restricted based on their [*visibility*]. Entities that explicitly introduce a name in the source code are: -* [Items] +* [Items]: * [Module declarations] * [External crate declarations] * [Use declarations] @@ -38,7 +38,7 @@ Entities that explicitly introduce a name in the source code are: * [External block items] * [`macro_rules` declarations] and [matcher metavariables] * [Implementation] associated items -* [Expressions] +* [Expressions]: * [Closure] parameters * [`while let`] pattern bindings * [`for`] pattern bindings @@ -59,7 +59,7 @@ expanding to one of the above items. The following entities are implicitly defined by the language, or are introduced by compiler options and extensions: -* [Language prelude] +* [Language prelude]: * [Boolean type] — `bool` * [Textual types] — `char` and `str` * [Integer types] — `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128` From afb3464c615bdcab4f0f86693a80fa9e999c3394 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 18 Jan 2021 10:30:42 -0800 Subject: [PATCH 3/7] Update definition of namespace. --- src/glossary.md | 7 ++++--- src/names/namespaces.md | 14 ++++++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/glossary.md b/src/glossary.md index 7f0d58549..e1622fea9 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -142,9 +142,10 @@ identifiers, and labels are used to refer to an entity. ### Namespace -A [*namespace*] is a collection of uniquely named [entities](#entity). -Namespaces can be organized in a hierarchy, where each level of the hierarchy -has its own collection of named entities. +A [*namespace*] is a set of [names](#name) where each name unambiguously +refers to a specific [entity](#entity). Namespaces are organized in a +hierarchy, where each level of the hierarchy has its own collection of named +entities. ### Nominal types diff --git a/src/names/namespaces.md b/src/names/namespaces.md index 62b5584da..5136cfcd6 100644 --- a/src/names/namespaces.md +++ b/src/names/namespaces.md @@ -1,9 +1,13 @@ # Namespaces -Entity names are segregated into separate *namespaces* based on the kind of -entity that declared the name. 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. +A *namespace* is a set of [names] where each name unambiguously refers to a +specific [entity]. Namespaces 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: @@ -121,6 +125,7 @@ imported. [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 @@ -135,6 +140,7 @@ imported. [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 From 3847261a394242b00f6f0acf96ac9c186771345c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 18 Jan 2021 11:34:53 -0800 Subject: [PATCH 4/7] Take another stab at defining "entity". --- src/glossary.md | 23 +++++++++++++---------- src/names.md | 26 ++++++++++++++++++-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/glossary.md b/src/glossary.md index e1622fea9..202841abf 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -63,8 +63,10 @@ A dynamically sized type (DST) is a type without a statically known size or alig ### Entity -An [*entity*] is a [type], [item], [generic parameter], [variable binding], -[loop label], [lifetime], [field], or [attribute]. +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 @@ -251,23 +253,24 @@ 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 -[attribute]: attributes.md +[attributes]: attributes.md [*entity*]: names.md [enums]: items/enumerations.md -[field]: expressions/field-expr.md +[fields]: expressions/field-expr.md [free item]: #free-item -[generic parameter]: items/generics.md +[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 -[item]: items.md +[items]: items.md [labels]: tokens.md#lifetimes-and-loop-labels [lifetime or loop label]: tokens.md#lifetimes-and-loop-labels -[lifetime]: tokens.md#lifetimes-and-loop-labels -[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 @@ -280,7 +283,7 @@ example of an uninhabited type is the [never type] `!`, or an enum with no varia [structs]: items/structs.md [trait objects]: types/trait-object.md [traits]: items/traits.md -[type]: types.md +[types]: types.md [undefined-behavior]: behavior-considered-undefined.md [unions]: items/unions.md -[variable binding]: patterns.md +[variable bindings]: patterns.md diff --git a/src/names.md b/src/names.md index bb3b3a6a5..c5fa809df 100644 --- a/src/names.md +++ b/src/names.md @@ -1,12 +1,17 @@ # Names -Entities declare a *name* to refer to that entity. Some entities are -[explicitly declared](#explicit-entities) in the source code, and some are -[implicitly declared](#implicit-entities) as part of the language or compiler -extensions. +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]. -Entity names are valid within a [*scope*] — a region of source text where that -name may be referenced. +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](#explicit-entities) in the source +code, and some are [implicitly declared](#implicit-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 @@ -75,16 +80,16 @@ introduced by compiler options and extensions: * The [`'static`] lifetime Additionally, the crate root module does not have a name, but can be referred -to with certain [path qualifiers]. +to with certain [path qualifiers] or aliases. [*Name resolution*]: names/name-resolution.md [*namespaces*]: names/namespaces.md +[*path*]: paths.md [*paths*]: paths.md [*scope*]: names/scopes.md [*visibility*]: visibility-and-privacy.md [`'static`]: keywords.md#weak-keywords -[path qualifiers]: paths.md#path-qualifiers [`for`]: expressions/loop-expr.md#iterator-loops [`if let`]: expressions/if-expr.md#if-let-expressions [`let` statement]: statements.md#let-statements @@ -105,6 +110,7 @@ to with certain [path qualifiers]. [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 @@ -115,12 +121,14 @@ to with certain [path qualifiers]. [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 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 @@ -129,5 +137,7 @@ to with certain [path qualifiers]. [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 From 0ce54e64e3c98d99862485c57087d0ab36f40ef0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 18 Jan 2021 17:13:53 -0800 Subject: [PATCH 5/7] Updates to no_implicit_prelude and no_std. * Fix: no_implicit_prelude behaves differently in 2015. * Try to make it clearer how standard library stuff is injected into the crate. --- src/items/extern-crates.md | 3 ++- src/names/preludes.md | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/items/extern-crates.md b/src/items/extern-crates.md index 784a401c3..7c2f9ad76 100644 --- a/src/items/extern-crates.md +++ b/src/items/extern-crates.md @@ -65,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 @@ -77,6 +77,7 @@ crate to access only its macros. [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 [extern prelude]: ../names/preludes.md#extern-prelude +[`macro_use` prelude]: ../names/preludes.md#macro_use-prelude