From 0aabecf5783457d3d8fb0c27715705813543020f Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Fri, 30 Aug 2024 16:58:55 -0400 Subject: [PATCH 1/4] Add identifier syntax to items.md and subchapters --- src/items.md | 40 +++++++++- src/items/associated-items.md | 87 ++++++++++++++++++---- src/items/constant-items.md | 22 +++++- src/items/enumerations.md | 49 +++++++++++- src/items/extern-crates.md | 19 +++++ src/items/external-blocks.md | 135 ++++++++++++++++++++++++++++++++-- src/items/functions.md | 72 +++++++++++++++++- src/items/generics.md | 33 ++++++++- src/items/implementations.md | 47 +++++++++++- src/items/modules.md | 32 +++++++- src/items/static-items.md | 32 +++++++- src/items/structs.md | 9 +++ src/items/traits.md | 44 +++++++++++ src/items/type-aliases.md | 9 +++ src/items/unions.md | 69 ++++++++++++++--- src/items/use-declarations.md | 65 +++++++++++++++- 16 files changed, 714 insertions(+), 50 deletions(-) diff --git a/src/items.md b/src/items.md index 00639acf4..e3763d457 100644 --- a/src/items.md +++ b/src/items.md @@ -1,5 +1,8 @@ # Items +r[items] + +r[items.syntax] > **Syntax:**\ > _Item_:\ >    [_OuterAttribute_]\*\ @@ -28,36 +31,71 @@ >       [_MacroInvocationSemi_]\ >    | [_MacroRulesDefinition_] - +r[items.intro] An _item_ is a component of a crate. Items are organized within a crate by a nested set of [modules]. Every crate has a single "outermost" anonymous module; all further items within the crate have [paths] within the module tree of the crate. +r[items.static-def] Items are entirely determined at compile-time, generally remain fixed during execution, and may reside in read-only memory. +r[items.kinds] There are several kinds of items: +r[items.kind-modules] * [modules] + +r[items.kind-extern-crate] * [`extern crate` declarations] + +r[items.kind-use] * [`use` declarations] + +r[items.kind-fn] * [function definitions] + +r[items.kind-type] * [type definitions] + +r[items.kind-struct] * [struct definitions] + +r[items.kind-enum] * [enumeration definitions] + +r[items.kind-union] * [union definitions] + +r[items.kind-const] * [constant items] + +r[items.kind-static] * [static items] + +r[items.kind-trait] * [trait definitions] + +r[items.kind-impl] * [implementations] + +r[items.kind-extern] * [`extern` blocks] +r[items.locations] Items may be declared in the [root of the crate], a [module][modules], or a [block expression]. + +r[items.associated-locations] A subset of items, called [associated items], may be declared in [traits] and [implementations]. + +r[items.extern-locations] A subset of items, called external items, may be declared in [`extern` blocks]. +r[items.decl-order] Items may be defined in any order, with the exception of [`macro_rules`] which has its own scoping behavior. + +r[items.name-resolution] [Name resolution] of item names allows items to be defined before or after where the item is referred to in the module or block. See [item scopes] for information on the scoping rules of items. diff --git a/src/items/associated-items.md b/src/items/associated-items.md index c4e7a194f..d7ba4ea01 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -1,5 +1,8 @@ # Associated Items +r[items.associated] + +r[items.associated.syntax] > **Syntax**\ > _AssociatedItem_ :\ >    [_OuterAttribute_]\* (\ @@ -7,39 +10,53 @@ >       | ( [_Visibility_]? ( [_TypeAlias_] | [_ConstantItem_] | [_Function_] ) )\ >    ) +r[items.associated.intro] *Associated Items* are the items declared in [traits] or defined in [implementations]. They are called this because they are defined on an associate -type — the type in the implementation. They are a subset of the kinds of -items you can declare in a module. Specifically, there are [associated -functions] (including methods), [associated types], and [associated constants]. +type — the type in the implementation + +r[items.associated.kinds] +They are a subset of the kinds of items you can declare in a module. +Specifically, there are [associated functions] (including methods), [associated types], and [associated constants]. [associated functions]: #associated-functions-and-methods [associated types]: #associated-types [associated constants]: #associated-constants +r[items.associated.related] Associated items are useful when the associated item logically is related to the associating item. For example, the `is_some` method on `Option` is intrinsically related to Options, so should be associated. +r[items.associated.decl-def] Every associated item kind comes in two varieties: definitions that contain the actual implementation and declarations that declare signatures for definitions. +r[items.associated.trait-items] It is the declarations that make up the contract of traits and what is available on generic types. ## Associated functions and methods +r[items.associated.fn] + +r[items.associated.fn.intro] *Associated functions* are [functions] associated with a type. +r[items.associated.fn.decl] An *associated function declaration* declares a signature for an associated function definition. It is written as a function item, except the function body is replaced with a `;`. -The identifier is the name of the function. The generics, parameter list, -return type, and where clause of the associated function must be the same as the +r[items.associated.name] +The identifier is the name of the function. + +r[items.associated.constraint] +The generics, parameter list, return type, and where clause of the associated function must be the same as the associated function declarations's. +r[items.associated.fn.def] An *associated function definition* defines a function associated with another type. It is written the same as a [function item]. @@ -64,6 +81,7 @@ fn main () { } ``` +r[items.associated.fn.qualified-self] When the associated function is declared on a trait, the function can also be called with a [path] that is a path to the trait appended by the name of the trait. When this happens, it is substituted for `<_ as Trait>::function_name`. @@ -86,10 +104,14 @@ let _: f64 = f64::from_i32(42); ### Methods +r[items.associated.fn.method] + +r[items.associated.fn.method.intro] Associated functions whose first parameter is named `self` are called *methods* and may be invoked using the [method call operator], for example, `x.foo()`, as well as the usual function call notation. +r[items.associated.fn.method.constraint] If the type of the `self` parameter is specified, it is limited to types resolving to one generated by the following grammar (where `'lt` denotes some arbitrary lifetime): @@ -99,6 +121,7 @@ P = &'lt S | &'lt mut S | Box | Rc | Arc | Pin

S = Self | P ``` +r[items.associated.fn.method.self-ty] The `Self` terminal in this grammar denotes a type resolving to the implementing type. This can also include the contextual type alias `Self`, other type aliases, or associated type projections resolving to the implementing type. @@ -127,6 +150,7 @@ impl Example { } ``` +r[associated.fn.method.self-pat-shorthands] Shorthand syntax can be used without specifying a type, which have the following equivalents: @@ -138,6 +162,7 @@ Shorthand | Equivalent > **Note**: Lifetimes can be, and usually are, elided with this shorthand. +r[associated.fn.method.self-pat-mut] If the `self` parameter is prefixed with `mut`, it becomes a mutable variable, similar to regular parameters using a `mut` [identifier pattern]. For example: @@ -189,21 +214,30 @@ let circle_shape = Circle::new(); let bounding_box = circle_shape.bounding_box(); ``` +r[items.associated.fn.params-edition2015] > **Edition differences**: In the 2015 edition, it is possible to declare trait > methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and > an error as of the 2018 edition. All parameters must have an argument name. #### Attributes on method parameters +r[items.associated.fn.param-attributes] + Attributes on method parameters follow the same rules and restrictions as [regular function parameters]. ## Associated Types -*Associated types* are [type aliases] associated with another type. Associated -types cannot be defined in [inherent implementations] nor can they be given a +r[items.associated.type] + +r[items.associated.type.intro] +*Associated types* are [type aliases] associated with another type. + +r[items.associated.type.constraint] +Associated types cannot be defined in [inherent implementations] nor can they be given a default implementation in traits. +r[items.associated.type.decl] An *associated type declaration* declares a signature for associated type definitions. It is written in one of the following forms, where `Assoc` is the name of the associated type, `Params` is a comma-separated list of type, @@ -221,13 +255,21 @@ type Assoc where WhereBounds; type Assoc: Bounds where WhereBounds; ``` -The identifier is the name of the declared type alias. The optional trait bounds -must be fulfilled by the implementations of the type alias. +r[items.associated.type.name] +The identifier is the name of the declared type alias + +r[items.associated.type.constraint-impl] +The optional trait bounds must be fulfilled by the implementations of the type alias. + +r[items.associated.type.sized] There is an implicit [`Sized`] bound on associated types that can be relaxed using the special `?Sized` bound. +r[items.associated.type.def] An *associated type definition* defines a type alias for the implementation -of a trait on a type. They are written similarly to an *associated type declaration*, -but cannot contain `Bounds`, but instead must contain a `Type`: +of a trait on a type + +r[items.associated.type.restriction-def] +They are written similarly to an *associated type declaration*, but cannot contain `Bounds`, but instead must contain a `Type`: ```rust,ignore @@ -237,11 +279,15 @@ type Assoc = Type where WhereBounds; type Assoc where WhereBounds = Type; // deprecated, prefer the form above ``` +r[items.associated.type.alias] If a type `Item` has an associated type `Assoc` from a trait `Trait`, then `::Assoc` is a type that is an alias of the type specified in the -associated type definition. Furthermore, if `Item` is a type parameter, then -`Item::Assoc` can be used in type parameters. +associated type definition + +r[items.associated.type.param] +Furthermore, if `Item` is a type parameter, then `Item::Assoc` can be used in type parameters. +r[items.associated.type.generic] Associated types may include [generic parameters] and [where clauses]; these are often referred to as *generic associated types*, or *GATs*. If the type `Thing` has an associated type `Item` from a trait `Trait` with the generics `<'a>` , the @@ -300,7 +346,6 @@ fn borrow<'a, T: Lend>(array: &'a mut T) -> ::Lender<'a> { array.lend() } - fn main() { let mut array = [0usize; 16]; let lender = borrow(&mut array); @@ -352,11 +397,15 @@ Given a reference to the associated type like `::Output`, the a ### Required where clauses on generic associated types +r[items.associated.type.generic-where-clause] + +r[items.associated.type.generic-where-clause.intro] Generic associated type declarations on traits currently may require a list of where clauses, dependent on functions in the trait and how the GAT is used. These rules may be loosened in the future; updates can be found [on the generic associated types initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/explainer/required_bounds.html). +r[items.associated.type.generic-where-clause.constraint-valid-fn] In a few words, these where clauses are required in order to maximize the allowed definitions of the associated type in impls. To do this, any clauses that *can be proven to hold* on functions (using the parameters of the function or trait) @@ -373,6 +422,7 @@ In the above, on the `next` function, we can prove that `Self: 'a`, because of the implied bounds from `&'a mut self`; therefore, we must write the equivalent bound on the GAT itself: `where Self: 'x`. +r[items.associated.type.generic-where-clause.constraint-intersection] When there are multiple functions in a trait that use the GAT, then the *intersection* of the bounds from the different functions are used, rather than the union. @@ -390,6 +440,7 @@ know that `T: 'a` on `create_checker`, we do not know that on `do_check`. Howeve if `do_check` was commented out, then the `where T: 'x` bound would be required on `Checker`. +r[items.associated.type.generic-where-clause.constraint-forward] The bounds on associated types also propagate required where clauses. ```rust @@ -404,6 +455,7 @@ Here, `where Self: 'a` is required on `Item` because of `iter`. However, `Item` is used in the bounds of `Iterator`, the `where Self: 'a` clause is also required there. +r[items.associated.type.generic-where-clause.static] Finally, any explicit uses of `'static` on GATs in the trait do not count towards the required bounds. @@ -416,18 +468,25 @@ trait StaticReturn { ## Associated Constants +r[items.associated.const] + +r[items.associated.const.intro] *Associated constants* are [constants] associated with a type. +r[items.associated.const.decl] An *associated constant declaration* declares a signature for associated constant definitions. It is written as `const`, then an identifier, then `:`, then a type, finished by a `;`. +r[items.associated.const.name] The identifier is the name of the constant used in the path. The type is the type that the definition has to implement. +r[items.associated.const.def] An *associated constant definition* defines a constant associated with a type. It is written the same as a [constant item]. +r[items.associated.const.eval] Associated constant definitions undergo [constant evaluation] only when referenced. Further, definitions that include [generic parameters] are evaluated after monomorphization. diff --git a/src/items/constant-items.md b/src/items/constant-items.md index f6ba8da73..533345569 100644 --- a/src/items/constant-items.md +++ b/src/items/constant-items.md @@ -1,23 +1,32 @@ # Constant items +r[items.const] + +r[items.const.syntax] > **Syntax**\ > _ConstantItem_ :\ >    `const` ( [IDENTIFIER] | `_` ) `:` [_Type_] ( `=` [_Expression_] )? `;` +r[items.const.intro] A *constant item* is an optionally named _[constant value]_ which is not associated -with a specific memory location in the program. Constants are essentially inlined -wherever they are used, meaning that they are copied directly into the relevant +with a specific memory location in the program. + +r[items.const.behaviour] +Constants are essentially inlined wherever they are used, meaning that they are copied directly into the relevant 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. +r[items.const.namespace] The constant declaration defines the constant value in the [value namespace] of the module or block where it is located. +r[items.const.static] Constants must be explicitly typed. The type must have a `'static` lifetime: any references in the initializer must have `'static` lifetimes. References in the type of a constant default to `'static` lifetime; see [static lifetime elision]. +r[items.const.static-temporary] A reference to a constant will have `'static` lifetime if the constant value is eligible for [promotion]; otherwise, a temporary will be created. @@ -39,10 +48,13 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { }; ``` +r[items.const.restriction] The constant expression may only be omitted in a [trait definition]. ## Constants with Destructors +r[items.const.destructor] + Constants can contain destructors. Destructors are run when the value goes out of scope. @@ -66,6 +78,9 @@ fn create_and_drop_zero_with_destructor() { ## Unnamed constant +r[items.const.unnamed] + +r[items.const.unnamed.intro] Unlike an [associated constant], a [free] constant may be unnamed by using an underscore instead of the name. For example: @@ -76,6 +91,7 @@ const _: () = { struct _SameNameTwice; }; const _: () = { struct _SameNameTwice; }; ``` +r[items.const.unnamed.repetition] As with [underscore imports], macros may safely emit the same unnamed constant in the same scope more than once. For example, the following should not produce an error: @@ -92,6 +108,8 @@ m!(const _: () = ();); ## Evaluation +r[items.const.eval] + [Free][free] constants are always [evaluated][const_eval] at compile-time to surface panics. This happens even within an unused function: diff --git a/src/items/enumerations.md b/src/items/enumerations.md index 63a3e76ba..d2441a1bf 100644 --- a/src/items/enumerations.md +++ b/src/items/enumerations.md @@ -1,5 +1,8 @@ # Enumerations +r[items.enum] + +r[items.enum.sybtax] > **Syntax**\ > _Enumeration_ :\ >    `enum` @@ -25,11 +28,15 @@ > _EnumItemDiscriminant_ :\ >    `=` [_Expression_] +r[items.enum.intro] An *enumeration*, also referred to as an *enum*, is a simultaneous definition of a 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. +r[items.enum.decl] Enumerations are declared with the keyword `enum`. + +r[items.enum.namespace] 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: @@ -44,6 +51,7 @@ let mut a: Animal = Animal::Dog; a = Animal::Cat; ``` +r[items.enum.constructor] Enum constructors can have either named or unnamed fields: ```rust @@ -59,6 +67,7 @@ a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 }; In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply called an enum variant. +r[items.enum.fieldless] An enum where no constructors contain fields are called a *field-less enum*. For example, this is a fieldless enum: @@ -70,6 +79,7 @@ enum Fieldless { } ``` +r[items.enum.unit-only] If a field-less enum only contains unit variants, the enum is called an *unit-only enum*. For example: @@ -81,12 +91,20 @@ enum Enum { } ``` +r[items.enum.constructor-names] Variant constructors are similar to [struct] definitions, and can be referenced by a path from the enumeration name, including in [use declarations]. + +r[items.enum.constructor-namespace] Each variant defines its type in the [type namespace], though that type cannot be used as a type specifier. Tuple-like and unit-like variants also define a constructor in the [value namespace]. +r[items.enum.struct-expr] A struct-like variant can be instantiated with a [struct expression]. + +r[items.enum.tuple-expr] A tuple-like variant can be instantiated with a [call expression] or a [struct expression]. + +r[items.enum.path-expr] A unit-like variant can be instantiated with a [path expression] or a [struct expression]. For example: @@ -108,9 +126,13 @@ let z = StructLike { value: 123 }; // Struct expression. ## Discriminants +r[items.enum.discriminant] + +r[items.enum.discrimnant.intro] Each enum instance has a _discriminant_: an integer logically associated to it that is used to determine which variant it holds. +r[items.enum.discriminant.repr-rust] Under the [default representation], the discriminant is interpreted as an `isize` value. However, the compiler is allowed to use a smaller type (or another means of distinguishing variants) in its actual memory layout. @@ -119,13 +141,16 @@ another means of distinguishing variants) in its actual memory layout. #### Explicit discriminants +r[items.enum.discriminant.explicit] + +r[items.enum.discriminant.explicit.intro] In two circumstances, the discriminant of a variant may be explicitly set by following the variant name with `=` and a [constant expression]: - +r[items.enum.discriminant.explicit.unit-only] 1. if the enumeration is "[unit-only]". - +r[items.enum.discriminan.explicit.primitive-repr] 2. if a [primitive representation] is used. For example: ```rust @@ -142,6 +167,8 @@ following the variant name with `=` and a [constant expression]: #### Implicit discriminants +r[items.enum.discriminant.implicit] + If a discriminant for a variant is not specified, then it is set to one higher than the discriminant of the previous variant in the declaration. If the discriminant of the first variant in the declaration is unspecified, then @@ -160,6 +187,9 @@ assert_eq!(baz_discriminant, 123); #### Restrictions +r[items.enum.discriminant.constraints] + +r[items.enum.discrimnant.constraints.same-discriminant] It is an error when two variants share the same discriminant. ```rust,compile_fail @@ -175,6 +205,7 @@ enum SharedDiscriminantError2 { } ``` +r[items.enum.discrimnant.constraints.above-max-discriminant] It is also an error to have an unspecified discriminant where the previous discriminant is the maximum value for the size of the discriminant. @@ -197,12 +228,17 @@ enum OverflowingDiscriminantError2 { #### Via `mem::discriminant` +r[items.enum.discriminant.access-opaque] + [`std::mem::discriminant`] returns an opaque reference to the discriminant of an enum value which can be compared. This cannot be used to get the value of the discriminant. #### Casting +r[items.enum.discriminant.coercion] + +r[items.enum.discriminant.coercion.intro] If an enumeration is [unit-only] (with no tuple and struct variants), then its discriminant can be directly accessed with a [numeric cast]; e.g.: @@ -218,6 +254,7 @@ assert_eq!(1, Enum::Bar as isize); assert_eq!(2, Enum::Baz as isize); ``` +r[items.enum.discriminant.coercion.constraint] [Field-less enums] can be casted if they do not have explicit discriminants, or where only unit variants are explicit. ```rust @@ -249,6 +286,8 @@ assert_eq!(22, FieldlessWithDiscrimants::Unit as u8); #### Pointer casting +r[items.enum.discriminant.access-memory] + If the enumeration specifies a [primitive representation], then the discriminant may be reliably accessed via unsafe pointer casting: @@ -277,6 +316,9 @@ assert_eq!(2, struct_like.discriminant()); ## Zero-variant enums +r[items.enum.empty] + +r[items.enum.empty.intro] Enums with zero variants are known as *zero-variant enums*. As they have no valid values, they cannot be instantiated. @@ -284,6 +326,7 @@ no valid values, they cannot be instantiated. enum ZeroVariants {} ``` +r[items.enum.empty.uninhabited] Zero-variant enums are equivalent to the [never type], but they cannot be coerced into other types. @@ -295,6 +338,8 @@ let y: u32 = x; // mismatched type error ## Variant visibility +r[items.enum.constraint-variant-visibility] + Enum variants syntactically allow a [_Visibility_] annotation, but this is rejected when the enum is validated. This allows items to be parsed with a unified syntax across different contexts where they are used. diff --git a/src/items/extern-crates.md b/src/items/extern-crates.md index 523e9720d..b0522934e 100644 --- a/src/items/extern-crates.md +++ b/src/items/extern-crates.md @@ -1,5 +1,8 @@ # Extern crate declarations +r[items.extern-crate] + +r[items.extern-crate.syntax] > **Syntax:**\ > _ExternCrate_ :\ >    `extern` `crate` _CrateRef_ _AsClause_? `;` @@ -10,11 +13,19 @@ > _AsClause_ :\ >    `as` ( [IDENTIFIER] | `_` ) +r[items.extern-crate.intro] An _`extern crate` declaration_ specifies a dependency on an external crate. + +r[items.extern-crate.namespace] The external crate is then bound into the declaring scope as the given [identifier] in the [type namespace]. + +r[items.extern-crate.extern-prelude] 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. + +r[items.extern-crate.as] The `as` clause can be used to bind the imported crate to a different name. +r[items.exter-crate.lookup] 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 loading at runtime. The `soname` is resolved at compile time by scanning the @@ -23,6 +34,7 @@ the [`crate_name` attributes] that were declared on the external crate when it w compiled. If no `crate_name` is provided, a default `name` attribute is assumed, equal to the [identifier] given in the `extern crate` declaration. +r[items.extern-crate.self] The `self` crate may be imported which creates a binding to the current crate. In this case the `as` clause must be used to specify the name to bind it to. @@ -37,6 +49,7 @@ extern crate std; // equivalent to: extern crate std as std; extern crate std as ruststd; // linking to 'std' under another name ``` +r[items.extern-crate.name-restrictions] When naming Rust crates, hyphens are disallowed. However, Cargo packages may make use of them. In such case, when `Cargo.toml` doesn't specify a crate name, Cargo will transparently replace `-` with `_` (Refer to [RFC 940] for more @@ -52,16 +65,22 @@ extern crate hello_world; // hyphen replaced with an underscore ## Underscore Imports +r[items.extern-crate.underscore] + +r[items.extern-crate.underscore.intro] An external crate dependency can be declared without binding its name in scope by using an underscore with the form `extern crate foo as _`. This may be useful for crates that only need to be linked, but are never referenced, and will avoid being reported as unused. +r[items.extern-crate.underscore.macro_use] The [`macro_use` attribute] works as usual and imports the macro names into the [`macro_use` prelude]. ## The `no_link` attribute +r[items.extern-crate.no_link] + The *`no_link` attribute* may be specified on an `extern crate` item to prevent linking the crate into the output. This is commonly used to load a crate to access only its macros. diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 21feb0eaf..6cb49f03b 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -1,5 +1,8 @@ # External blocks +r[items.extern] + +r[items.extern.syntax] > **Syntax**\ > _ExternBlock_ :\ >    `unsafe`? `extern` [_Abi_]? `{`\ @@ -13,32 +16,45 @@ >       | ( [_Visibility_]? ( [_StaticItem_] | [_Function_] ) )\ >    ) +r[items.extern.intro] External blocks provide _declarations_ of items that are not _defined_ in the current crate and are the basis of Rust's foreign function interface. These are akin to unchecked imports. +r[items.extern.restriction] 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. +[statics]. + +r[items.extern.fn-safety] +Calling functions or accessing statics that are declared in external blocks is only allowed in an `unsafe` context. +r[items.extern.namespace] The external block defines its functions and statics in the [value namespace] of the module or block where it is located. ## Functions +r[items.extern.fn] + +r[items.extern.fn.body] Functions within external blocks are declared in the same way as other Rust functions, with the exception that they must not have a body and are instead -terminated by a semicolon. Patterns are not allowed in parameters, only -[IDENTIFIER] or `_` may be used. The `safe` and `unsafe` function qualifiers are +terminated by a semicolon + +r[items.extern.fn.restriction] +Patterns are not allowed in parameters, only [IDENTIFIER] or `_` may be used. The `safe` and `unsafe` function qualifiers are allowed, but other function qualifiers (e.g. `const`, `async`, `extern`) are not. +r[items.extern.fn.foreign-abi] Functions within external blocks may be called by Rust code, just like functions defined in Rust. The Rust compiler automatically translates between the Rust ABI and the foreign ABI. +r[items.extern.fn.safety] A function declared in an extern block is implicitly `unsafe` unless the `safe` function qualifier is present. +r[items.extern.fn.fn-ptr] When coerced to a function pointer, a function declared in an extern block has type `extern "abi" for<'l1, ..., 'lm> fn(A1, ..., An) -> R`, where `'l1`, ... `'lm` are its lifetime parameters, `A1`, ..., `An` are the declared types of @@ -46,14 +62,22 @@ its parameters, `R` is the declared return type. ## Statics +r[items.extern.static] + +r[items.extern.static.intro] Statics within external blocks are declared in the same way as [statics] outside of external blocks, except that they do not have an expression initializing their value. + +r[items.extern.static.safety] Unless a static item declared in an extern block is qualified as `safe`, it is `unsafe` to access that item, whether or not it's mutable, because there is nothing guaranteeing that the bit pattern at the static's memory is valid for the type it is declared with, since some arbitrary (e.g. C) code is in charge of initializing the static. +r[items.extern.static.mut] Extern statics can be either immutable or mutable just like [statics] outside of external blocks. + +r[items.extern.static.read-only] An immutable static *must* be initialized before any Rust code is executed. It is not enough for the static to be initialized before Rust code reads from it. Once Rust code runs, mutating an immutable static (from inside or outside Rust) is UB, @@ -61,6 +85,9 @@ except if the mutation happens to bytes inside of an `UnsafeCell`. ## ABI +r[items.extern.abi] + +r[items.extern.abi.intro] By default external blocks assume that the library they are calling uses the standard C ABI on the specific platform. Other ABIs may be specified using an `abi` string, as shown here: @@ -71,34 +98,60 @@ standard C ABI on the specific platform. Other ABIs may be specified using an unsafe extern "stdcall" { } ``` +r[items.extern.abi.standard] There are three ABI strings which are cross-platform, and which all compilers are guaranteed to support: +r[items.extern.abi.rust] * `unsafe extern "Rust"` -- The default ABI when you write a normal `fn foo()` in any Rust code. + +r[items.extern.abi.c] * `unsafe extern "C"` -- This is the same as `extern fn foo()`; whatever the default your C compiler supports. + +r[items.extern.abi.system] * `unsafe extern "system"` -- Usually the same as `extern "C"`, except on Win32, in which case it's `"stdcall"`, or what you should use to link to the Windows API itself +r[items.extern.abi.platform] There are also some platform-specific ABI strings: +r[items.extern.abi.cdecl] * `unsafe extern "cdecl"` -- The default for x86\_32 C code. + +r[items.extern.abi.stdcall] * `unsafe extern "stdcall"` -- The default for the Win32 API on x86\_32. + +r[items.extern.abi.win64] * `unsafe extern "win64"` -- The default for C code on x86\_64 Windows. + +r[items.extern.abi.sysv64] * `unsafe extern "sysv64"` -- The default for C code on non-Windows x86\_64. + +r[items.extern.abi.aapcs] * `unsafe extern "aapcs"` -- The default for ARM. + +r[items.extern.abi.fastcall] * `unsafe extern "fastcall"` -- The `fastcall` ABI -- corresponds to MSVC's `__fastcall` and GCC and clang's `__attribute__((fastcall))` + +r[items.extern.abi.vectorcall] * `unsafe extern "vectorcall"` -- The `vectorcall` ABI -- corresponds to MSVC's `__vectorcall` and clang's `__attribute__((vectorcall))` + +r[items.extern.abi.thiscall] * `unsafe extern "thiscall"` -- The default for C++ member functions on MSVC -- corresponds to MSVC's `__thiscall` and GCC and clang's `__attribute__((thiscall))` + +r[items.extern.abi.efiapi] * `unsafe extern "efiapi"` -- The ABI used for [UEFI] functions. ## Variadic functions +r[items.extern.variadic] + Functions within external blocks may be variadic by specifying `...` as the last argument. The variadic parameter may optionally be specified with an identifier. @@ -113,36 +166,58 @@ unsafe extern "C" { ## Attributes on extern blocks +r[items.extern.attributes] + +r[items.extern.attributes.intro] The following [attributes] control the behavior of external blocks. ### The `link` attribute +r[items.extern.attributes.link] + +r[items.extern.attributes.link.intro] The *`link` attribute* specifies the name of a native library that the -compiler should link with for the items within an `extern` block. It uses the -[_MetaListNameValueStr_] syntax to specify its inputs. The `name` key is the +compiler should link with for the items within an `extern` block. + +r[items.extern.attributes.link.syntax] +It uses the [_MetaListNameValueStr_] syntax to specify its inputs. The `name` key is the name of the native library to link. The `kind` key is an optional value which specifies the kind of library with the following possible values: +r[items.extern.attributes.link.dylib] - `dylib` --- Indicates a dynamic library. This is the default if `kind` is not specified. + +r[items.extern.attributes.link.static] - `static` --- Indicates a static library. + +r[items.extern.attributes.link.framework] - `framework` --- Indicates a macOS framework. This is only valid for macOS targets. + +r[items.extern.attributes.link.raw-dylib] - `raw-dylib` --- Indicates a dynamic library where the compiler will generate an import library to link against (see [`dylib` versus `raw-dylib`] below for details). This is only valid for Windows targets. +r[items.extern.attributes.link.constraint] The `name` key must be included if `kind` is specified. +r[items.extern.attributes.link.modifiers] The optional `modifiers` argument is a way to specify linking modifiers for the library to link. + +r[items.extern.attributes.link.modifiers-syntax] Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. + +r[items.extern.attributes.link.modifiers-constraint] Specifying multiple `modifiers` arguments in a single `link` attribute, or multiple identical modifiers in the same `modifiers` argument is not currently supported. \ Example: `#[link(name = "mylib", kind = "static", modifiers = "+whole-archive")]`. +r[items.extern.attributes.link.wasm_import_module] The `wasm_import_module` key may be used to specify the [WebAssembly module] name for the items within an `extern` block when importing symbols from the host environment. The default module name is `env` if `wasm_import_module` is @@ -166,6 +241,7 @@ unsafe extern { } ``` +r[items.extern.attributes.link.empty-block] It is valid to add the `link` attribute on an empty extern block. You can use this to satisfy the linking requirements of extern blocks elsewhere in your code (including upstream crates) instead of adding the attribute to each extern @@ -173,13 +249,18 @@ block. #### Linking modifiers: `bundle` +r[items.extern.attributes.link.modifier-bundle] + +r[items.extern.attributes.link.modifier-bundle.constraint] This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. +r[items.extern.attributes.link.modifier-bundle.behaviour] When building a rlib or staticlib `+bundle` means that the native static library will be packed into the rlib or staticlib archive, and then retrieved from there during linking of the final binary. +r[items.extern.attributes.link.modifier-bundle.behaviour-negative] When building a rlib `-bundle` means that the native static library is registered as a dependency of that rlib "by name", and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. \ @@ -187,8 +268,10 @@ When building a staticlib `-bundle` means that the native static library is simp into the archive and some higher level build system will need to add it later during linking of the final binary. +r[items.extern.attributes.link.modifier-bundle.no-effect] This modifier has no effect when building other targets like executables or dynamic libraries. +r[items.extern.attributes.link.modifier-bundle.default] The default for this modifier is `+bundle`. More implementation details about this modifier can be found in @@ -196,12 +279,17 @@ More implementation details about this modifier can be found in #### Linking modifiers: `whole-archive` +r[items.extern.attributes.link.modifier-whole-archive] + +r[items.extern.attributes.link.modifier-whole-archive.constraint] This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. +r[items.extern.attributes.link.modifier-whole-archive.behaviour] `+whole-archive` means that the static library is linked as a whole archive without throwing any object files away. +r[items.extern.attributes.link.modifier-whole-archive.default] The default for this modifier is `-whole-archive`. More implementation details about this modifier can be found in @@ -209,15 +297,21 @@ More implementation details about this modifier can be found in ### Linking modifiers: `verbatim` +r[items.extern.attributes.link.modifier-verbatim] + +r[items.extern.attributes.link.modifier-verbatim.constraint] This modifier is compatible with all linking kinds. +r[items.extern.attributes.link.modifier-verbatim.behaviour] `+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker. +r[items.extern.attributes.link.modifier-verbatim.behaviour-negative] `-verbatim` means that rustc will either add a target-specific prefix and suffix to the library name before passing it to linker, or won't prevent linker from implicitly adding it. +r[items.extern.attributes.link.modifier-verbatim.default] The default for this modifier is `-verbatim`. More implementation details about this modifier can be found in @@ -225,22 +319,30 @@ More implementation details about this modifier can be found in #### `dylib` versus `raw-dylib` +r[items.extern.attributes.link.kind-raw-dylib] + +r[items.extern.attributes.link.kind-raw-dylib.intro] On Windows, linking against a dynamic library requires that an import library is provided to the linker: this is a special static library that declares all of the symbols exported by the dynamic library in such a way that the linker knows that they have to be dynamically loaded at runtime. +r[items.extern.attributes.link.kind-raw-dylib.import] Specifying `kind = "dylib"` instructs the Rust compiler to link an import library based on the `name` key. The linker will then use its normal library resolution logic to find that import library. Alternatively, specifying `kind = "raw-dylib"` instructs the compiler to generate an import library during compilation and provide that to the linker instead. +r[items.extern.attributes.link.kind-raw-dylib.platform-specific] `raw-dylib` is only supported on Windows. Using it when targeting other platforms will result in a compiler error. #### The `import_name_type` key +r[items.extern.attributes.link.import_name_type] + +r[items.extern.attributes.link.import_name_type.intro] On x86 Windows, names of functions are "decorated" (i.e., have a specific prefix and/or suffix added) to indicate their calling convention. For example, a `stdcall` calling convention function with the name `fn1` that has no arguments @@ -250,6 +352,7 @@ use different decorations for the same calling conventions which means, by default, some Win32 functions cannot be called using the `raw-dylib` link kind via the GNU toolchain. +r[items.extern.attributes.link.import_name_type.values] To allow for these differences, when using the `raw-dylib` link kind you may also specify the `import_name_type` key with one of the following values to change how functions are named in the generated import library: @@ -260,20 +363,28 @@ change how functions are named in the generated import library: format, but skipping the leading `?`, `@`, or optionally `_`. * `undecorated`: The function name will not be decorated. +r[items.extern.attributes.link.import_name_type.default] If the `import_name_type` key is not specified, then the function name will be fully-decorated using the target toolchain's format. +r[items.extern.attributes.link.import_name_type.variables] Variables are never decorated and so the `import_name_type` key has no effect on how they are named in the generated import library. +r[items.extern.attributes.link.import_name_type.platform-specific] The `import_name_type` key is only supported on x86 Windows. Using it when targeting other platforms will result in a compiler error. ### The `link_name` attribute +r[items.extern.attributes.link_name] + +r[items.extern.attributes.link_name.intro] The *`link_name` attribute* may be specified on declarations inside an `extern` -block to indicate the symbol to import for the given function or static. It -uses the [_MetaNameValueStr_] syntax to specify the name of the symbol. +block to indicate the symbol to import for the given function or static. + +r[items.extern.attributes.link_name.syntax] +It uses the [_MetaNameValueStr_] syntax to specify the name of the symbol. ```rust unsafe extern { @@ -282,11 +393,15 @@ unsafe extern { } ``` +r[items.extern.attributes.link_name.exclusive] Using this attribute with the `link_ordinal` attribute will result in a compiler error. ### The `link_ordinal` attribute +r[items.extern.attributes.link_ordinal] + +r[items.extern.attributes.link_ordinal.intro] The *`link_ordinal` attribute* can be applied on declarations inside an `extern` block to indicate the numeric ordinal to use when generating the import library to link against. An ordinal is a unique number per symbol exported by a dynamic @@ -305,14 +420,18 @@ unsafe extern "stdcall" { } ``` +r[items.extern.attributes.link_ordinal.constraints] This attribute is only used with the `raw-dylib` linking kind. Using any other kind will result in a compiler error. +r[items.extern.attributes.link_ordinal.exclusive] Using this attribute with the `link_name` attribute will result in a compiler error. ### Attributes on function parameters +r[items.extern.attributes.fn-parameters] + Attributes on extern function parameters follow the same rules and restrictions as [regular function parameters]. diff --git a/src/items/functions.md b/src/items/functions.md index d3f2c4548..4235269be 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -1,5 +1,8 @@ # Functions +r[items.fn] + +r[items.fn.syntax] > **Syntax**\ > _Function_ :\ >    _FunctionQualifiers_ `fn` [IDENTIFIER] [_GenericParams_]?\ @@ -48,13 +51,21 @@ > [^fn-param-2015]: Function parameters with only a type are only allowed > in an associated function of a [trait item] in the 2015 edition. +r[items.fn.intro] 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. + +r[items.fn.namespace] 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. + +r[items.fn.signature] 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. + +r[items.fn.implicit-return] If the output type is not explicitly stated, it is the [unit type]. +r[items.fn.fn-item-type] When referred to, a _function_ yields a first-class *value* of the corresponding zero-sized [*function item type*], which when called evaluates to a direct call to the function. For example, this is a simple function: @@ -64,10 +75,14 @@ fn answer_to_life_the_universe_and_everything() -> i32 { } ``` +r[items.fn.constraint-safety-qualifiers] The `safe` function is semantically only allowed when used in an [`extern` block]. ## Function parameters +r[items.fn.params] + +r[items.fn.params.intro] Function parameters are irrefutable [patterns], so any pattern that is valid in an else-less `let` binding is also valid as a parameter: @@ -75,16 +90,24 @@ an else-less `let` binding is also valid as a parameter: fn first((value, _): (i32, i32)) -> i32 { value } ``` +r[items.fn.params.self-pat] If the first parameter is a _SelfParam_, this indicates that the function is a -[method]. Functions with a self parameter may only appear as an [associated +[method]. + +r[items.fn.params.self-constraint] +Functions with a self parameter may only appear as an [associated function] in a [trait] or [implementation]. +r[items.fn.params.varargs] A parameter with the `...` token indicates a [variadic function], and may only be used as the last parameter of an [external block] function. The variadic parameter may have an optional identifier, such as `args: ...`. ## Function body +r[items.fn.body] + +r[items.fn.body.intro] The body block of a function is conceptually wrapped in another block that first binds the argument patterns and then `return`s the value of the function's body. This means that the tail expression of the block, if evaluated, ends up being @@ -102,11 +125,15 @@ return { }; ``` +r[items.fn.body.restriction] Functions without a body block are terminated with a semicolon. This form may only appear in a [trait] or [external block]. ## Generic functions +r[items.fn.generics] + +r[items.fn.generics.intro] A _generic function_ allows one or more _parameterized types_ to appear in its signature. Each type parameter must be explicitly declared in an angle-bracket-enclosed and comma-separated list, following the function name. @@ -118,8 +145,12 @@ fn foo(x: A, y: B) { # } ``` +r[items.fn.generics.param-names] Inside the function signature and body, the name of the type parameter can be -used as a type name. [Trait] bounds can be specified for type +used as a type name. + +r[items.fn.generics.param-bounds] +[Trait] bounds can be specified for type parameters to allow methods with that trait to be called on values of that type. This is specified using the `where` syntax: @@ -129,6 +160,7 @@ fn foo(x: T) where T: Debug { # } ``` +r[items.fn.generics.mono] When a generic function is referenced, its type is instantiated based on the context of the reference. For example, calling the `foo` function here: @@ -144,6 +176,7 @@ foo(&[1, 2]); will instantiate type parameter `T` with `i32`. +r[items.fn.generics.explicit-arguments] The type parameters can also be explicitly supplied in a trailing [path] component after the function name. This might be necessary if there is not sufficient context to determine the type parameters. For example, @@ -151,6 +184,9 @@ sufficient context to determine the type parameters. For example, ## Extern function qualifier +r[items.fn.extern] + +r[items.fn.extern.intro] The `extern` function qualifier allows providing function _definitions_ that can be called with a particular ABI: @@ -159,6 +195,7 @@ be called with a particular ABI: extern "ABI" fn foo() { /* ... */ } ``` +r[items.fn.extern.def] These are often used in combination with [external block] items which provide function _declarations_ that can be used to call functions without providing their _definition_: @@ -173,6 +210,7 @@ unsafe { foo() }; bar(); ``` +r[items.fn.extern.default-abi] When `"extern" Abi?*` is omitted from `FunctionQualifiers` in function items, the ABI `"Rust"` is assigned. For example: @@ -186,6 +224,7 @@ is equivalent to: extern "Rust" fn foo() {} ``` +r[items.fn.extern.foreign-call] Functions can be called by foreign code, and using an ABI that differs from Rust allows, for example, to provide functions that can be called from other programming languages like C: @@ -199,6 +238,7 @@ extern "C" fn new_i32() -> i32 { 0 } extern "stdcall" fn new_i32_stdcall() -> i32 { 0 } ``` +r[items.fn.extern.default-extern] Just as with [external block], when the `extern` keyword is used and the `"ABI"` is omitted, the ABI used defaults to `"C"`. That is, this: @@ -214,6 +254,7 @@ extern "C" fn new_i32() -> i32 { 0 } let fptr: extern "C" fn() -> i32 = new_i32; ``` +r[items.fn.extern.unwind] Functions with an ABI that differs from `"Rust"` do not support unwinding in the exact same way that Rust does. Therefore, unwinding past the end of functions with such ABIs causes the process to abort. @@ -223,16 +264,24 @@ aborts the process by executing an illegal instruction. ## Const functions +r[items.fn.const] + +r[item.fn.const.intro] Functions qualified with the `const` keyword are [const functions], as are [tuple struct] and [tuple variant] constructors. _Const functions_ can be called from within [const contexts]. +r[item.fn.const.extern] Const functions may use the [`extern`] function qualifier. +r[items.fn.const.exclusivity] Const functions are not allowed to be [async](#async-functions). ## Async functions +r[items.fn.async] + +r[items.fn.async.intro] Functions may be qualified as async, and this can also be combined with the `unsafe` qualifier: @@ -241,10 +290,12 @@ async fn regular_example() { } async unsafe fn unsafe_example() { } ``` +r[items.fn.async.future] Async functions do no work when called: instead, they capture their arguments into a future. When polled, that future will execute the function's body. +r[items.fn.async.desugar-brief] An async function is roughly equivalent to a function that returns [`impl Future`] and with an [`async move` block][async-blocks] as its body: @@ -266,12 +317,16 @@ fn example<'a>(x: &'a str) -> impl Future + 'a { } ``` +r[items.fn.async.desugar] The actual desugaring is more complex: +r[items.fn.async.lifetime-catpure] - The return type in the desugaring is assumed to capture all lifetime parameters from the `async fn` declaration. This can be seen in the desugared example above, which explicitly outlives, and hence captures, `'a`. + +r[items.fn.async.param-capture] - The [`async move` block][async-blocks] in the body captures all function parameters, including those that are unused or bound to a `_` pattern. This ensures that function parameters are dropped in the @@ -284,11 +339,15 @@ For more information on the effect of async, see [`async` blocks][async-blocks]. [async-blocks]: ../expressions/block-expr.md#async-blocks [`impl Future`]: ../types/impl-trait.md +r[items.fn.async.edition2018] > **Edition differences**: Async functions are only available beginning with > Rust 2018. ### Combining `async` and `unsafe` +r[items.fn.async.safety] + +r[items.fn.async.safety.intro] It is legal to declare a function that is both async and unsafe. The resulting function is unsafe to call and (like any async function) returns a future. This future is just an ordinary future and thus an @@ -314,6 +373,7 @@ async fn safe_example() { } ``` +r[items.fn.async.safety.] Note that this behavior is a consequence of the desugaring to a function that returns an `impl Future` -- in this case, the function we desugar to is an `unsafe` function, but the return value remains @@ -331,6 +391,9 @@ responsibility to ensure that. ## Attributes on functions +r[items.fn.attributes] + +r[items.fn.attributes.intro] [Outer attributes][attributes] are allowed on functions. [Inner attributes][attributes] are allowed directly after the `{` inside its body [block]. @@ -346,6 +409,7 @@ fn documented() { > Note: Except for lints, it is idiomatic to only use outer attributes on > function items. +r[items.fn.attributes.builtin-attributes] The attributes that have meaning on a function are [`cfg`], [`cfg_attr`], [`deprecated`], [`doc`], [`export_name`], [`link_section`], [`no_mangle`], [the lint check attributes], [`must_use`], [the procedural macro attributes], [the testing @@ -354,6 +418,9 @@ attributes macros. ## Attributes on function parameters +r[items.fn.param-attributes] + +r[items.fn.param-attributes.intro] [Outer attributes][attributes] are allowed on function parameters and the permitted [built-in attributes] are restricted to `cfg`, `cfg_attr`, `allow`, `warn`, `deny`, and `forbid`. @@ -367,6 +434,7 @@ fn len( } ``` +r[items.fn.param-attributes.parsed-attributes] Inert helper attributes used by procedural macro attributes applied to items are also allowed but be careful to not include these inert attributes in your final `TokenStream`. diff --git a/src/items/generics.md b/src/items/generics.md index 9b756594b..498de7424 100644 --- a/src/items/generics.md +++ b/src/items/generics.md @@ -1,5 +1,8 @@ # Generic parameters +r[items.generics] + +r[items.generics.syntax] > **Syntax**\ > _GenericParams_ :\ >       `<` `>`\ @@ -17,12 +20,17 @@ > _ConstParam_:\ >    `const` [IDENTIFIER] `:` [_Type_] ( `=` _[Block][block]_ | [IDENTIFIER] | -?[LITERAL] )? +r[items.generics.syntax.intro] [Functions], [type aliases], [structs], [enumerations], [unions], [traits], and [implementations] may be *parameterized* by types, constants, and lifetimes. These parameters are listed in angle brackets (`<...>`), usually immediately after the name of the item and before its definition. For implementations, which don't have a name, they come directly after `impl`. + +r[items.generics.syntax.decl-order] The order of generic parameters is restricted to lifetime parameters and then type and const parameters intermixed. + +r[items.generics.syntax.constraint] The same parameter name may not be declared more than once in a _GenericParams_ list. Some examples of items with type, const, and lifetime parameters: @@ -35,25 +43,35 @@ struct InnerArray([T; N]); struct EitherOrderWorks(U); ``` +r[items.generics.syntax.scope] Generic parameters are in scope within the item definition where they are declared. They are not in scope for items declared within the body of a function as described in [item declarations]. See [generic parameter scopes] for more details. +r[items.generics.builtin-generic-types] [References], [raw pointers], [arrays], [slices], [tuples], and [function pointers] have lifetime or type parameters as well, but are not referred to with path syntax. +r[items.generics.constraint-widlcard-lifetime] `'_` is not a valid lifetime parameter. ### Const generics +r[items.generics.const] + +r[items.generics.const.intro] *Const generic parameters* allow items to be generic over constant values. + +r[items.generics.const.namespace] 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. +r[items.generics.const.constraint] The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`. +r[items.generics.const.usage] Const parameters can be used anywhere a [const item] can be used, with the exception that when used in a [type] or [array repeat expression], it must be standalone (as described below). That is, they are allowed in the following @@ -111,6 +129,7 @@ fn foo() { } ``` +r[items.generics.const.constraint-const-expr] As a further restriction, const parameters may only appear as a standalone argument inside of a [type] or [array repeat expression]. In those contexts, they may only be used as a single segment [path expression], possibly inside a @@ -128,7 +147,10 @@ fn bad_function() -> [u8; {N + 1}] { } ``` +r[items.generics.const.argument] A const argument in a [path] specifies the const value to use for that item. + +r[items.generics.const.argument-restriction] The argument must be a [const expression] of the type ascribed to the const parameter. The const expression must be a [block expression][block] (surrounded with braces) unless it is a single path segment (an [IDENTIFIER]) @@ -154,6 +176,7 @@ fn example() { } ``` +r[items.generics.const.type-ambiguity] When there is ambiguity if a generic argument could be resolved as either a type or const argument, it is always resolved as a type. Placing the argument in a block expression can force it to be interpreted as a const argument. @@ -172,6 +195,7 @@ fn foo() -> Foo { todo!() } // ERROR fn bar() -> Foo<{ N }> { todo!() } // ok ``` +r[items.generics.const.variance] Unlike type and lifetime parameters, const parameters can be declared without being used inside of a parameterized item, with the exception of implementations as described in [generic implementations]: @@ -188,6 +212,7 @@ struct Unconstrained; impl Unconstrained {} ``` +r[items.generics.const.exhaustiveness] When resolving a trait bound obligation, the exhaustiveness of all implementations of const parameters is not considered when determining if the bound is satisfied. For example, in the following, even though all possible @@ -207,9 +232,11 @@ fn generic() { } ``` - ## Where clauses +r[items.generics.where] + +r[items.generics.where.syntax] > **Syntax**\ > _WhereClause_ :\ >    `where` ( _WhereClauseItem_ `,` )\* _WhereClauseItem_ ? @@ -224,10 +251,12 @@ fn generic() { > _TypeBoundWhereClauseItem_ :\ >    [_ForLifetimes_]? [_Type_] `:` [_TypeParamBounds_]? +r[items.generics.where.intro] *Where clauses* provide another way to specify bounds on type and lifetime parameters as well as a way to specify bounds on types that aren't type parameters. +r[items.generics.where.higher-ranked-;ifetimes] The `for` keyword can be used to introduce [higher-ranked lifetimes]. It only allows [_LifetimeParam_] parameters. @@ -245,6 +274,8 @@ where ## Attributes +r[items.generics.attributes] + Generic lifetime and type parameters allow [attributes] on them. There are no built-in attributes that do anything in this position, although custom derive attributes may give meaning to it. diff --git a/src/items/implementations.md b/src/items/implementations.md index 37965569e..6f631f3c2 100644 --- a/src/items/implementations.md +++ b/src/items/implementations.md @@ -1,5 +1,8 @@ # Implementations +r[items.impl] + +r[items.impl.syntax] > **Syntax**\ > _Implementation_ :\ >    _InherentImpl_ | _TraitImpl_ @@ -19,11 +22,13 @@ >       [_AssociatedItem_]\*\ >    `}` +r[items.impl.intro] An _implementation_ is an item that associates items with an _implementing type_. Implementations are defined with the keyword `impl` and contain functions that belong to an instance of the type that is being implemented or to the type statically. +r[items.impl.kinds] There are two types of implementations: - inherent implementations @@ -31,22 +36,33 @@ There are two types of implementations: ## Inherent Implementations +r[items.impl.inherent] + +r[items.impl.inherent.intro] An inherent implementation is defined as the sequence of the `impl` keyword, generic type declarations, a path to a nominal type, a where clause, and a bracketed set of associable items. +r[items.impl.inherent.implementing-type] The nominal type is called the _implementing type_ and the associable items are the _associated items_ to the implementing type. +r[items.impl.inherent.associated-items] Inherent implementations associate the contained items to the -implementing type. Inherent implementations can contain [associated -functions] (including [methods]) and [associated constants]. They cannot -contain associated type aliases. +implementing type. + +r[items.impl.inherent.values] +Inherent implementations can contain [associated functions] (including [methods]) and [associated constants]. +r[items.impl.inherent.constraint-type-alias] +They cannot contain associated type aliases. + +r[items.impl.inherent.associated-item-path] The [path] to an associated item is any path to the implementing type, followed by the associated item's identifier as the final path component. +r[items.impl.inherent.coherence] A type can also have multiple inherent implementations. An implementing type must be defined within the same crate as the original type definition. @@ -86,23 +102,30 @@ fn main() { ## Trait Implementations +r[items.impl.trait] + +r[items.impl.trait.intro] A _trait implementation_ is defined like an inherent implementation except that the optional generic type declarations are followed by a [trait], followed by the keyword `for`, followed by a path to a nominal type. +r[items.impl.trait.implemented-trait] The trait is known as the _implemented trait_. The implementing type implements the implemented trait. +r[items.impl.trait.constraint] A trait implementation must define all non-default associated items declared by the implemented trait, may redefine default associated items defined by the implemented trait, and cannot define any other items. +r[items.impl.trait.associated-item-path] The path to the associated items is `<` followed by a path to the implementing type followed by `as` followed by a path to the trait followed by `>` as a path component followed by the associated item's path component. +r[items.impl.trait.safety] [Unsafe traits] require the trait implementation to begin with the `unsafe` keyword. @@ -140,9 +163,13 @@ impl Shape for Circle { ### Trait Implementation Coherence +r[items.impl.trait.coherence] + +r[items.impl.trait.coherence.intro] A trait implementation is considered incoherent if either the orphan rules check fails or there are overlapping implementation instances. +r[items.impl.trait.coherence.overlapping] Two trait implementations overlap when there is a non-empty intersection of the traits the implementation is for, the implementations can be instantiated with the same type. #### Orphan rules +r[items.impl.trait.orphan-rule] + +r[items.impl.trait.orphan-rule.general] Given `impl Trait for T0`, an `impl` is valid only if at least one of the following is true: @@ -160,14 +190,19 @@ least one of the following is true: - No [uncovered type] parameters `P1..=Pn` may appear in `T0..Ti` (excluding `Ti`) +r[items.impl.trait.uncovered-param] Only the appearance of *uncovered* type parameters is restricted. + +r[items.impl.trait.fundamental] Note that for the purposes of coherence, [fundamental types] are special. The `T` in `Box` is not considered covered, and `Box` is considered local. - ## Generic Implementations +r[items.impl.generics] + +r[items.impl.generics.intro] An implementation can take [generic parameters], which can be used in the rest of the implementation. Implementation parameters are written directly after the `impl` keyword. @@ -182,6 +217,7 @@ impl Seq for u32 { } ``` +r[items.impl.generics.usage] Generic parameters *constrain* an implementation if the parameter appears at least once in one of: @@ -190,6 +226,7 @@ least once in one of: * As an [associated type] in the [bounds] of a type that contains another parameter that constrains the implementation +r[items.impl.generics.constraint] Type and const parameters must always constrain the implementation. Lifetimes must constrain the implementation if the lifetime is used in an associated type. @@ -263,6 +300,8 @@ impl<'a> HasAssocType for Struct { ## Attributes on Implementations +r[items.impl.attributes] + Implementations may contain outer [attributes] before the `impl` keyword and inner [attributes] inside the brackets that contain the associated items. Inner attributes must come before any associated items. The attributes that have diff --git a/src/items/modules.md b/src/items/modules.md index e709f52fd..8617e15ea 100644 --- a/src/items/modules.md +++ b/src/items/modules.md @@ -1,5 +1,8 @@ # Modules +r[items.mod] + +r[items.mod.syntax] > **Syntax:**\ > _Module_ :\ >       `unsafe`? `mod` [IDENTIFIER] `;`\ @@ -8,11 +11,16 @@ >         [_Item_]\*\ >       `}` +r[items.mod.intro] A module is a container for zero or more [items]. +r[items.mod.def] A _module item_ is a module, surrounded in braces, named, and prefixed with the keyword `mod`. A module item introduces a new, named module into the tree of -modules making up a crate. Modules can nest arbitrarily. +modules making up a crate. + +r[items.mod.nesting] +Modules can nest arbitrarily. An example of a module: @@ -34,10 +42,14 @@ mod math { } ``` +r[items.mod.namespace] Modules are defined in the [type namespace] of the module or block where they are located. + +r[items.mod.namespace-def] 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. +r[items.mod.constraint] 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 the syntax and make use of the `unsafe` keyword, before removing it from the @@ -45,9 +57,15 @@ token stream. ## Module Source Filenames +r[items.mod.outlined] + +r[items.mod.outlined.intro] A module without a body is loaded from an external file. When the module does not have a `path` attribute, the path to the file mirrors the logical [module -path]. Ancestor module path components are directories, and the module's +path]. + +r[items.mod.outlined.search] +Ancestor module path components are directories, and the module's contents are in a file with the name of the module plus the `.rs` extension. For example, the following module structure can have this corresponding filesystem structure: @@ -58,6 +76,7 @@ Module Path | Filesystem Path | File Contents `crate::util` | `util.rs` | `mod config;` `crate::util::config` | `util/config.rs` | +r[items.mod.outlined.search-mod] Module filenames may also be the name of the module as a directory with the contents in a file named `mod.rs` within that directory. The above example can alternately be expressed with `crate::util`'s contents in a file named @@ -70,9 +89,13 @@ alternately be expressed with `crate::util`'s contents in a file named ### The `path` attribute +r[items.mod.outlined.path] + +r[items.mod.outlined.path.intro] The directories and files used for loading external file modules can be influenced with the `path` attribute. +r[items.mod.outlined.path.search] For `path` attributes on modules not inside inline module blocks, the file path is relative to the directory the source file is located. For example, the following code snippet would use the paths shown based on where it is located: @@ -88,6 +111,7 @@ Source File | `c`'s File Location | `c`'s Module Path `src/a/b.rs` | `src/a/foo.rs` | `crate::a::b::c` `src/a/mod.rs` | `src/a/foo.rs` | `crate::a::c` +r[items.mod.outlined.path.search-nested] For `path` attributes inside inline module blocks, the relative location of the file path depends on the kind of source file the `path` attribute is located in. "mod-rs" source files are root modules (such as `lib.rs` or @@ -128,10 +152,14 @@ mod thread { ## Attributes on Modules +r[items.mod.attributes] + +r[items.mod.attributes.intro] Modules, like all items, accept outer attributes. They also accept inner attributes: either after `{` for a module with a body, or at the beginning of the source file, after the optional BOM and shebang. +r[items.mod.attributes.supported] 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. diff --git a/src/items/static-items.md b/src/items/static-items.md index f688a9024..55890712e 100644 --- a/src/items/static-items.md +++ b/src/items/static-items.md @@ -1,5 +1,8 @@ # Static items +r[items.static] + +r[items.static.syntax] > **Syntax**\ > _StaticItem_ :\ >    [_ItemSafety_]?[^extern-safety] `static` `mut`? [IDENTIFIER] `:` [_Type_] @@ -8,33 +11,48 @@ > [^extern-safety]: The `safe` and `unsafe` function qualifiers are only > allowed semantically within `extern` blocks. +r[items.static.intro] A *static item* is similar to a [constant], except that it represents a precise memory location in the program. All references to the static refer to the same -memory location. Static items have the `static` lifetime, which outlives all +memory location. + +r[items.static.lifetime] +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. +r[items.static.namespace] The static declaration defines a static value in the [value namespace] of the module or block where it is located. +r[items.static.init] The static initializer is a [constant expression] evaluated at compile time. Static initializers may refer to other statics. +r[items.static.read-only] Non-`mut` static items that contain a type that is not [interior mutable] may be placed in read-only memory. +r[items.static.safety] All access to a static is safe, but there are a number of restrictions on statics: +r[items.static.constraint-sync] * The type must have the `Sync` trait bound to allow thread-safe access. + +r[items.static.constraint-const] * Constants cannot refer to statics. +r[items.static.restriction-init] The initializer expression must be omitted in an [external block], and must be provided for free static items. +r[items.static.constraint-safety-qualifier] The `safe` and `unsafe` qualifiers are semantically only allowed when used in an [external block]. ## Statics & generics +r[items.static.generics] + A static item defined in a generic scope (for example in a blanket or default implementation) will result in exactly one static item being defined, as if the static definition was pulled out of the current scope into the module. @@ -83,14 +101,21 @@ blanket_impl: counter was 1 ## Mutable statics +r[items.static.mut] + +r[items.static.mut.intro] If a static item is declared with the `mut` keyword, then it is allowed to be modified by the program. One of Rust's goals is to make concurrency bugs hard to run into, and this is obviously a very large source of race conditions or -other bugs. For this reason, an `unsafe` block is required when either reading +other bugs + +r[items.static.mut.safety] +For this reason, an `unsafe` block is required when either reading or writing a mutable static variable. Care should be taken to ensure that modifications to a mutable static are safe with respect to other threads running in the same process. +r[items.static.mut.extern] Mutable statics are still very useful, however. They can be used with C libraries and can also be bound from C libraries in an `extern` block. @@ -122,11 +147,14 @@ fn bump_levels_safe() -> u32 { } ``` +r[items.static.mut.constraints] Mutable statics have the same restrictions as normal statics, except that the type does not have to implement the `Sync` trait. ## Using Statics or Consts +r[items.static.alternate] + It can be confusing whether or not you should use a constant item or a static item. Constants should, in general, be preferred over statics unless one of the following are true: diff --git a/src/items/structs.md b/src/items/structs.md index e59d7e9c0..8a6c9eb22 100644 --- a/src/items/structs.md +++ b/src/items/structs.md @@ -1,5 +1,8 @@ # Structs +r[items.struct] + +r[items.struct.syntax] > **Syntax**\ > _Struct_ :\ >       _StructStruct_\ @@ -36,7 +39,10 @@ >    [_Visibility_]?\ >    [_Type_] +r[items.struct.intro] A _struct_ is a nominal [struct type] defined with the keyword `struct`. + +r[items.struct.namespace] 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: @@ -47,6 +53,7 @@ let p = Point {x: 10, y: 11}; let px: i32 = p.x; ``` +r[items.struct.tuple] 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. @@ -58,6 +65,7 @@ let p = Point(10, 11); let px: i32 = match p { Point(x, _) => x }; ``` +r[items.struct.unit] 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 type with the same name. For example: @@ -75,6 +83,7 @@ const Cookie: Cookie = Cookie {}; let c = [Cookie, Cookie {}, Cookie, Cookie {}]; ``` +r[items.struct.layout] The precise memory layout of a struct is not specified. One can specify a particular layout using the [`repr` attribute]. diff --git a/src/items/traits.md b/src/items/traits.md index bbcd4f926..baafe9c20 100644 --- a/src/items/traits.md +++ b/src/items/traits.md @@ -1,5 +1,8 @@ # Traits +r[items.trait] + +r[items.trait.syntax] > **Syntax**\ > _Trait_ :\ >    `unsafe`? `trait` [IDENTIFIER]  @@ -10,6 +13,7 @@ >      [_AssociatedItem_]\*\ >    `}` +r[items.trait.intro] A _trait_ describes an abstract interface that types can implement. This interface consists of [associated items], which come in three varieties: @@ -17,16 +21,22 @@ interface consists of [associated items], which come in three varieties: - [types](associated-items.md#associated-types) - [constants](associated-items.md#associated-constants) +r[items.trait.namespace] The trait declaration defines a trait in the [type namespace] of the module or block where it is located. + +r[items.trait.associated-item-namespaces] 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. +r[items.trait.self-param] 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 other traits and so forth [as usual][generics]. +r[items.trait.impls] Traits are implemented for specific types through separate [implementations]. +r[item.trait.associated-item-decls] Trait functions may omit the function body by replacing it with a semicolon. This indicates that the implementation must define the function. If the trait function defines a body, this definition acts as a default for any @@ -46,14 +56,19 @@ trait Example { } ``` +r[items.trait.fn-constraint] Trait functions are not allowed to be [`const`]. ## Trait bounds +r[items.traits.bounds] + Generic items may use traits as [bounds] on their type parameters. ## Generic traits +r[items.traits.generic] + Type parameters can be specified for a trait to make it generic. These appear after the trait name, using the same syntax used in [generic functions]. @@ -68,13 +83,25 @@ trait Seq { ## Dyn compatibility +r[items.trait.dyn-compatible] + +r[items.trait.dyn-compatible.intro] A dyn-compatible trait can be the base trait of a [trait object]. A trait is *dyn compatible* if it has the following qualities: +r[items.trait.dyn-compatible.supertraits] * All [supertraits] must also be dyn compatible. + +r[items.trait.dyn-compatible.sized] * `Sized` must not be a [supertrait][supertraits]. In other words, it must not require `Self: Sized`. + +r[items.trait.dyn-compatible.associated-consts] * It must not have any associated constants. + +r[items.trait.dyn-compatible.associated-types] * It must not have any associated types with generics. + +r[items.trait.dyn-compatible.associated-functions] * All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable: * Dispatchable functions must: * Not have any type parameters (although lifetime parameters are allowed). @@ -179,14 +206,19 @@ let obj: Box = Box::new(S); // ERROR: cannot use `Self` type param ## Supertraits +r[items.trait.supertraits] + +r[items.trait.supertraits.intro] **Supertraits** are traits that are required to be implemented for a type to implement a specific trait. Furthermore, anywhere a [generic][generics] or [trait object] is bounded by a trait, it has access to the associated items of its supertraits. +r[items.trait.supertraits.decl] Supertraits are declared by trait bounds on the `Self` type of a trait and transitively the supertraits of the traits declared in those trait bounds. It is an error for a trait to be its own supertrait. +r[items.trait.supertraits.subtrait] The trait with a supertrait is called a **subtrait** of its supertrait. The following is an example of declaring `Shape` to be a supertrait of `Circle`. @@ -245,6 +277,9 @@ let nonsense = circle.radius() * circle.area(); ## Unsafe traits +r[items.trait.safety] + +r[items.trait.safety.intro] Traits items that begin with the `unsafe` keyword indicate that *implementing* the trait may be [unsafe]. It is safe to use a correctly implemented unsafe trait. The [trait implementation] must also begin with the `unsafe` keyword. @@ -253,11 +288,15 @@ The [trait implementation] must also begin with the `unsafe` keyword. ## Parameter patterns +r[items.trait.params] + +r[items.trait.params.constraint] Function or method declarations without a body only allow [IDENTIFIER] or `_` [wild card][WildcardPattern] patterns. `mut` [IDENTIFIER] is currently allowed, but it is deprecated and will become a hard error in the future. +r[items.trait.params.edition2015] In the 2015 edition, the pattern for a trait function or method parameter is optional: @@ -268,6 +307,7 @@ trait T { } ``` +r[items.trait.params.restriction] The kinds of patterns for parameters is limited to one of the following: * [IDENTIFIER] @@ -276,6 +316,7 @@ The kinds of patterns for parameters is limited to one of the following: * `&` [IDENTIFIER] * `&&` [IDENTIFIER] +r[items.trait.params.restriction-edition2018] Beginning in the 2018 edition, function or method parameter patterns are no longer optional. Also, all irrefutable patterns are allowed as long as there is a body. Without a body, the limitations listed above are still in effect. @@ -289,6 +330,9 @@ trait T { ## Item visibility +r[items.trait.associated-visibility] + +r[items.trait.associated-visibility.intro] Trait items syntactically allow a [_Visibility_] annotation, but this is rejected when the trait is validated. This allows items to be parsed with a unified syntax across different contexts where they are used. As an example, diff --git a/src/items/type-aliases.md b/src/items/type-aliases.md index ef3e6fcb7..434639589 100644 --- a/src/items/type-aliases.md +++ b/src/items/type-aliases.md @@ -1,11 +1,15 @@ # Type aliases +r[items.type] + +r[items.type.syntax] > **Syntax**\ > _TypeAlias_ :\ >    `type` [IDENTIFIER] [_GenericParams_]? > ( `:` [_TypeParamBounds_] )? > [_WhereClause_]? ( `=` [_Type_] [_WhereClause_]?)? `;` +r[items.type.intro] 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. @@ -18,6 +22,7 @@ type Point = (u8, u8); let p: Point = (41, 68); ``` +r[items.type.constraint-constructor] A type alias to a tuple-struct or unit-struct cannot be used to qualify that type's constructor: ```rust,compile_fail @@ -30,15 +35,19 @@ let _ = UseAlias(5); // OK let _ = TypeAlias(5); // Doesn't work ``` +r[items.type.constraint] A type alias, when not used as an [associated type], must include a [_Type_] and may not include [_TypeParamBounds_]. +r[items.type.constraint-associated-trait] A type alias, when used as an [associated type] in a [trait], must not include a [_Type_] specification but may include [_TypeParamBounds_]. +r[items.type.constraint-associated-impl] A type alias, when used as an [associated type] in a [trait impl], must include a [_Type_] specification and may not include [_TypeParamBounds_]. +r[items.type.deprecated] Where clauses before the equals sign on a type alias in a [trait impl] (like `type TypeAlias where T: Foo = Bar`) are deprecated. Where clauses after the equals sign (like `type TypeAlias = Bar where T: Foo`) are preferred. diff --git a/src/items/unions.md b/src/items/unions.md index d6a03ed39..f1e696a08 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -1,12 +1,18 @@ # Unions +r[items.union] + +r[items.union.syntax] > **Syntax**\ > _Union_ :\ >    `union` [IDENTIFIER] [_GenericParams_]? [_WhereClause_]? > `{`[_StructFields_]? `}` +r[items.union.intro] A union declaration uses the same syntax as a struct declaration, except with `union` in place of `struct`. + +r[items.union.namespace] A union declaration defines the given name in the [type namespace] of the module or block where it is located. ```rust @@ -17,24 +23,39 @@ union MyUnion { } ``` +r[items.union.common-storage] The key property of unions is that all fields of a union share common storage. As a result, writes to one field of a union can overwrite its other fields, and size of a union is determined by the size of its largest field. +r[items.union.field-constraints] Union field types are restricted to the following subset of types: + +r[items.union.field-copy] - `Copy` types + +r[items.union.field-references] - References (`&T` and `&mut T` for arbitrary `T`) + +r[items.union.field-manually-drop] - `ManuallyDrop` (for arbitrary `T`) + +r[items.union.field-tuple] - Tuples and arrays containing only allowed union field types +r[items.union.drop] This restriction ensures, in particular, that union fields never need to be dropped. Like for structs and enums, it is possible to `impl Drop` for a union to manually define what happens when it gets dropped. +r[items.union.constraint] Unions without any fields are not accepted by the compiler, but can be accepted by macros. ## Initialization of a union +r[items.union.init] + +r[items.union.init.intro] A value of a union type can be created using the same syntax that is used for struct types, except that it must specify exactly one field: @@ -44,6 +65,7 @@ struct types, except that it must specify exactly one field: let u = MyUnion { f1: 1 }; ``` +r[items.union.init.result] The expression above creates a value of type `MyUnion` and initializes the storage using field `f1`. The union can be accessed using the same syntax as struct fields: @@ -57,18 +79,28 @@ let f = unsafe { u.f1 }; ## Reading and writing union fields +r[items.union.fields] + +r[items.union.fields.intro] Unions have no notion of an "active field". Instead, every union access just -interprets the storage as the type of the field used for the access. Reading a -union field reads the bits of the union at the field's type. Fields might have a -non-zero offset (except when [the C representation] is used); in that case the -bits starting at the offset of the fields are read. It is the programmer's -responsibility to make sure that the data is valid at the field's type. Failing +interprets the storage as the type of the field used for the access. + +r[items.union.fields.read] +Reading a union field reads the bits of the union at the field's type. + +r[items.union.fields.offset] +Fields might have a non-zero offset (except when [the C representation] is used); in that case the +bits starting at the offset of the fields are read + +r[items.union.fields.precondition] +It is the programmer's responsibility to make sure that the data is valid at the field's type. Failing to do so results in [undefined behavior]. For example, reading the value `3` from a field of the [boolean type] is undefined behavior. Effectively, writing to and then reading from a union with [the C representation] is analogous to a [`transmute`] from the type used for writing to the type used for reading. +r[items.union.fields.read-safety] Consequently, all reads of union fields have to be placed in `unsafe` blocks: ```rust @@ -83,6 +115,7 @@ unsafe { Commonly, code using unions will provide safe wrappers around unsafe union field accesses. +r[items.union.fields.write-safety] In contrast, writes to union fields are safe, since they just overwrite arbitrary data, but cannot cause undefined behavior. (Note that union field types can never have drop glue, so a union field write will never implicitly @@ -90,10 +123,17 @@ drop anything.) ## Pattern matching on unions -Another way to access union fields is to use pattern matching. Pattern matching -on union fields uses the same syntax as struct patterns, except that the pattern -must specify exactly one field. Since pattern matching is like reading the union -with a particular field, it has to be placed in `unsafe` blocks as well. +r[items.union.pattern] + +r[items.union.pattern.intro] +Another way to access union fields is to use pattern matching. + +r[items.union.pattern.constraint] +Pattern matching on union fields uses the same syntax as struct patterns, except that the pattern +must specify exactly one field. + +r[items.union.pattern.safety] +Since pattern matching is like reading the union with a particular field, it has to be placed in `unsafe` blocks as well. ```rust # union MyUnion { f1: u32, f2: f32 } @@ -108,6 +148,7 @@ fn f(u: MyUnion) { } ``` +r[items.union.pattern.subpattern] Pattern matching may match a union as a field of a larger structure. In particular, when using a Rust union to implement a C tagged union via FFI, this allows matching on the tag and the corresponding field simultaneously: @@ -141,9 +182,14 @@ fn is_zero(v: Value) -> bool { ## References to union fields +r[items.union.ref] + +r[items.union.ref.intro] Since union fields share common storage, gaining write access to one field of a -union can give write access to all its remaining fields. Borrow checking rules -have to be adjusted to account for this fact. As a result, if one field of a +union can give write access to all its remaining fields. + +r[items.union.ref.borrow] +Borrow checking rules have to be adjusted to account for this fact. As a result, if one field of a union is borrowed, all its remaining fields are borrowed as well for the same lifetime. @@ -164,6 +210,7 @@ fn test() { } ``` +r[items.union.ref.usage] As you could see, in many aspects (except for layouts, safety, and ownership) unions behave exactly like structs, largely as a consequence of inheriting their syntactic shape from structs. This is also true for many unmentioned diff --git a/src/items/use-declarations.md b/src/items/use-declarations.md index 4e1096082..1b6a2282c 100644 --- a/src/items/use-declarations.md +++ b/src/items/use-declarations.md @@ -1,5 +1,8 @@ # Use declarations +r[items.use] + +r[items.use.syntax] > **Syntax:**\ > _UseDeclaration_ :\ >    `use` _UseTree_ `;` @@ -9,6 +12,7 @@ >    | ([_SimplePath_]? `::`)? `{` (_UseTree_ ( `,` _UseTree_ )\* `,`?)? `}`\ >    | [_SimplePath_] ( `as` ( [IDENTIFIER] | `_` ) )? +r[items.use.intro] A _use declaration_ creates one or more local name bindings synonymous with some other [path]. Usually a `use` declaration is used to shorten the path required to refer to a module item. These declarations may appear in [modules] @@ -19,17 +23,27 @@ A `use` declaration is also sometimes called an _import_, or, if it is public, a [modules]: modules.md [blocks]: ../expressions/block-expr.md +r[items.use.modes] Use declarations support a number of convenient shortcuts: +r[items.use.mode-multiple] * Simultaneously binding a list of paths with a common prefix, using the brace syntax `use a::b::{c, d, e::f, g::h::i};` + +r[items.use.mode-self] * Simultaneously binding a list of paths with a common prefix and their common parent module, using the `self` keyword, such as `use a::b::{self, c, d::e};` + +r[items.use.mode-as] * Rebinding the target name as a new local name, using the syntax `use p::q::r as x;`. This can also be used with the last two features: `use a::b::{self as ab, c as abc}`. + +r[items.use.mode-glob] * Binding all paths matching a given prefix, using the asterisk wildcard syntax `use a::b::*;`. + +r[items.use.mode-nesting] * Nesting groups of the previous features multiple times, such as `use a::b::{self as ab, c, d::{*, e::f}};` @@ -58,12 +72,18 @@ fn main() { ## `use` Visibility +r[items.use.vis] + +r[items.use.visibility.intro] Like items, `use` declarations are private to the containing module, by default. Also like items, a `use` declaration can be public, if qualified by the `pub` keyword. Such a `use` declaration serves to _re-export_ a name. A public `use` declaration can therefore _redirect_ some public name to a different target definition: even a definition with a private canonical path, -inside a different module. If a sequence of such redirections form a cycle or +inside a different module. + +r[items.use.visibility.constraint] +If a sequence of such redirections form a cycle or cannot be resolved unambiguously, they represent a compile-time error. An example of re-exporting: @@ -88,6 +108,9 @@ In this example, the module `quux` re-exports two public names defined in ## `use` Paths +r[items.use.path] + +r[items.use.path.intro] The [paths] that are allowed in a `use` item follow the [_SimplePath_] grammar and are similar to the paths that may be used in an expression. They may create bindings for: @@ -97,8 +120,10 @@ They may create bindings for: * [Attributes] * [Derive macros] +r[items.use.path.constraint] They cannot import [associated items], [generic parameters], [local variables], paths with [`Self`], or [tool attributes]. More restrictions are described below. +r[items.use.path.namespace] `use` will create bindings for all [namespaces] from the imported entities, with the exception that a `self` import will only import from the type namespace (as described below). For example, the following illustrates creating bindings for the same name in two namespaces: @@ -116,6 +141,7 @@ fn example() { } ``` +r[items.use.path.edition2015] > **Edition differences**: In the 2015 edition, `use` paths are relative to the crate root. > For example: > @@ -141,6 +167,8 @@ fn example() { ## `as` renames +r[item.use.as] + The `as` keyword can be used to change the name of an imported entity. For example: @@ -155,6 +183,9 @@ mod inner { ## Brace syntax +r[item.use.multiple-syntax] + +r[item.use.multiple-syntax.intro] Braces can be used in the last segment of the path to import multiple entities from the previous segment, or, if there are no previous segments, from the current scope. Braces can be nested, creating a tree of paths, where each grouping of segments is logically combined with its parent to create a full path. @@ -166,13 +197,18 @@ Braces can be nested, creating a tree of paths, where each grouping of segments use std::collections::{BTreeSet, hash_map::{self, HashMap}}; ``` +r[item.use.multiple-syntax.sempty] An empty brace does not import anything, though the leading path is validated that it is accessible. +r[item.use.multiple-syntax.edition2015] > **Edition differences**: In the 2015 edition, paths are relative to the crate root, so an import such as `use {foo, bar};` will import the names `foo` and `bar` from the crate root, whereas starting in 2018, those names are relative to the current scope. ## `self` imports +r[item.use.self] + +r[item.use.self.intro] The keyword `self` may be used within [brace syntax](#brace-syntax) to create a binding of the parent entity under its own name. ```rust @@ -191,6 +227,7 @@ mod example { # fn main() {} ``` +r[item.use.self.namespace] `self` only creates a binding from the [type namespace] of the parent entity. For example, in the following, only the `foo` mod is imported: @@ -215,6 +252,9 @@ fn main() { ## Glob imports +r[item.use.glob] + +r[item.use.glob.intro] The `*` character may be used as the last segment of a `use` path to import all importable entities from the entity of the preceding segment. For example: @@ -237,6 +277,7 @@ mod foo { } ``` +r[item.use.glob.shadowing] Items and named imports are allowed to shadow names from glob imports in the same [namespace]. That is, if there is a name already defined by another item in the same namespace, the glob import will be shadowed. For example: @@ -268,20 +309,26 @@ mod clashing { } ``` +r[item.use.glob.restriction] `*` cannot be used as the first or intermediate segments. `*` cannot be used to import a module's contents into itself (such as `use self::*;`). +r[item.use.glob.edition2015] > **Edition differences**: In the 2015 edition, paths are relative to the crate root, so an import such as `use *;` is valid, and it means to import everything from the crate root. > This cannot be used in the crate root itself. ## Underscore Imports +r[item.use.as-underscore] + +r[item.use.as-underscore.intro] Items can be imported without binding to a name by using an underscore with the form `use path as _`. This is particularly useful to import a trait so that its methods may be used without importing the trait's symbol, for example if the trait's symbol may conflict with another symbol. Another example is to link an external crate without importing its name. +r[item.use.as-underscore.glob] Asterisk glob imports will import items imported with `_` in their unnameable form. @@ -303,6 +350,7 @@ fn main() { } ``` +r[item.use.as-underscore.macro] The unique, unnameable symbols are created after macro expansion so that macros may safely emit multiple references to `_` imports. For example, the following should not produce an error: @@ -320,12 +368,23 @@ m!(use std as _;); ## Restrictions +r[item.use.restriction] + The following are restrictions for valid `use` declarations: +r[item.use.restriction.crate] * `use crate;` must use `as` to define the name to which to bind the crate root. + +r[item.use.restriction.self] * `use {self};` is an error; there must be a leading segment when using `self`. + +r[item.use.restriction.duplicate-name] * As with any item definition, `use` imports cannot create duplicate bindings of the same name in the same namespace in a module or block. + +r[item.use.restriction.macro-crate] * `use` paths with `$crate` are not allowed in a [`macro_rules`] expansion. + +r[item.use.restriction.variant] * `use` paths cannot refer to enum variants through a [type alias]. For example: ```rust,compile_fail enum MyEnum { @@ -339,10 +398,14 @@ The following are restrictions for valid `use` declarations: ## Ambiguities +r[item.use.ambiguity] + > **Note**: This section is incomplete. +r[item.use.ambiguity.intro] Some situations are an error when there is an ambiguity as to which name a `use` declaration refers. This happens when there are two name candidates that do not resolve to the same entity. +r[item.use.ambiguity.glob] Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used. For example: From 7e8a9fd21a725c8cbb9a9fdf9f2775c7df2f192c Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Thu, 12 Sep 2024 10:32:20 -0400 Subject: [PATCH 2/4] Remove trailing spaces --- src/items/modules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/items/modules.md b/src/items/modules.md index 8617e15ea..3244aad13 100644 --- a/src/items/modules.md +++ b/src/items/modules.md @@ -17,7 +17,7 @@ A module is a container for zero or more [items]. r[items.mod.def] A _module item_ is a module, surrounded in braces, named, and prefixed with the keyword `mod`. A module item introduces a new, named module into the tree of -modules making up a crate. +modules making up a crate\1 r[items.mod.nesting] Modules can nest arbitrarily. From b563d02fceb308d75cbebf6eaa476704a6285c6a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 30 Oct 2024 10:39:56 -0700 Subject: [PATCH 3/4] Consistently use "items" --- src/items/functions.md | 2 +- src/items/traits.md | 2 +- src/items/use-declarations.md | 52 +++++++++++++++++------------------ 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/items/functions.md b/src/items/functions.md index 4235269be..3b258d12d 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -266,7 +266,7 @@ aborts the process by executing an illegal instruction. r[items.fn.const] -r[item.fn.const.intro] +r[items.fn.const.intro] Functions qualified with the `const` keyword are [const functions], as are [tuple struct] and [tuple variant] constructors. _Const functions_ can be called from within [const contexts]. diff --git a/src/items/traits.md b/src/items/traits.md index baafe9c20..a16ad0172 100644 --- a/src/items/traits.md +++ b/src/items/traits.md @@ -36,7 +36,7 @@ other traits and so forth [as usual][generics]. r[items.trait.impls] Traits are implemented for specific types through separate [implementations]. -r[item.trait.associated-item-decls] +r[items.trait.associated-item-decls] Trait functions may omit the function body by replacing it with a semicolon. This indicates that the implementation must define the function. If the trait function defines a body, this definition acts as a default for any diff --git a/src/items/use-declarations.md b/src/items/use-declarations.md index 1b6a2282c..c66f07352 100644 --- a/src/items/use-declarations.md +++ b/src/items/use-declarations.md @@ -167,7 +167,7 @@ r[items.use.path.edition2015] ## `as` renames -r[item.use.as] +r[items.use.as] The `as` keyword can be used to change the name of an imported entity. For example: @@ -183,9 +183,9 @@ mod inner { ## Brace syntax -r[item.use.multiple-syntax] +r[items.use.multiple-syntax] -r[item.use.multiple-syntax.intro] +r[items.use.multiple-syntax.intro] Braces can be used in the last segment of the path to import multiple entities from the previous segment, or, if there are no previous segments, from the current scope. Braces can be nested, creating a tree of paths, where each grouping of segments is logically combined with its parent to create a full path. @@ -197,18 +197,18 @@ Braces can be nested, creating a tree of paths, where each grouping of segments use std::collections::{BTreeSet, hash_map::{self, HashMap}}; ``` -r[item.use.multiple-syntax.sempty] +r[items.use.multiple-syntax.sempty] An empty brace does not import anything, though the leading path is validated that it is accessible. -r[item.use.multiple-syntax.edition2015] +r[items.use.multiple-syntax.edition2015] > **Edition differences**: In the 2015 edition, paths are relative to the crate root, so an import such as `use {foo, bar};` will import the names `foo` and `bar` from the crate root, whereas starting in 2018, those names are relative to the current scope. ## `self` imports -r[item.use.self] +r[items.use.self] -r[item.use.self.intro] +r[items.use.self.intro] The keyword `self` may be used within [brace syntax](#brace-syntax) to create a binding of the parent entity under its own name. ```rust @@ -227,7 +227,7 @@ mod example { # fn main() {} ``` -r[item.use.self.namespace] +r[items.use.self.namespace] `self` only creates a binding from the [type namespace] of the parent entity. For example, in the following, only the `foo` mod is imported: @@ -252,9 +252,9 @@ fn main() { ## Glob imports -r[item.use.glob] +r[items.use.glob] -r[item.use.glob.intro] +r[items.use.glob.intro] The `*` character may be used as the last segment of a `use` path to import all importable entities from the entity of the preceding segment. For example: @@ -277,7 +277,7 @@ mod foo { } ``` -r[item.use.glob.shadowing] +r[items.use.glob.shadowing] Items and named imports are allowed to shadow names from glob imports in the same [namespace]. That is, if there is a name already defined by another item in the same namespace, the glob import will be shadowed. For example: @@ -309,26 +309,26 @@ mod clashing { } ``` -r[item.use.glob.restriction] +r[items.use.glob.restriction] `*` cannot be used as the first or intermediate segments. `*` cannot be used to import a module's contents into itself (such as `use self::*;`). -r[item.use.glob.edition2015] +r[items.use.glob.edition2015] > **Edition differences**: In the 2015 edition, paths are relative to the crate root, so an import such as `use *;` is valid, and it means to import everything from the crate root. > This cannot be used in the crate root itself. ## Underscore Imports -r[item.use.as-underscore] +r[items.use.as-underscore] -r[item.use.as-underscore.intro] +r[items.use.as-underscore.intro] Items can be imported without binding to a name by using an underscore with the form `use path as _`. This is particularly useful to import a trait so that its methods may be used without importing the trait's symbol, for example if the trait's symbol may conflict with another symbol. Another example is to link an external crate without importing its name. -r[item.use.as-underscore.glob] +r[items.use.as-underscore.glob] Asterisk glob imports will import items imported with `_` in their unnameable form. @@ -350,7 +350,7 @@ fn main() { } ``` -r[item.use.as-underscore.macro] +r[items.use.as-underscore.macro] The unique, unnameable symbols are created after macro expansion so that macros may safely emit multiple references to `_` imports. For example, the following should not produce an error: @@ -368,23 +368,23 @@ m!(use std as _;); ## Restrictions -r[item.use.restriction] +r[items.use.restriction] The following are restrictions for valid `use` declarations: -r[item.use.restriction.crate] +r[items.use.restriction.crate] * `use crate;` must use `as` to define the name to which to bind the crate root. -r[item.use.restriction.self] +r[items.use.restriction.self] * `use {self};` is an error; there must be a leading segment when using `self`. -r[item.use.restriction.duplicate-name] +r[items.use.restriction.duplicate-name] * As with any item definition, `use` imports cannot create duplicate bindings of the same name in the same namespace in a module or block. -r[item.use.restriction.macro-crate] +r[items.use.restriction.macro-crate] * `use` paths with `$crate` are not allowed in a [`macro_rules`] expansion. -r[item.use.restriction.variant] +r[items.use.restriction.variant] * `use` paths cannot refer to enum variants through a [type alias]. For example: ```rust,compile_fail enum MyEnum { @@ -398,14 +398,14 @@ r[item.use.restriction.variant] ## Ambiguities -r[item.use.ambiguity] +r[items.use.ambiguity] > **Note**: This section is incomplete. -r[item.use.ambiguity.intro] +r[items.use.ambiguity.intro] Some situations are an error when there is an ambiguity as to which name a `use` declaration refers. This happens when there are two name candidates that do not resolve to the same entity. -r[item.use.ambiguity.glob] +r[items.use.ambiguity.glob] Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used. For example: From 9e4d72671d3fbb6dcb456422d171171d971170fb Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 31 Oct 2024 14:13:46 -0700 Subject: [PATCH 4/4] Rule annotation cleanup A few things for cleanup: - Fix spelling and formatting - Remove rules in a list. The list is more of an index, the items aren't intended to be rules themselves. - Use some more consistent naming. - Use plurals where appropriate. - Avoid generic "constraint" terminology. --- src/items.md | 25 --------------- src/items/associated-items.md | 23 +++++++------- src/items/constant-items.md | 4 +-- src/items/enumerations.md | 16 +++++----- src/items/extern-crates.md | 2 +- src/items/external-blocks.md | 49 +++++++++++++++-------------- src/items/functions.md | 11 +++---- src/items/generics.md | 12 ++++---- src/items/implementations.md | 8 ++--- src/items/modules.md | 4 +-- src/items/static-items.md | 10 +++--- src/items/traits.md | 58 +++++++++++++++++------------------ src/items/type-aliases.md | 8 ++--- src/items/unions.md | 8 ++--- src/items/use-declarations.md | 42 +++++++++++++------------ 15 files changed, 129 insertions(+), 151 deletions(-) diff --git a/src/items.md b/src/items.md index e3763d457..d5733491c 100644 --- a/src/items.md +++ b/src/items.md @@ -44,43 +44,18 @@ execution, and may reside in read-only memory. r[items.kinds] There are several kinds of items: -r[items.kind-modules] * [modules] - -r[items.kind-extern-crate] * [`extern crate` declarations] - -r[items.kind-use] * [`use` declarations] - -r[items.kind-fn] * [function definitions] - -r[items.kind-type] * [type definitions] - -r[items.kind-struct] * [struct definitions] - -r[items.kind-enum] * [enumeration definitions] - -r[items.kind-union] * [union definitions] - -r[items.kind-const] * [constant items] - -r[items.kind-static] * [static items] - -r[items.kind-trait] * [trait definitions] - -r[items.kind-impl] * [implementations] - -r[items.kind-extern] * [`extern` blocks] r[items.locations] diff --git a/src/items/associated-items.md b/src/items/associated-items.md index d7ba4ea01..3df2e0eee 100644 --- a/src/items/associated-items.md +++ b/src/items/associated-items.md @@ -13,7 +13,7 @@ r[items.associated.syntax] r[items.associated.intro] *Associated Items* are the items declared in [traits] or defined in [implementations]. They are called this because they are defined on an associate -type — the type in the implementation +type — the type in the implementation. r[items.associated.kinds] They are a subset of the kinds of items you can declare in a module. @@ -52,7 +52,7 @@ function body is replaced with a `;`. r[items.associated.name] The identifier is the name of the function. -r[items.associated.constraint] +r[items.associated.same-signature] The generics, parameter list, return type, and where clause of the associated function must be the same as the associated function declarations's. @@ -111,7 +111,7 @@ Associated functions whose first parameter is named `self` are called *methods* and may be invoked using the [method call operator], for example, `x.foo()`, as well as the usual function call notation. -r[items.associated.fn.method.constraint] +r[items.associated.fn.method.self-ty] If the type of the `self` parameter is specified, it is limited to types resolving to one generated by the following grammar (where `'lt` denotes some arbitrary lifetime): @@ -121,7 +121,6 @@ P = &'lt S | &'lt mut S | Box | Rc | Arc | Pin

S = Self | P ``` -r[items.associated.fn.method.self-ty] The `Self` terminal in this grammar denotes a type resolving to the implementing type. This can also include the contextual type alias `Self`, other type aliases, or associated type projections resolving to the implementing type. @@ -214,7 +213,7 @@ let circle_shape = Circle::new(); let bounding_box = circle_shape.bounding_box(); ``` -r[items.associated.fn.params-edition2015] +r[items.associated.fn.params.edition2015] > **Edition differences**: In the 2015 edition, it is possible to declare trait > methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and > an error as of the 2018 edition. All parameters must have an argument name. @@ -233,7 +232,7 @@ r[items.associated.type] r[items.associated.type.intro] *Associated types* are [type aliases] associated with another type. -r[items.associated.type.constraint] +r[items.associated.type.restrictions] Associated types cannot be defined in [inherent implementations] nor can they be given a default implementation in traits. @@ -256,9 +255,9 @@ type Assoc: Bounds where WhereBounds; ``` r[items.associated.type.name] -The identifier is the name of the declared type alias +The identifier is the name of the declared type alias. -r[items.associated.type.constraint-impl] +r[items.associated.type.impl-fulfillment] The optional trait bounds must be fulfilled by the implementations of the type alias. r[items.associated.type.sized] @@ -268,7 +267,7 @@ r[items.associated.type.def] An *associated type definition* defines a type alias for the implementation of a trait on a type -r[items.associated.type.restriction-def] +r[items.associated.type.def.restriction] They are written similarly to an *associated type declaration*, but cannot contain `Bounds`, but instead must contain a `Type`: @@ -405,7 +404,7 @@ where clauses, dependent on functions in the trait and how the GAT is used. Thes rules may be loosened in the future; updates can be found [on the generic associated types initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/explainer/required_bounds.html). -r[items.associated.type.generic-where-clause.constraint-valid-fn] +r[items.associated.type.generic-where-clause.valid-fn] In a few words, these where clauses are required in order to maximize the allowed definitions of the associated type in impls. To do this, any clauses that *can be proven to hold* on functions (using the parameters of the function or trait) @@ -422,7 +421,7 @@ In the above, on the `next` function, we can prove that `Self: 'a`, because of the implied bounds from `&'a mut self`; therefore, we must write the equivalent bound on the GAT itself: `where Self: 'x`. -r[items.associated.type.generic-where-clause.constraint-intersection] +r[items.associated.type.generic-where-clause.intersection] When there are multiple functions in a trait that use the GAT, then the *intersection* of the bounds from the different functions are used, rather than the union. @@ -440,7 +439,7 @@ know that `T: 'a` on `create_checker`, we do not know that on `do_check`. Howeve if `do_check` was commented out, then the `where T: 'x` bound would be required on `Checker`. -r[items.associated.type.generic-where-clause.constraint-forward] +r[items.associated.type.generic-where-clause.forward] The bounds on associated types also propagate required where clauses. ```rust diff --git a/src/items/constant-items.md b/src/items/constant-items.md index 533345569..b80b145e7 100644 --- a/src/items/constant-items.md +++ b/src/items/constant-items.md @@ -11,7 +11,7 @@ r[items.const.intro] A *constant item* is an optionally named _[constant value]_ which is not associated with a specific memory location in the program. -r[items.const.behaviour] +r[items.const.behavior] Constants are essentially inlined wherever they are used, meaning that they are copied directly into the relevant context when used. This includes usage of constants from external crates, and non-[`Copy`] types. References to the same constant are not necessarily @@ -48,7 +48,7 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { }; ``` -r[items.const.restriction] +r[items.const.expr-omission] The constant expression may only be omitted in a [trait definition]. ## Constants with Destructors diff --git a/src/items/enumerations.md b/src/items/enumerations.md index d2441a1bf..f20c77d72 100644 --- a/src/items/enumerations.md +++ b/src/items/enumerations.md @@ -2,7 +2,7 @@ r[items.enum] -r[items.enum.sybtax] +r[items.enum.syntax] > **Syntax**\ > _Enumeration_ :\ >    `enum` @@ -128,7 +128,7 @@ let z = StructLike { value: 123 }; // Struct expression. r[items.enum.discriminant] -r[items.enum.discrimnant.intro] +r[items.enum.discriminant.intro] Each enum instance has a _discriminant_: an integer logically associated to it that is used to determine which variant it holds. @@ -150,7 +150,7 @@ following the variant name with `=` and a [constant expression]: r[items.enum.discriminant.explicit.unit-only] 1. if the enumeration is "[unit-only]". -r[items.enum.discriminan.explicit.primitive-repr] +r[items.enum.discriminant.explicit.primitive-repr] 2. if a [primitive representation] is used. For example: ```rust @@ -187,9 +187,9 @@ assert_eq!(baz_discriminant, 123); #### Restrictions -r[items.enum.discriminant.constraints] +r[items.enum.discriminant.restrictions] -r[items.enum.discrimnant.constraints.same-discriminant] +r[items.enum.discriminant.restrictions.same-discriminant] It is an error when two variants share the same discriminant. ```rust,compile_fail @@ -205,7 +205,7 @@ enum SharedDiscriminantError2 { } ``` -r[items.enum.discrimnant.constraints.above-max-discriminant] +r[items.enum.discriminant.restrictions.above-max-discriminant] It is also an error to have an unspecified discriminant where the previous discriminant is the maximum value for the size of the discriminant. @@ -254,7 +254,7 @@ assert_eq!(1, Enum::Bar as isize); assert_eq!(2, Enum::Baz as isize); ``` -r[items.enum.discriminant.coercion.constraint] +r[items.enum.discriminant.coercion.fieldless] [Field-less enums] can be casted if they do not have explicit discriminants, or where only unit variants are explicit. ```rust @@ -338,7 +338,7 @@ let y: u32 = x; // mismatched type error ## Variant visibility -r[items.enum.constraint-variant-visibility] +r[items.enum.variant-visibility] Enum variants syntactically allow a [_Visibility_] annotation, but this is rejected when the enum is validated. This allows items to be parsed with a diff --git a/src/items/extern-crates.md b/src/items/extern-crates.md index b0522934e..85f10630e 100644 --- a/src/items/extern-crates.md +++ b/src/items/extern-crates.md @@ -25,7 +25,7 @@ Additionally, if the `extern crate` appears in the crate root, then the crate na r[items.extern-crate.as] The `as` clause can be used to bind the imported crate to a different name. -r[items.exter-crate.lookup] +r[items.extern-crate.lookup] 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 loading at runtime. The `soname` is resolved at compile time by scanning the diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md index 6cb49f03b..5839f242b 100644 --- a/src/items/external-blocks.md +++ b/src/items/external-blocks.md @@ -21,7 +21,7 @@ External blocks provide _declarations_ of items that are not _defined_ in the current crate and are the basis of Rust's foreign function interface. These are akin to unchecked imports. -r[items.extern.restriction] +r[items.extern.allowed-kinds] Two kinds of item _declarations_ are allowed in external blocks: [functions] and [statics]. @@ -38,10 +38,13 @@ r[items.extern.fn] r[items.extern.fn.body] Functions within external blocks are declared in the same way as other Rust functions, with the exception that they must not have a body and are instead -terminated by a semicolon +terminated by a semicolon. -r[items.extern.fn.restriction] -Patterns are not allowed in parameters, only [IDENTIFIER] or `_` may be used. The `safe` and `unsafe` function qualifiers are +r[items.extern.fn.param-patterns] +Patterns are not allowed in parameters, only [IDENTIFIER] or `_` may be used. + +r[items.extern.fn.qualifiers] +The `safe` and `unsafe` function qualifiers are allowed, but other function qualifiers (e.g. `const`, `async`, `extern`) are not. @@ -200,19 +203,19 @@ r[items.extern.attributes.link.raw-dylib] an import library to link against (see [`dylib` versus `raw-dylib`] below for details). This is only valid for Windows targets. -r[items.extern.attributes.link.constraint] +r[items.extern.attributes.link.name-requirement] The `name` key must be included if `kind` is specified. r[items.extern.attributes.link.modifiers] The optional `modifiers` argument is a way to specify linking modifiers for the library to link. -r[items.extern.attributes.link.modifiers-syntax] +r[items.extern.attributes.link.modifiers.syntax] Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. -r[items.extern.attributes.link.modifiers-constraint] +r[items.extern.attributes.link.modifiers.multiple] Specifying multiple `modifiers` arguments in a single `link` attribute, or multiple identical modifiers in the same `modifiers` argument is not currently supported. \ Example: `#[link(name = "mylib", kind = "static", modifiers = "+whole-archive")]`. @@ -249,18 +252,18 @@ block. #### Linking modifiers: `bundle` -r[items.extern.attributes.link.modifier-bundle] +r[items.extern.attributes.link.modifiers.bundle] -r[items.extern.attributes.link.modifier-bundle.constraint] +r[items.extern.attributes.link.modifiers.bundle.allowed-kinds] This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. -r[items.extern.attributes.link.modifier-bundle.behaviour] +r[items.extern.attributes.link.modifiers.bundle.behavior] When building a rlib or staticlib `+bundle` means that the native static library will be packed into the rlib or staticlib archive, and then retrieved from there during linking of the final binary. -r[items.extern.attributes.link.modifier-bundle.behaviour-negative] +r[items.extern.attributes.link.modifiers.bundle.behavior-negative] When building a rlib `-bundle` means that the native static library is registered as a dependency of that rlib "by name", and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking. \ @@ -268,10 +271,10 @@ When building a staticlib `-bundle` means that the native static library is simp into the archive and some higher level build system will need to add it later during linking of the final binary. -r[items.extern.attributes.link.modifier-bundle.no-effect] +r[items.extern.attributes.link.modifiers.bundle.no-effect] This modifier has no effect when building other targets like executables or dynamic libraries. -r[items.extern.attributes.link.modifier-bundle.default] +r[items.extern.attributes.link.modifiers.bundle.default] The default for this modifier is `+bundle`. More implementation details about this modifier can be found in @@ -279,17 +282,17 @@ More implementation details about this modifier can be found in #### Linking modifiers: `whole-archive` -r[items.extern.attributes.link.modifier-whole-archive] +r[items.extern.attributes.link.modifiers.whole-archive] -r[items.extern.attributes.link.modifier-whole-archive.constraint] +r[items.extern.attributes.link.modifiers.whole-archive.allowed-kinds] This modifier is only compatible with the `static` linking kind. Using any other kind will result in a compiler error. -r[items.extern.attributes.link.modifier-whole-archive.behaviour] +r[items.extern.attributes.link.modifiers.whole-archive.behavior] `+whole-archive` means that the static library is linked as a whole archive without throwing any object files away. -r[items.extern.attributes.link.modifier-whole-archive.default] +r[items.extern.attributes.link.modifiers.whole-archive.default] The default for this modifier is `-whole-archive`. More implementation details about this modifier can be found in @@ -297,21 +300,21 @@ More implementation details about this modifier can be found in ### Linking modifiers: `verbatim` -r[items.extern.attributes.link.modifier-verbatim] +r[items.extern.attributes.link.modifiers.verbatim] -r[items.extern.attributes.link.modifier-verbatim.constraint] +r[items.extern.attributes.link.modifiers.verbatim.allowed-kinds] This modifier is compatible with all linking kinds. -r[items.extern.attributes.link.modifier-verbatim.behaviour] +r[items.extern.attributes.link.modifiers.verbatim.behavior] `+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker. -r[items.extern.attributes.link.modifier-verbatim.behaviour-negative] +r[items.extern.attributes.link.modifiers.verbatim.behavior-negative] `-verbatim` means that rustc will either add a target-specific prefix and suffix to the library name before passing it to linker, or won't prevent linker from implicitly adding it. -r[items.extern.attributes.link.modifier-verbatim.default] +r[items.extern.attributes.link.modifiers.verbatim.default] The default for this modifier is `-verbatim`. More implementation details about this modifier can be found in @@ -420,7 +423,7 @@ unsafe extern "stdcall" { } ``` -r[items.extern.attributes.link_ordinal.constraints] +r[items.extern.attributes.link_ordinal.allowed-kinds] This attribute is only used with the `raw-dylib` linking kind. Using any other kind will result in a compiler error. diff --git a/src/items/functions.md b/src/items/functions.md index 3b258d12d..8300ad19d 100644 --- a/src/items/functions.md +++ b/src/items/functions.md @@ -75,7 +75,7 @@ fn answer_to_life_the_universe_and_everything() -> i32 { } ``` -r[items.fn.constraint-safety-qualifiers] +r[items.fn.safety-qualifiers] The `safe` function is semantically only allowed when used in an [`extern` block]. ## Function parameters @@ -94,7 +94,7 @@ r[items.fn.params.self-pat] If the first parameter is a _SelfParam_, this indicates that the function is a [method]. -r[items.fn.params.self-constraint] +r[items.fn.params.self-restriction] Functions with a self parameter may only appear as an [associated function] in a [trait] or [implementation]. @@ -125,7 +125,7 @@ return { }; ``` -r[items.fn.body.restriction] +r[items.fn.body.bodyless] Functions without a body block are terminated with a semicolon. This form may only appear in a [trait] or [external block]. @@ -271,7 +271,7 @@ Functions qualified with the `const` keyword are [const functions], as are [tuple struct] and [tuple variant] constructors. _Const functions_ can be called from within [const contexts]. -r[item.fn.const.extern] +r[items.fn.const.extern] Const functions may use the [`extern`] function qualifier. r[items.fn.const.exclusivity] @@ -320,7 +320,7 @@ fn example<'a>(x: &'a str) -> impl Future + 'a { r[items.fn.async.desugar] The actual desugaring is more complex: -r[items.fn.async.lifetime-catpure] +r[items.fn.async.lifetime-capture] - The return type in the desugaring is assumed to capture all lifetime parameters from the `async fn` declaration. This can be seen in the desugared example above, which explicitly outlives, and hence @@ -373,7 +373,6 @@ async fn safe_example() { } ``` -r[items.fn.async.safety.] Note that this behavior is a consequence of the desugaring to a function that returns an `impl Future` -- in this case, the function we desugar to is an `unsafe` function, but the return value remains diff --git a/src/items/generics.md b/src/items/generics.md index 498de7424..feb84ee69 100644 --- a/src/items/generics.md +++ b/src/items/generics.md @@ -30,7 +30,7 @@ implementations, which don't have a name, they come directly after `impl`. r[items.generics.syntax.decl-order] The order of generic parameters is restricted to lifetime parameters and then type and const parameters intermixed. -r[items.generics.syntax.constraint] +r[items.generics.syntax.duplicate-params] The same parameter name may not be declared more than once in a _GenericParams_ list. Some examples of items with type, const, and lifetime parameters: @@ -54,7 +54,7 @@ r[items.generics.builtin-generic-types] [function pointers] have lifetime or type parameters as well, but are not referred to with path syntax. -r[items.generics.constraint-widlcard-lifetime] +r[items.generics.wildcard-lifetime] `'_` is not a valid lifetime parameter. ### Const generics @@ -67,7 +67,7 @@ r[items.generics.const.intro] r[items.generics.const.namespace] 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. -r[items.generics.const.constraint] +r[items.generics.const.allowed-types] The only allowed types of const parameters are `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`. @@ -129,7 +129,7 @@ fn foo() { } ``` -r[items.generics.const.constraint-const-expr] +r[items.generics.const.standalone] As a further restriction, const parameters may only appear as a standalone argument inside of a [type] or [array repeat expression]. In those contexts, they may only be used as a single segment [path expression], possibly inside a @@ -150,7 +150,7 @@ fn bad_function() -> [u8; {N + 1}] { r[items.generics.const.argument] A const argument in a [path] specifies the const value to use for that item. -r[items.generics.const.argument-restriction] +r[items.generics.const.argument.const-expr] The argument must be a [const expression] of the type ascribed to the const parameter. The const expression must be a [block expression][block] (surrounded with braces) unless it is a single path segment (an [IDENTIFIER]) @@ -256,7 +256,7 @@ r[items.generics.where.intro] parameters as well as a way to specify bounds on types that aren't type parameters. -r[items.generics.where.higher-ranked-;ifetimes] +r[items.generics.where.higher-ranked-lifetimes] The `for` keyword can be used to introduce [higher-ranked lifetimes]. It only allows [_LifetimeParam_] parameters. diff --git a/src/items/implementations.md b/src/items/implementations.md index 6f631f3c2..5bde1ec21 100644 --- a/src/items/implementations.md +++ b/src/items/implementations.md @@ -51,10 +51,10 @@ r[items.impl.inherent.associated-items] Inherent implementations associate the contained items to the implementing type. -r[items.impl.inherent.values] +r[items.impl.inherent.associated-items.allowed-items] Inherent implementations can contain [associated functions] (including [methods]) and [associated constants]. -r[items.impl.inherent.constraint-type-alias] +r[items.impl.inherent.type-alias] They cannot contain associated type aliases. r[items.impl.inherent.associated-item-path] @@ -115,7 +115,7 @@ r[items.impl.trait.implemented-trait] The trait is known as the _implemented trait_. The implementing type implements the implemented trait. -r[items.impl.trait.constraint] +r[items.impl.trait.def-requirement] A trait implementation must define all non-default associated items declared by the implemented trait, may redefine default associated items defined by the implemented trait, and cannot define any other items. @@ -226,7 +226,7 @@ least once in one of: * As an [associated type] in the [bounds] of a type that contains another parameter that constrains the implementation -r[items.impl.generics.constraint] +r[items.impl.generics.constrain] Type and const parameters must always constrain the implementation. Lifetimes must constrain the implementation if the lifetime is used in an associated type. diff --git a/src/items/modules.md b/src/items/modules.md index 3244aad13..c8fd4c89e 100644 --- a/src/items/modules.md +++ b/src/items/modules.md @@ -45,11 +45,11 @@ mod math { r[items.mod.namespace] Modules are defined in the [type namespace] of the module or block where they are located. -r[items.mod.namespace-def] +r[items.mod.multiple-items] 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. -r[items.mod.constraint] +r[items.mod.unsafe] 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 the syntax and make use of the `unsafe` keyword, before removing it from the diff --git a/src/items/static-items.md b/src/items/static-items.md index 55890712e..f7e47736c 100644 --- a/src/items/static-items.md +++ b/src/items/static-items.md @@ -36,17 +36,17 @@ r[items.static.safety] All access to a static is safe, but there are a number of restrictions on statics: -r[items.static.constraint-sync] +r[items.static.sync] * The type must have the `Sync` trait bound to allow thread-safe access. -r[items.static.constraint-const] +r[items.static.const] * Constants cannot refer to statics. -r[items.static.restriction-init] +r[items.static.init.omission] The initializer expression must be omitted in an [external block], and must be provided for free static items. -r[items.static.constraint-safety-qualifier] +r[items.static.safety-qualifiers] The `safe` and `unsafe` qualifiers are semantically only allowed when used in an [external block]. ## Statics & generics @@ -147,7 +147,7 @@ fn bump_levels_safe() -> u32 { } ``` -r[items.static.mut.constraints] +r[items.static.mut.sync] Mutable statics have the same restrictions as normal statics, except that the type does not have to implement the `Sync` trait. diff --git a/src/items/traits.md b/src/items/traits.md index a16ad0172..dd315e440 100644 --- a/src/items/traits.md +++ b/src/items/traits.md @@ -1,8 +1,8 @@ # Traits -r[items.trait] +r[items.traits] -r[items.trait.syntax] +r[items.traits.syntax] > **Syntax**\ > _Trait_ :\ >    `unsafe`? `trait` [IDENTIFIER]  @@ -13,7 +13,7 @@ r[items.trait.syntax] >      [_AssociatedItem_]\*\ >    `}` -r[items.trait.intro] +r[items.traits.intro] A _trait_ describes an abstract interface that types can implement. This interface consists of [associated items], which come in three varieties: @@ -21,22 +21,22 @@ interface consists of [associated items], which come in three varieties: - [types](associated-items.md#associated-types) - [constants](associated-items.md#associated-constants) -r[items.trait.namespace] +r[items.traits.namespace] The trait declaration defines a trait in the [type namespace] of the module or block where it is located. -r[items.trait.associated-item-namespaces] +r[items.traits.associated-item-namespaces] 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. -r[items.trait.self-param] +r[items.traits.self-param] 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 other traits and so forth [as usual][generics]. -r[items.trait.impls] +r[items.traits.impls] Traits are implemented for specific types through separate [implementations]. -r[items.trait.associated-item-decls] +r[items.traits.associated-item-decls] Trait functions may omit the function body by replacing it with a semicolon. This indicates that the implementation must define the function. If the trait function defines a body, this definition acts as a default for any @@ -56,7 +56,7 @@ trait Example { } ``` -r[items.trait.fn-constraint] +r[items.traits.const-fn] Trait functions are not allowed to be [`const`]. ## Trait bounds @@ -83,25 +83,25 @@ trait Seq { ## Dyn compatibility -r[items.trait.dyn-compatible] +r[items.traits.dyn-compatible] -r[items.trait.dyn-compatible.intro] +r[items.traits.dyn-compatible.intro] A dyn-compatible trait can be the base trait of a [trait object]. A trait is *dyn compatible* if it has the following qualities: -r[items.trait.dyn-compatible.supertraits] +r[items.traits.dyn-compatible.supertraits] * All [supertraits] must also be dyn compatible. -r[items.trait.dyn-compatible.sized] +r[items.traits.dyn-compatible.sized] * `Sized` must not be a [supertrait][supertraits]. In other words, it must not require `Self: Sized`. -r[items.trait.dyn-compatible.associated-consts] +r[items.traits.dyn-compatible.associated-consts] * It must not have any associated constants. -r[items.trait.dyn-compatible.associated-types] +r[items.traits.dyn-compatible.associated-types] * It must not have any associated types with generics. -r[items.trait.dyn-compatible.associated-functions] +r[items.traits.dyn-compatible.associated-functions] * All associated functions must either be dispatchable from a trait object or be explicitly non-dispatchable: * Dispatchable functions must: * Not have any type parameters (although lifetime parameters are allowed). @@ -206,19 +206,19 @@ let obj: Box = Box::new(S); // ERROR: cannot use `Self` type param ## Supertraits -r[items.trait.supertraits] +r[items.traits.supertraits] -r[items.trait.supertraits.intro] +r[items.traits.supertraits.intro] **Supertraits** are traits that are required to be implemented for a type to implement a specific trait. Furthermore, anywhere a [generic][generics] or [trait object] is bounded by a trait, it has access to the associated items of its supertraits. -r[items.trait.supertraits.decl] +r[items.traits.supertraits.decl] Supertraits are declared by trait bounds on the `Self` type of a trait and transitively the supertraits of the traits declared in those trait bounds. It is an error for a trait to be its own supertrait. -r[items.trait.supertraits.subtrait] +r[items.traits.supertraits.subtrait] The trait with a supertrait is called a **subtrait** of its supertrait. The following is an example of declaring `Shape` to be a supertrait of `Circle`. @@ -277,9 +277,9 @@ let nonsense = circle.radius() * circle.area(); ## Unsafe traits -r[items.trait.safety] +r[items.traits.safety] -r[items.trait.safety.intro] +r[items.traits.safety.intro] Traits items that begin with the `unsafe` keyword indicate that *implementing* the trait may be [unsafe]. It is safe to use a correctly implemented unsafe trait. The [trait implementation] must also begin with the `unsafe` keyword. @@ -288,15 +288,15 @@ The [trait implementation] must also begin with the `unsafe` keyword. ## Parameter patterns -r[items.trait.params] +r[items.traits.params] -r[items.trait.params.constraint] +r[items.traits.params.allowed-patterns] Function or method declarations without a body only allow [IDENTIFIER] or `_` [wild card][WildcardPattern] patterns. `mut` [IDENTIFIER] is currently allowed, but it is deprecated and will become a hard error in the future. -r[items.trait.params.edition2015] +r[items.traits.params.edition2015] In the 2015 edition, the pattern for a trait function or method parameter is optional: @@ -307,7 +307,7 @@ trait T { } ``` -r[items.trait.params.restriction] +r[items.traits.params.restriction] The kinds of patterns for parameters is limited to one of the following: * [IDENTIFIER] @@ -316,7 +316,7 @@ The kinds of patterns for parameters is limited to one of the following: * `&` [IDENTIFIER] * `&&` [IDENTIFIER] -r[items.trait.params.restriction-edition2018] +r[items.traits.params.restriction.edition2018] Beginning in the 2018 edition, function or method parameter patterns are no longer optional. Also, all irrefutable patterns are allowed as long as there is a body. Without a body, the limitations listed above are still in effect. @@ -330,9 +330,9 @@ trait T { ## Item visibility -r[items.trait.associated-visibility] +r[items.traits.associated-visibility] -r[items.trait.associated-visibility.intro] +r[items.traits.associated-visibility.intro] Trait items syntactically allow a [_Visibility_] annotation, but this is rejected when the trait is validated. This allows items to be parsed with a unified syntax across different contexts where they are used. As an example, diff --git a/src/items/type-aliases.md b/src/items/type-aliases.md index 434639589..d496b8c60 100644 --- a/src/items/type-aliases.md +++ b/src/items/type-aliases.md @@ -22,7 +22,7 @@ type Point = (u8, u8); let p: Point = (41, 68); ``` -r[items.type.constraint-constructor] +r[items.type.constructor-alias] A type alias to a tuple-struct or unit-struct cannot be used to qualify that type's constructor: ```rust,compile_fail @@ -35,15 +35,15 @@ let _ = UseAlias(5); // OK let _ = TypeAlias(5); // Doesn't work ``` -r[items.type.constraint] +r[items.type.associated-type] A type alias, when not used as an [associated type], must include a [_Type_] and may not include [_TypeParamBounds_]. -r[items.type.constraint-associated-trait] +r[items.type.associated-trait] A type alias, when used as an [associated type] in a [trait], must not include a [_Type_] specification but may include [_TypeParamBounds_]. -r[items.type.constraint-associated-impl] +r[items.type.associated-impl] A type alias, when used as an [associated type] in a [trait impl], must include a [_Type_] specification and may not include [_TypeParamBounds_]. diff --git a/src/items/unions.md b/src/items/unions.md index f1e696a08..835f924ea 100644 --- a/src/items/unions.md +++ b/src/items/unions.md @@ -28,7 +28,7 @@ The key property of unions is that all fields of a union share common storage. As a result, writes to one field of a union can overwrite its other fields, and size of a union is determined by the size of its largest field. -r[items.union.field-constraints] +r[items.union.field-restrictions] Union field types are restricted to the following subset of types: r[items.union.field-copy] @@ -48,7 +48,7 @@ This restriction ensures, in particular, that union fields never need to be dropped. Like for structs and enums, it is possible to `impl Drop` for a union to manually define what happens when it gets dropped. -r[items.union.constraint] +r[items.union.fieldless] Unions without any fields are not accepted by the compiler, but can be accepted by macros. ## Initialization of a union @@ -92,7 +92,7 @@ r[items.union.fields.offset] Fields might have a non-zero offset (except when [the C representation] is used); in that case the bits starting at the offset of the fields are read -r[items.union.fields.precondition] +r[items.union.fields.validity] It is the programmer's responsibility to make sure that the data is valid at the field's type. Failing to do so results in [undefined behavior]. For example, reading the value `3` from a field of the [boolean type] is undefined behavior. Effectively, @@ -128,7 +128,7 @@ r[items.union.pattern] r[items.union.pattern.intro] Another way to access union fields is to use pattern matching. -r[items.union.pattern.constraint] +r[items.union.pattern.one-field] Pattern matching on union fields uses the same syntax as struct patterns, except that the pattern must specify exactly one field. diff --git a/src/items/use-declarations.md b/src/items/use-declarations.md index c66f07352..ca70b8a8b 100644 --- a/src/items/use-declarations.md +++ b/src/items/use-declarations.md @@ -23,27 +23,27 @@ A `use` declaration is also sometimes called an _import_, or, if it is public, a [modules]: modules.md [blocks]: ../expressions/block-expr.md -r[items.use.modes] +r[items.use.forms] Use declarations support a number of convenient shortcuts: -r[items.use.mode-multiple] +r[items.use.forms.multiple] * Simultaneously binding a list of paths with a common prefix, using the brace syntax `use a::b::{c, d, e::f, g::h::i};` -r[items.use.mode-self] +r[items.use.forms.self] * Simultaneously binding a list of paths with a common prefix and their common parent module, using the `self` keyword, such as `use a::b::{self, c, d::e};` -r[items.use.mode-as] +r[items.use.forms.as] * Rebinding the target name as a new local name, using the syntax `use p::q::r as x;`. This can also be used with the last two features: `use a::b::{self as ab, c as abc}`. -r[items.use.mode-glob] +r[items.use.forms.glob] * Binding all paths matching a given prefix, using the asterisk wildcard syntax `use a::b::*;`. -r[items.use.mode-nesting] +r[items.use.forms.nesting] * Nesting groups of the previous features multiple times, such as `use a::b::{self as ab, c, d::{*, e::f}};` @@ -72,7 +72,7 @@ fn main() { ## `use` Visibility -r[items.use.vis] +r[items.use.visibility] r[items.use.visibility.intro] Like items, `use` declarations are private to the containing module, by @@ -82,7 +82,7 @@ public `use` declaration can therefore _redirect_ some public name to a different target definition: even a definition with a private canonical path, inside a different module. -r[items.use.visibility.constraint] +r[items.use.visibility.unambiguous] If a sequence of such redirections form a cycle or cannot be resolved unambiguously, they represent a compile-time error. @@ -120,7 +120,7 @@ They may create bindings for: * [Attributes] * [Derive macros] -r[items.use.path.constraint] +r[items.use.path.disallowed] They cannot import [associated items], [generic parameters], [local variables], paths with [`Self`], or [tool attributes]. More restrictions are described below. r[items.use.path.namespace] @@ -197,7 +197,7 @@ Braces can be nested, creating a tree of paths, where each grouping of segments use std::collections::{BTreeSet, hash_map::{self, HashMap}}; ``` -r[items.use.multiple-syntax.sempty] +r[items.use.multiple-syntax.empty] An empty brace does not import anything, though the leading path is validated that it is accessible. @@ -309,8 +309,10 @@ mod clashing { } ``` -r[items.use.glob.restriction] +r[items.use.glob.last-segment-only] `*` cannot be used as the first or intermediate segments. + +r[items.use.glob.self-import] `*` cannot be used to import a module's contents into itself (such as `use self::*;`). r[items.use.glob.edition2015] @@ -368,23 +370,23 @@ m!(use std as _;); ## Restrictions -r[items.use.restriction] +r[items.use.restrictions] The following are restrictions for valid `use` declarations: -r[items.use.restriction.crate] +r[items.use.restrictions.crate] * `use crate;` must use `as` to define the name to which to bind the crate root. -r[items.use.restriction.self] +r[items.use.restrictions.self] * `use {self};` is an error; there must be a leading segment when using `self`. -r[items.use.restriction.duplicate-name] +r[items.use.restrictions.duplicate-name] * As with any item definition, `use` imports cannot create duplicate bindings of the same name in the same namespace in a module or block. -r[items.use.restriction.macro-crate] +r[items.use.restrictions.macro-crate] * `use` paths with `$crate` are not allowed in a [`macro_rules`] expansion. -r[items.use.restriction.variant] +r[items.use.restrictions.variant] * `use` paths cannot refer to enum variants through a [type alias]. For example: ```rust,compile_fail enum MyEnum { @@ -398,14 +400,14 @@ r[items.use.restriction.variant] ## Ambiguities -r[items.use.ambiguity] +r[items.use.ambiguities] > **Note**: This section is incomplete. -r[items.use.ambiguity.intro] +r[items.use.ambiguities.intro] Some situations are an error when there is an ambiguity as to which name a `use` declaration refers. This happens when there are two name candidates that do not resolve to the same entity. -r[items.use.ambiguity.glob] +r[items.use.ambiguities.glob] Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used. For example: