`]: ../special-types-and-traits.md#boxt
[`Pin`]: ../special-types-and-traits.md#pinp
[`Rc`]: ../special-types-and-traits.md#rct
-[_OuterAttribute_]: ../attributes.md
[traits]: traits.md
[type aliases]: type-aliases.md
[inherent implementations]: implementations.md#inherent-implementations
@@ -367,3 +358,5 @@ fn main() {
[method call operator]: ../expressions/method-call-expr.md
[path]: ../paths.md
[regular function parameters]: functions.md#attributes-on-function-parameters
+[generic parameters]: generics.md
+[where clauses]: generics.md#where-clauses
diff --git a/src/items/constant-items.md b/src/items/constant-items.md
index 3d8834fe8..75b586ebe 100644
--- a/src/items/constant-items.md
+++ b/src/items/constant-items.md
@@ -2,7 +2,7 @@
> **Syntax**\
> _ConstantItem_ :\
-> `const` ( [IDENTIFIER] | `_` ) `:` [_Type_] `=` [_Expression_] `;`
+> `const` ( [IDENTIFIER] | `_` ) `:` [_Type_] ( `=` [_Expression_] )? `;`
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
@@ -38,6 +38,8 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
};
```
+The constant expression may only be omitted in a [trait definition].
+
## Constants with Destructors
Constants can contain destructors. Destructors are run when the value goes out
@@ -91,6 +93,7 @@ m!(const _: () = (););
[constant value]: ../const_eval.md#constant-expressions
[free]: ../glossary.md#free-item
[static lifetime elision]: ../lifetime-elision.md#static-lifetime-elision
+[trait definition]: traits.md
[IDENTIFIER]: ../identifiers.md
[underscore imports]: use-declarations.md#underscore-imports
[_Type_]: ../types.md#type-expressions
diff --git a/src/items/external-blocks.md b/src/items/external-blocks.md
index 6a1ada912..9443276d4 100644
--- a/src/items/external-blocks.md
+++ b/src/items/external-blocks.md
@@ -10,25 +10,8 @@
> _ExternalItem_ :\
> [_OuterAttribute_]\* (\
> [_MacroInvocationSemi_]\
-> | ( [_Visibility_]? ( _ExternalStaticItem_ | _ExternalFunctionItem_ ) )\
+> | ( [_Visibility_]? ( [_StaticItem_] | [_Function_] ) )\
> )
->
-> _ExternalStaticItem_ :\
-> `static` `mut`? [IDENTIFIER] `:` [_Type_] `;`
->
-> _ExternalFunctionItem_ :\
-> `fn` [IDENTIFIER] [_GenericParams_]?\
-> `(` ( _NamedFunctionParameters_ | _NamedFunctionParametersWithVariadics_ )? `)`\
-> [_FunctionReturnType_]? [_WhereClause_]? `;`
->
-> _NamedFunctionParameters_ :\
-> _NamedFunctionParam_ ( `,` _NamedFunctionParam_ )\* `,`?
->
-> _NamedFunctionParam_ :\
-> [_OuterAttribute_]\* ( [IDENTIFIER] | `_` ) `:` [_Type_]
->
-> _NamedFunctionParametersWithVariadics_ :\
-> ( _NamedFunctionParam_ `,` )\* _NamedFunctionParam_ `,` [_OuterAttribute_]\* `...`
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
@@ -46,9 +29,10 @@ token stream.
## Functions
Functions within external blocks are declared in the same way as other Rust
-functions, with the exception that they may not have a body and are instead
+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.
+[IDENTIFIER] or `_` may be used. Function qualifiers (`const`, `async`,
+`unsafe`, and `extern`) are not allowed.
Functions within external blocks may be called by Rust code, just like
functions defined in Rust. The Rust compiler automatically translates between
@@ -109,12 +93,15 @@ There are also some platform-specific ABI strings:
## Variadic functions
-Functions within external blocks may be variadic by specifying `...` after one
-or more named arguments in the argument list:
+Functions within external blocks may be variadic by specifying `...` as the
+last argument. There must be at least one parameter before the variadic
+parameter. The variadic parameter may optionally be specified with an
+identifier.
```rust
-extern {
+extern "C" {
fn foo(x: i32, ...);
+ fn with_name(format: *const u8, args: ...);
}
```
@@ -189,15 +176,13 @@ restrictions as [regular function parameters].
[functions]: functions.md
[statics]: static-items.md
[_Abi_]: functions.md
-[_FunctionReturnType_]: functions.md
-[_GenericParams_]: generics.md
+[_Function_]: functions.md
[_InnerAttribute_]: ../attributes.md
[_MacroInvocationSemi_]: ../macros.md#macro-invocation
[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
[_OuterAttribute_]: ../attributes.md
-[_Type_]: ../types.md#type-expressions
+[_StaticItem_]: static-items.md
[_Visibility_]: ../visibility-and-privacy.md
-[_WhereClause_]: generics.md#where-clauses
[attributes]: ../attributes.md
[regular function parameters]: functions.md#attributes-on-function-parameters
diff --git a/src/items/functions.md b/src/items/functions.md
index 550f6d96a..b6bd15904 100644
--- a/src/items/functions.md
+++ b/src/items/functions.md
@@ -5,25 +5,42 @@
> _FunctionQualifiers_ `fn` [IDENTIFIER] [_GenericParams_]?\
> `(` _FunctionParameters_? `)`\
> _FunctionReturnType_? [_WhereClause_]?\
-> [_BlockExpression_]
+> ( [_BlockExpression_] | `;` )
>
> _FunctionQualifiers_ :\
-> _AsyncConstQualifiers_? `unsafe`? (`extern` _Abi_?)?
->
-> _AsyncConstQualifiers_ :\
-> `async` | `const`
+> `const`? `async`[^async-edition]? `unsafe`? (`extern` _Abi_?)?
>
> _Abi_ :\
> [STRING_LITERAL] | [RAW_STRING_LITERAL]
>
> _FunctionParameters_ :\
-> _FunctionParam_ (`,` _FunctionParam_)\* `,`?
+> _SelfParam_ `,`?\
+> | (_SelfParam_ `,`)? _FunctionParam_ (`,` _FunctionParam_)\* `,`?
+>
+> _SelfParam_ :\
+> [_OuterAttribute_]\* ( _ShorthandSelf_ | _TypedSelf_ )
+>
+> _ShorthandSelf_ :\
+> (`&` | `&` [_Lifetime_])? `mut`? `self`
+>
+> _TypedSelf_ :\
+> `mut`? `self` `:` [_Type_]
>
> _FunctionParam_ :\
-> [_OuterAttribute_]\* [_Pattern_] `:` [_Type_]
+> [_OuterAttribute_]\* (
+> _FunctionParamPattern_ | `...` | [_Type_] [^fn-param-2015]
+> )
+>
+> _FunctionParamPattern_ :\
+> [_Pattern_] `:` ( [_Type_] | `...` )
>
> _FunctionReturnType_ :\
> `->` [_Type_]
+>
+> [^async-edition]: The `async` qualifier is not allowed in the 2015 edition.
+>
+> [^fn-param-2015]: Function parameters with only a type are only allowed
+> in an associated function of a [trait item] in the 2015 edition.
A _function_ consists of a [block], along with a name and a set of parameters.
Other than a name, all these are optional. Functions are declared with the
@@ -43,13 +60,25 @@ fn answer_to_life_the_universe_and_everything() -> i32 {
}
```
-As with `let` bindings, function arguments are irrefutable [patterns], so any
+## Function parameters
+
+As with `let` bindings, function parameters are irrefutable [patterns], so any
pattern that is valid in a let binding is also valid as an argument:
```rust
fn first((value, _): (i32, i32)) -> i32 { value }
```
+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
+function] in a [trait] or [implementation].
+
+A parameter with the `...` token indicates a [variadic function], and may only
+be used as the last parameter of a [external block] function. The variadic
+parameter may have an optional identifier, such as `args: ...`.
+
+## Function body
+
The block of a function is conceptually wrapped in a block that binds the
argument patterns and then `return`s the value of the function's block. This
means that the tail expression of the block, if evaluated, ends up being
@@ -67,6 +96,9 @@ return {
};
```
+Functions without a body block are terminated with a semicolon. This form
+may only appear in a [trait] or [external block].
+
## Generic functions
A _generic function_ allows one or more _parameterized types_ to appear in its
@@ -187,6 +219,9 @@ 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 context]s.
+Const functions are not allowed to be [async](#async-functions), and cannot
+use the [`extern` function qualifier](#extern-function-qualifier).
+
## Async functions
Functions may be qualified as async, and this can also be combined with the
@@ -342,6 +377,7 @@ fn foo_oof(#[some_inert_attribute] arg: u8) {
[STRING_LITERAL]: ../tokens.md#string-literals
[_BlockExpression_]: ../expressions/block-expr.md
[_GenericParams_]: generics.md
+[_Lifetime_]: ../trait-bounds.md
[_Pattern_]: ../patterns.md
[_Type_]: ../types.md#type-expressions
[_WhereClause_]: generics.md#where-clauses
@@ -372,3 +408,8 @@ fn foo_oof(#[some_inert_attribute] arg: u8) {
[`link_section`]: ../abi.md#the-link_section-attribute
[`no_mangle`]: ../abi.md#the-no_mangle-attribute
[built-in attributes]: ../attributes.html#built-in-attributes-index
+[trait item]: traits.md
+[method]: associated-items.md#methods
+[associated function]: associated-items.md#associated-functions-and-methods
+[implementation]: implementations.md
+[variadic function]: external-blocks.md#variadic-functions
diff --git a/src/items/implementations.md b/src/items/implementations.md
index a31ccc11d..f1baad74e 100644
--- a/src/items/implementations.md
+++ b/src/items/implementations.md
@@ -7,29 +7,17 @@
> _InherentImpl_ :\
> `impl` [_GenericParams_]? [_Type_] [_WhereClause_]? `{`\
> [_InnerAttribute_]\*\
-> _InherentImplItem_\*\
+> [_AssociatedItem_]\*\
> `}`
>
-> _InherentImplItem_ :\
-> [_OuterAttribute_]\* (\
-> [_MacroInvocationSemi_]\
-> | ( [_Visibility_]? ( [_ConstantItem_] | [_Function_] | [_Method_] ) )\
-> )
->
> _TraitImpl_ :\
> `unsafe`? `impl` [_GenericParams_]? `!`?
> [_TypePath_] `for` [_Type_]\
> [_WhereClause_]?\
> `{`\
> [_InnerAttribute_]\*\
-> _TraitImplItem_\*\
+> [_AssociatedItem_]\*\
> `}`
->
-> _TraitImplItem_ :\
-> [_OuterAttribute_]\* (\
-> [_MacroInvocationSemi_]\
-> | ( [_Visibility_]? ( [_TypeAlias_] | [_ConstantItem_] | [_Function_] | [_Method_] ) )\
-> )
An _implementation_ is an item that associates items with an _implementing type_.
Implementations are defined with the keyword `impl` and contain functions
@@ -52,7 +40,7 @@ the _associated items_ to the implementing type.
Inherent implementations associate the contained items to the
implementing type. Inherent implementations can contain [associated
-functions] (including methods) and [associated constants]. They cannot
+functions] (including [methods]) and [associated constants]. They cannot
contain associated type aliases.
The [path] to an associated item is any path to the implementing type,
@@ -281,17 +269,11 @@ attributes must come before any associated items. That attributes that have
meaning here are [`cfg`], [`deprecated`], [`doc`], and [the lint check
attributes].
-[_ConstantItem_]: constant-items.md
-[_Function_]: functions.md
+[_AssociatedItem_]: associated-items.md
[_GenericParams_]: generics.md
[_InnerAttribute_]: ../attributes.md
-[_MacroInvocationSemi_]: ../macros.md#macro-invocation
-[_Method_]: associated-items.md#methods
-[_OuterAttribute_]: ../attributes.md
-[_TypeAlias_]: type-aliases.md
[_TypePath_]: ../paths.md#paths-in-types
[_Type_]: ../types.md#type-expressions
-[_Visibility_]: ../visibility-and-privacy.md
[_WhereClause_]: generics.md#where-clauses
[trait]: traits.md
[associated constants]: associated-items.md#associated-constants
@@ -303,6 +285,7 @@ attributes].
[`deprecated`]: ../attributes/diagnostics.md#the-deprecated-attribute
[`doc`]: ../../rustdoc/the-doc-attribute.html
[generic parameters]: generics.md
+[methods]: associated-items.md#methods
[path]: ../paths.md
[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
[Unsafe traits]: traits.md#unsafe-traits
diff --git a/src/items/static-items.md b/src/items/static-items.md
index 4e9640e4e..284e78e28 100644
--- a/src/items/static-items.md
+++ b/src/items/static-items.md
@@ -3,7 +3,7 @@
> **Syntax**\
> _StaticItem_ :\
> `static` `mut`? [IDENTIFIER] `:` [_Type_]
-> `=` [_Expression_] `;`
+> ( `=` [_Expression_] )? `;`
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
@@ -23,6 +23,9 @@ statics:
* The type must have the `Sync` trait bound to allow thread-safe access.
* Constants cannot refer to statics.
+The initializer expression must be omitted in an [external block], and must be
+provided for free static items.
+
## Mutable statics
If a static item is declared with the `mut` keyword, then it is allowed to be
@@ -73,6 +76,7 @@ following are true:
[constant]: constant-items.md
[`drop`]: ../destructors.md
[constant expression]: ../const_eval.md#constant-expressions
+[external block]: external-blocks.md
[interior mutable]: ../interior-mutability.md
[IDENTIFIER]: ../identifiers.md
[_Type_]: ../types.md#type-expressions
diff --git a/src/items/traits.md b/src/items/traits.md
index 3094bb49f..e11e1e8de 100644
--- a/src/items/traits.md
+++ b/src/items/traits.md
@@ -7,45 +7,8 @@
> ( `:` [_TypeParamBounds_]? )?
> [_WhereClause_]? `{`\
> [_InnerAttribute_]\*\
-> _TraitItem_\*\
+> [_AssociatedItem_]\*\
> `}`
->
-> _TraitItem_ :\
-> [_OuterAttribute_]\* [_Visibility_]? (\
-> _TraitFunc_\
-> | _TraitMethod_\
-> | _TraitConst_\
-> | _TraitType_\
-> | [_MacroInvocationSemi_]\
-> )
->
-> _TraitFunc_ :\
-> _TraitFunctionDecl_ ( `;` | [_BlockExpression_] )
->
-> _TraitMethod_ :\
-> _TraitMethodDecl_ ( `;` | [_BlockExpression_] )
->
-> _TraitFunctionDecl_ :\
-> [_FunctionQualifiers_] `fn` [IDENTIFIER] [_GenericParams_]?\
-> `(` _TraitFunctionParameters_? `)`\
-> [_FunctionReturnType_]? [_WhereClause_]?
->
-> _TraitMethodDecl_ :\
-> [_FunctionQualifiers_] `fn` [IDENTIFIER] [_GenericParams_]?\
-> `(` [_SelfParam_] (`,` _TraitFunctionParam_)\* `,`? `)`\
-> [_FunctionReturnType_]? [_WhereClause_]?
->
-> _TraitFunctionParameters_ :\
-> _TraitFunctionParam_ (`,` _TraitFunctionParam_)\* `,`?
->
-> _TraitFunctionParam_[†](#parameter-patterns) :\
-> [_OuterAttribute_]\* ( [_Pattern_] `:` )? [_Type_]
->
-> _TraitConst_ :\
-> `const` [IDENTIFIER] `:` [_Type_] ( `=` [_Expression_] )? `;`
->
-> _TraitType_ :\
-> `type` [IDENTIFIER] ( `:` [_TypeParamBounds_]? )? `;`
A _trait_ describes an abstract interface that types can implement. This
interface consists of [associated items], which come in three varieties:
@@ -61,10 +24,26 @@ other traits and so forth [as usual][generics].
Traits are implemented for specific types through separate [implementations].
-Items associated with a trait do not need to be defined in the trait, but they
-may be. If the trait provides a definition, then this definition acts as a
-default for any implementation which does not override it. If it does not, then
-any implementation must provide a definition.
+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
+implementation which does not override it. Similarly, associated constants may
+omit the equals sign and expression to indicate implementations must define
+the constant value. Associated types must never define the type, the type may
+only be specified in an implementation.
+
+```rust
+// Examples of associated trait items with and without definitions.
+trait Example {
+ const CONST_NO_DEFAULT: i32;
+ const CONST_WITH_DEFAULT: i32 = 99;
+ type TypeNoDefault;
+ fn method_without_default(&self);
+ fn method_with_default(&self) {}
+}
+```
+
+Trait functions are are not allowed to be [`async`] or [`const`].
## Trait bounds
@@ -335,18 +314,10 @@ fn main() {
[IDENTIFIER]: ../identifiers.md
[WildcardPattern]: ../patterns.md#wildcard-pattern
-[_BlockExpression_]: ../expressions/block-expr.md
-[_Expression_]: ../expressions.md
-[_FunctionQualifiers_]: functions.md
-[_FunctionReturnType_]: functions.md
+[_AssociatedItem_]: associated-items.md
[_GenericParams_]: generics.md
-[_MacroInvocationSemi_]: ../macros.md#macro-invocation
-[_OuterAttribute_]: ../attributes.md
[_InnerAttribute_]: ../attributes.md
-[_Pattern_]: ../patterns.md
-[_SelfParam_]: associated-items.md#methods
[_TypeParamBounds_]: ../trait-bounds.md
-[_Type_]: ../types.md#type-expressions
[_Visibility_]: ../visibility-and-privacy.md
[_WhereClause_]: generics.md#where-clauses
[bounds]: ../trait-bounds.md
@@ -366,3 +337,5 @@ fn main() {
[`Box`]: ../special-types-and-traits.md#boxt
[`Pin`]: ../special-types-and-traits.md#pinp
[`Rc`]: ../special-types-and-traits.md#rct
+[`async`]: functions.md#async-functions
+[`const`]: functions.md#const-functions
diff --git a/src/items/type-aliases.md b/src/items/type-aliases.md
index d8fc5bf66..c471f7a6a 100644
--- a/src/items/type-aliases.md
+++ b/src/items/type-aliases.md
@@ -3,15 +3,13 @@
> **Syntax**\
> _TypeAlias_ :\
> `type` [IDENTIFIER] [_GenericParams_]?
-> [_WhereClause_]? `=` [_Type_] `;`
+> [_WhereClause_]? ( `=` [_Type_] ) `;`
A _type alias_ defines a new name for an existing [type]. Type aliases are
declared with the keyword `type`. Every value has a single, specific type, but
may implement several different traits, or be compatible with several different
type constraints.
-[type]: ../types.md
-
For example, the following defines the type `Point` as a synonym for the type
`(u8, u8)`, the type of pairs of unsigned 8 bit integers:
@@ -32,7 +30,13 @@ let _ = UseAlias(5); // OK
let _ = TypeAlias(5); // Doesn't work
```
+A type alias without the [_Type_] specification may only appear as an
+[associated type] in a [trait].
+
[IDENTIFIER]: ../identifiers.md
[_GenericParams_]: generics.md
[_WhereClause_]: generics.md#where-clauses
[_Type_]: ../types.md#type-expressions
+[associated type]: associated-items.md#associated-types
+[trait]: traits.md
+[type]: ../types.md
diff --git a/src/types/function-pointer.md b/src/types/function-pointer.md
index 4a7a1ae47..2059cf48b 100644
--- a/src/types/function-pointer.md
+++ b/src/types/function-pointer.md
@@ -2,9 +2,12 @@
> **Syntax**\
> _BareFunctionType_ :\
-> [_ForLifetimes_]? [_FunctionQualifiers_] `fn`\
+> [_ForLifetimes_]? _FunctionTypeQualifiers_ `fn`\
> `(` _FunctionParametersMaybeNamedVariadic_? `)` _BareFunctionReturnType_?
>
+> _FunctionTypeQualifiers_:\
+> `unsafe`? (`extern` [_Abi_]?)?
+>
> _BareFunctionReturnType_:\
> `->` [_TypeNoBounds_]
>
@@ -50,8 +53,8 @@ Attributes on function pointer parameters follow the same rules and
restrictions as [regular function parameters].
[IDENTIFIER]: ../identifiers.md
+[_Abi_]: ../items/functions.md
[_ForLifetimes_]: ../items/generics.md#where-clauses
-[_FunctionQualifiers_]: ../items/functions.md
[_TypeNoBounds_]: ../types.md#type-expressions
[_Type_]: ../types.md#type-expressions
[_OuterAttribute_]: ../attributes.md