Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add details on how names are introduced. #1052

Merged
merged 12 commits into from
Jul 30, 2024
2 changes: 1 addition & 1 deletion src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ active. All other attributes are inert.
## Tool attributes

The compiler may allow attributes for external tools where each tool resides
in its own namespace in the [tool prelude]. The first segment of the attribute
in its own module 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.

Expand Down
3 changes: 3 additions & 0 deletions src/items/constant-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ context when used. This includes usage of constants from external crates, and
non-[`Copy`] types. References to the same constant are not necessarily
guaranteed to refer to the same memory address.

The constant declaration defines the constant value in the [value namespace] of the module or block where it is located.

Constants must be explicitly typed. The type must have a `'static` lifetime: any
references in the initializer must have `'static` lifetimes.

Expand Down Expand Up @@ -115,3 +117,4 @@ fn unused_generic_function<T>() {
[_Type_]: ../types.md#type-expressions
[_Expression_]: ../expressions.md
[`Copy`]: ../special-types-and-traits.md#copy
[value namespace]: ../names/namespaces.md
52 changes: 42 additions & 10 deletions src/items/enumerations.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ nominal [enumerated type] as well as a set of *constructors*, that can be used
to create or pattern-match values of the corresponding enumerated type.

Enumerations are declared with the keyword `enum`.
The `enum` declaration defines the enumeration type in the [type namespace] of the module or block where it is located.

An example of an `enum` item and its use:

Expand Down Expand Up @@ -80,6 +81,30 @@ enum Enum {
}
```

Variant constructors are similar to [struct] definitions, and can be referenced by a path from the enumeration name, including in [use declarations].
Each variant defines its type in the [type namespace], though that type cannot be used as a type specifier.
Each variant also defines a constructor in the [value namespace].

A struct-like variant can be instantiated with a [struct expression].
A tuple-like variant can be instantiated with a [call expression] or a [struct expression].
A unit-like variant can be instantiated with a [path expression] or a [struct expression].
For example:

```rust
enum Examples {
UnitLike,
TupleLike(i32),
StructLike { value: i32 },
}

use Examples::*; // Creates aliases to all variants.
let x = UnitLike; // Path expression of the const item.
let x = UnitLike {}; // Struct expression.
let y = TupleLike(123); // Call expression.
let y = TupleLike { 0: 123 }; // Struct expression using integer field names.
let z = StructLike { value: 123 }; // Struct expression.
```

<span id="custom-discriminant-values-for-fieldless-enumerations"></span>
## Discriminants

Expand Down Expand Up @@ -299,20 +324,27 @@ enum E {
}
```

[IDENTIFIER]: ../identifiers.md
[_GenericParams_]: generics.md
[_WhereClause_]: generics.md#where-clauses
[_Expression_]: ../expressions.md
[_TupleFields_]: structs.md
[_GenericParams_]: generics.md
[_StructFields_]: structs.md
[_TupleFields_]: structs.md
[_Visibility_]: ../visibility-and-privacy.md
[enumerated type]: ../types/enum.md
[_WhereClause_]: generics.md#where-clauses
[`C` representation]: ../type-layout.md#the-c-representation
[`mem::discriminant`]: ../../std/mem/fn.discriminant.html
[never type]: ../types/never.md
[unit-only]: #unit-only-enum
[numeric cast]: ../expressions/operator-expr.md#semantics
[call expression]: ../expressions/call-expr.md
[constant expression]: ../const_eval.md#constant-expressions
[default representation]: ../type-layout.md#the-default-representation
[primitive representation]: ../type-layout.md#primitive-representations
[`C` representation]: ../type-layout.md#the-c-representation
[enumerated type]: ../types/enum.md
[Field-less enums]: #field-less-enum
[IDENTIFIER]: ../identifiers.md
[never type]: ../types/never.md
[numeric cast]: ../expressions/operator-expr.md#semantics
[path expression]: ../expressions/path-expr.md
[primitive representation]: ../type-layout.md#primitive-representations
[struct expression]: ../expressions/struct-expr.md
[struct]: structs.md
[type namespace]: ../names/namespaces.md
[unit-only]: #unit-only-enum
[use declarations]: use-declarations.md
[value namespace]: ../names/namespaces.md
9 changes: 4 additions & 5 deletions src/items/extern-crates.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@
> &nbsp;&nbsp; `as` ( [IDENTIFIER] | `_` )

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. 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 then bound into the declaring scope as the given [identifier] in the [type namespace].
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
Expand Down Expand Up @@ -74,6 +72,7 @@ crate to access only its macros.
[extern prelude]: ../names/preludes.md#extern-prelude
[`macro_use` prelude]: ../names/preludes.md#macro_use-prelude
[`crate_name` attributes]: ../crates-and-source-files.md#the-crate_name-attribute
[type namespace]: ../names/namespaces.md

<script>
(function() {
Expand Down
3 changes: 3 additions & 0 deletions src/items/external-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Two kinds 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.

The external block defines its functions and statics in the [value namespace] of the module or block where it is located.

The `unsafe` keyword is syntactically allowed to appear before the `extern`
keyword, but it is rejected at a semantic level. This allows macros to consume
the syntax and make use of the `unsafe` keyword, before removing it from the
Expand Down Expand Up @@ -342,3 +344,4 @@ restrictions as [regular function parameters].
[`verbatim` documentation for rustc]: ../../rustc/command-line-arguments.html#linking-modifiers-verbatim
[`dylib` versus `raw-dylib`]: #dylib-versus-raw-dylib
[PE Format]: https://learn.microsoft.com/windows/win32/debug/pe-format#import-name-type
[value namespace]: ../names/namespaces.md
3 changes: 2 additions & 1 deletion src/items/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
A _function_ consists of a [block] (that's the _body_ of the function),
along with a name, a set of parameters, and an output type.
Other than a name, all these are optional.
Functions are declared with the keyword `fn`.
Functions are declared with the keyword `fn` which defines the given name in the [value namespace] of the module or block where it is located.
Functions may declare a set of *input* [*variables*][variables] as parameters, through which the caller passes arguments into the function, and the *output* [*type*][type] of the value the function will return to its caller on completion.
If the output type is not explicitly stated, it is the [unit type].

Expand Down Expand Up @@ -413,4 +413,5 @@ fn foo_oof(#[some_inert_attribute] arg: u8) {
[method]: associated-items.md#methods
[associated function]: associated-items.md#associated-functions-and-methods
[implementation]: implementations.md
[value namespace]: ../names/namespaces.md
[variadic function]: external-blocks.md#variadic-functions
11 changes: 4 additions & 7 deletions src/items/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@ referred to with path syntax.

### Const generics

*Const generic parameters* allow items to be generic over constant values. The
const identifier introduces a name for the constant parameter, and all
instances of the item must be instantiated with a value of the given type.

<!-- TODO: update above to say "introduces a name in the [value namespace]"
once namespaces are added. -->
*Const generic parameters* allow items to be generic over constant values.
The const identifier introduces a name in the [value namespace] for the constant parameter, and all instances of the item must be instantiated with a value of the given type.

The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`,
`i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`.
Expand Down Expand Up @@ -282,6 +278,7 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
[slices]: ../types/slice.md
[associated const]: associated-items.md#associated-constants
[associated type]: associated-items.md#associated-types
[attributes]: ../attributes.md
[block]: ../expressions/block-expr.md
[const contexts]: ../const_eval.md#const-context
[const expression]: ../const_eval.md#constant-expressions
Expand All @@ -307,4 +304,4 @@ struct Foo<#[my_flexible_clone(unbounded)] H> {
[type aliases]: type-aliases.md
[type]: ../types.md
[unions]: unions.md
[attributes]: ../attributes.md
[value namespace]: ../names/namespaces.md
10 changes: 5 additions & 5 deletions src/items/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ mod math {
}
```

Modules and types share the same namespace. Declaring a named type with the
same name as a module in scope is forbidden: that is, a type definition, trait,
struct, enumeration, union, type parameter or crate can't shadow the name of a
module in scope, or vice versa. Items brought into scope with `use` also have
this restriction.
Modules are defined in the [type namespace] of the module or block where they are located.
It is an error to define multiple items with the same name in the same namespace within a module.
See the [scopes chapter] for more details on restrictions and shadowing behavior.

The `unsafe` keyword is syntactically allowed to appear before the `mod`
keyword, but it is rejected at a semantic level. This allows macros to consume
Expand Down Expand Up @@ -149,7 +147,9 @@ The built-in attributes that have meaning on a module are [`cfg`],
[attribute]: ../attributes.md
[items]: ../items.md
[module path]: ../paths.md
[scopes chapter]: ../names/scopes.md
[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
[type namespace]: ../names/namespaces.md

<script>
(function() {
Expand Down
3 changes: 3 additions & 0 deletions src/items/static-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ memory location. Static items have the `static` lifetime, which outlives all
other lifetimes in a Rust program. Static items do not call [`drop`] at the
end of the program.

The static declaration defines a static value in the [value namespace] of the module or block where it is located.

The static initializer is a [constant expression] evaluated at compile time.
Static initializers may refer to other statics.

Expand Down Expand Up @@ -136,3 +138,4 @@ following are true:
[IDENTIFIER]: ../identifiers.md
[_Type_]: ../types.md#type-expressions
[_Expression_]: ../expressions.md
[value namespace]: ../names/namespaces.md
28 changes: 16 additions & 12 deletions src/items/structs.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
> &nbsp;&nbsp; [_Type_]

A _struct_ is a nominal [struct type] defined with the keyword `struct`.
A struct declaration defines the given name in the [type namespace] of the module or block where it is located.

An example of a `struct` item and its use:

Expand All @@ -46,11 +47,10 @@ let p = Point {x: 10, y: 11};
let px: i32 = p.x;
```

A _tuple struct_ is a nominal [tuple type], also defined with the keyword
`struct`. For example:

[struct type]: ../types/struct.md
[tuple type]: ../types/tuple.md
A _tuple struct_ is a nominal [tuple type], and is also defined with the keyword `struct`.
In addition to defining a type, it also defines a constructor of the same name in the [value namespace].
The constructor is a function which can be called to create a new instance of the struct.
For example:

```rust
struct Point(i32, i32);
Expand All @@ -59,7 +59,7 @@ let px: i32 = match p { Point(x, _) => x };
```

A _unit-like struct_ is a struct without any fields, defined by leaving off the
list of fields entirely. Such a struct implicitly defines a constant of its
list of fields entirely. Such a struct implicitly defines a [constant] of its
type with the same name. For example:

```rust
Expand All @@ -78,11 +78,15 @@ let c = [Cookie, Cookie {}, Cookie, Cookie {}];
The precise memory layout of a struct is not specified. One can specify a
particular layout using the [`repr` attribute].

[`repr` attribute]: ../type-layout.md#representations

[_OuterAttribute_]: ../attributes.md
[IDENTIFIER]: ../identifiers.md
[_GenericParams_]: generics.md
[_WhereClause_]: generics.md#where-clauses
[_Visibility_]: ../visibility-and-privacy.md
[_OuterAttribute_]: ../attributes.md
[_Type_]: ../types.md#type-expressions
[_Visibility_]: ../visibility-and-privacy.md
[_WhereClause_]: generics.md#where-clauses
[`repr` attribute]: ../type-layout.md#representations
[IDENTIFIER]: ../identifiers.md
[constant]: constant-items.md
[struct type]: ../types/struct.md
[tuple type]: ../types/tuple.md
[type namespace]: ../names/namespaces.md
[value namespace]: ../names/namespaces.md
4 changes: 4 additions & 0 deletions src/items/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ interface consists of [associated items], which come in three varieties:
- [types](associated-items.md#associated-types)
- [constants](associated-items.md#associated-constants)

The trait declaration defines a trait in the [type namespace] of the module or block where it is located.
Associated items are defined as members of the trait within their respective namespaces. Associated types are defined in the type namespace. Associated constants and associated functions are defined in the value namespace.

All traits define an implicit type parameter `Self` that refers to "the type
that is implementing this interface". Traits may also contain additional type
parameters. These type parameters, including `Self`, may be constrained by
Expand Down Expand Up @@ -345,3 +348,4 @@ fn main() {
[`Rc<Self>`]: ../special-types-and-traits.md#rct
[`async`]: functions.md#async-functions
[`const`]: functions.md#const-functions
[type namespace]: ../names/namespaces.md
8 changes: 4 additions & 4 deletions src/items/type-aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
> ( `:` [_TypeParamBounds_] )<sup>?</sup>
> [_WhereClause_]<sup>?</sup> ( `=` [_Type_] [_WhereClause_]<sup>?</sup>)<sup>?</sup> `;`

A _type alias_ defines a new name for an existing [type]. Type aliases are
declared with the keyword `type`. Every value has a single, specific type, but
may implement several different traits, or be compatible with several different
type constraints.
A _type alias_ defines a new name for an existing [type] in the [type namespace] of the module or block where it is located.
Type aliases are declared with the keyword `type`.
Every value has a single, specific type, but may implement several different traits, and may be compatible with several different type constraints.

For example, the following defines the type `Point` as a synonym for the type
`(u8, u8)`, the type of pairs of unsigned 8 bit integers:
Expand Down Expand Up @@ -53,3 +52,4 @@ the equals sign (like `type TypeAlias<T> = Bar<T> where T: Foo`) are preferred.
[trait]: traits.md
[type]: ../types.md
[trait impl]: implementations.md#trait-implementations
[type namespace]: ../names/namespaces.md
2 changes: 2 additions & 0 deletions src/items/unions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

A union declaration uses the same syntax as a struct declaration, except with
`union` in place of `struct`.
A union declaration defines the given name in the [type namespace] of the module or block where it is located.

```rust
#[repr(C)]
Expand Down Expand Up @@ -179,4 +180,5 @@ checking, etc etc etc).
[boolean type]: ../types/boolean.md
[ManuallyDrop]: ../../std/mem/struct.ManuallyDrop.html
[the C representation]: ../type-layout.md#reprc-unions
[type namespace]: ../names/namespaces.md
[undefined behavior]: ../behavior-considered-undefined.html
Loading