Skip to content

Grammar: Functions, methods, impl, traits, extern. #430

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions src/items/associated-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,31 @@ let _: f64 = f64::from_i32(42);

### Methods

> _Method_ :\
> &nbsp;&nbsp; [_FunctionFront_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _SelfParam_ (`,` [_FunctionParam_])<sup>\*</sup> `,`<sup>?</sup> `)`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]
>
> _SelfParam_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; (`&` | `&` [_Lifetime_])<sup>?</sup> `mut`<sup>?</sup> `self`\
> &nbsp;&nbsp; | `mut`<sup>?</sup> `self` (`:` [_Type_])<sup>?</sup>

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.

The `self` parameter must have one of the following types. As a result, the
following shorthands may be used to declare `self`:
If the type of the `self` parameter is specified, it is limited to the type
being implemented (or `Self`), or a reference or mutable reference to the
type, or a boxed value of the type being implemented (such as `Box<Self>`).
Shorthand syntax can be used without specifying a type, which have the
following equivalents:

* `self` -> `self: Self`
* `&'lifetime self` -> `self: &'lifetime Self`
* `&'lifetime mut self` -> `self: &'lifetime mut Self`
* `self : Box<Self>` (no shorthand)
Shorthand | Equivalent
----------------------|-----------
`self` | `self: Self`
`&'lifetime self` | `self: &'lifetime Self`
`&'lifetime mut self` | `self: &'lifetime mut Self`

> Note: Lifetimes can be and usually are elided with this shorthand.

Expand Down Expand Up @@ -272,6 +286,14 @@ fn main() {
}
```

[_BlockExpression_]: expressions/block-expr.html
[_FunctionFront_]: items/functions.html
[_FunctionParam_]: items/functions.html
[_FunctionReturnType_]: items/functions.html
[_Generics_]: items/generics.html
[_Lifetime_]: trait-bounds.html
[_Type_]: types.html
[_WhereClause_]: items/generics.html#where-clauses
[trait]: items/traits.html
[traits]: items/traits.html
[type aliases]: items/type-aliases.html
Expand Down
47 changes: 44 additions & 3 deletions src/items/external-blocks.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
# External blocks

> **<sup>Syntax</sup>**\
> _ExternBlock_ :\
> &nbsp;&nbsp; `extern` [_Abi_]<sup>?</sup> `{`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_InnerAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; _ExternalItem_<sup>\*</sup>\
> &nbsp;&nbsp; `}`
>
> _ExternalItem_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
> &nbsp;&nbsp; ( _ExternalStaticItem_ | _ExternalFunctionItem_ )
>
> _ExternalStaticItem_ :\
> &nbsp;&nbsp; `static` `mut`<sup>?</sup> [IDENTIFIER] `:` [_Type_] `;`
>
> _ExternalFunctionItem_ :\
> &nbsp;&nbsp; `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
> &nbsp;&nbsp; `(` _NamedFunctionParameters_<sup>?</sup> | _NamedFunctionParametersWithVariadics_ ) `)`\
> &nbsp;&nbsp; [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup> `;`
>
> _NamedFunctionParameters_ :\
> &nbsp;&nbsp; _NamedFunctionParam_ ( `,` _NamedFunctionParam_ )<sup>\*</sup> `,`<sup>?</sup>
>
> _NamedFunctionParam_ :\
> &nbsp;&nbsp; ( [IDENTIFIER] | `_` ) `:` [_Type_]
>
> _NamedFunctionParametersWithVariadics_ :\
> &nbsp;&nbsp; ( _NamedFunctionParam_ `,` )<sup>\*</sup> _NamedFunctionParam_ `,` `...`

External blocks form the basis for Rust's foreign function interface.
Declarations in an external block describe symbols in external, non-Rust
libraries.

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
terminated by a semicolon.
terminated by a semicolon. Patterns are not allowed in parameters, only
[IDENTIFIER] or `_` may be used.

Functions within external blocks may be called by Rust code, just like
functions defined in Rust. The Rust compiler automatically translates between
Expand All @@ -23,8 +53,6 @@ extern {

A number of [attributes] control the behavior of external blocks.

[attributes]: attributes.html#ffi-attributes

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:
Expand Down Expand Up @@ -81,3 +109,16 @@ 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
block.

[IDENTIFIER]: identifiers.html
[_Abi_]: items/functions.html
[_FunctionParam_]: items/functions.html
[_FunctionParameters_]: items/functions.html
[_FunctionReturnType_]: items/functions.html
[_Generics_]: items/generics.html
[_InnerAttribute_]: attributes.html
[_OuterAttribute_]: attributes.html
[_Type_]: types.html
[_Visibility_]: visibility-and-privacy.html
[_WhereClause_]: items/generics.html#where-clauses
[attributes]: attributes.html#ffi-attributes
32 changes: 32 additions & 0 deletions src/items/functions.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Functions

> **<sup>Syntax</sup>**\
> _Function_ :\
> &nbsp;&nbsp; _FunctionFront_ `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _FunctionParameters_<sup>?</sup> `)`\
> &nbsp;&nbsp; &nbsp;&nbsp; _FunctionReturnType_<sup>?</sup> [_WhereClause_]<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]
>
> _FunctionFront_ :\
> &nbsp;&nbsp; `unsafe`<sup>?</sup> (`extern` _Abi_<sup>?</sup>)<sup>?</sup>
>
> _Abi_ :\
> &nbsp;&nbsp; [STRING_LITERAL] | [RAW_STRING_LITERAL]
>
> _FunctionParameters_ :\
> &nbsp;&nbsp; _FunctionParam_ (`,` _FunctionParam_)<sup>\*</sup> `,`<sup>?</sup>
>
> _FunctionParam_ :\
> &nbsp;&nbsp; [_Pattern_] `:` [_Type_]
>
> _FunctionReturnType_ :\
> &nbsp;&nbsp; `->` [_Type_]

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
keyword `fn`. Functions may declare a set of *input* [*variables*][variables]
Expand Down Expand Up @@ -138,6 +160,16 @@ attributes], [`must_use`], [the procedural macro attributes], [the testing
attributes], and [the optimization hint
attributes].

[IDENTIFIER]: identifiers.html
[RAW_STRING_LITERAL]: tokens.html#raw-string-literals
[STRING_LITERAL]: tokens.html#string-literals
[_BlockExpression_]: expressions/block-expr.html
[_Generics_]: items/generics.html
[_InnerAttribute_]: attributes.html
[_Pattern_]: patterns.html
[_Statement_]: statements.html
[_Type_]: types.html
[_WhereClause_]: items/generics.html#where-clauses
[external blocks]: items/external-blocks.html
[path]: paths.html
[block]: expressions/block-expr.html
Expand Down
45 changes: 45 additions & 0 deletions src/items/implementations.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Implementations

> **<sup>Syntax</sup>**\
> _Implementation_ :\
> &nbsp;&nbsp; _InherentImpl_ | _TraitImpl_
>
> _InherentImpl_ :\
> &nbsp;&nbsp; `impl` [_Generics_]&nbsp;[_Type_]&nbsp;[_WhereClause_]<sup>?</sup> `{`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_InnerAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; _InherentImplItem_<sup>\*</sup>\
> &nbsp;&nbsp; `}`
>
> _InherentImplItem_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
> &nbsp;&nbsp; ( [_ConstantItem_] | [_Function_] | [_Method_] )
>
> _TraitImpl_ :\
> &nbsp;&nbsp; `unsafe`<sup>?</sup> `impl` [_Generics_] `!`<sup>?</sup>
> [_TypePath_] `for` [_Type_]\
> &nbsp;&nbsp; [_WhereClause_]<sup>?</sup>\
> &nbsp;&nbsp; `{`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_InnerAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; _TraitImplItem_<sup>\*</sup>\
> &nbsp;&nbsp; `}`
>
> _TraitImplItem_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; [_Visibility_]<sup>?</sup>\
> &nbsp;&nbsp; ( [_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
that belong to an instance of the type that is being implemented or to the
Expand Down Expand Up @@ -59,6 +88,9 @@ 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.

[Unsafe traits] require the trait implementation to begin with the `unsafe`
keyword.

```rust
# #[derive(Copy, Clone)]
# struct Point {x: f64, y: f64};
Expand Down Expand Up @@ -143,9 +175,22 @@ attributes must come before any associated items. That attributes that have
meaning here are [`cfg`], [`deprecated`], [`doc`], and [the lint check
attributes].

[IDENTIFIER]: identifiers.html
[_ConstantItem_]: items/constant-items.html
[_Function_]: items/functions.html
[_Generics_]: items/generics.html
[_InnerAttribute_]: attributes.html
[_Method_]: items/associated-items.html#methods
[_OuterAttribute_]: attributes.html
[_TypeAlias_]: items/type-aliases.html
[_TypePath_]: paths.html#paths-in-types
[_Type_]: types.html
[_Visibility_]: visibility-and-privacy.html
[_WhereClause_]: items/generics.html#where-clauses
[trait]: items/traits.html
[attributes]: attributes.html
[`cfg`]: conditional-compilation.html
[`deprecated`]: attributes.html#deprecation
[`doc`]: attributes.html#documentation
[the lint check attributes]: attributes.html#lint-check-attributes
[Unsafe traits]: items/traits.html#unsafe-traits
100 changes: 100 additions & 0 deletions src/items/traits.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
# Traits

> **<sup>Syntax</sup>**\
> _Trait_ :\
> &nbsp;&nbsp; `unsafe`<sup>?</sup> `trait` [IDENTIFIER]&nbsp;
> [_Generics_]<sup>?</sup>
> [_WhereClause_]<sup>?</sup> `{`\
> &nbsp;&nbsp;&nbsp;&nbsp; _TraitItem_<sup>\*</sup>\
> &nbsp;&nbsp; `}`
>
> _TraitItem_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (_TraitFunc_ | _TraitMethod_ | _TraitConst_ | _TraitType_)
>
> _TraitFunc_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _TraitFunctionDecl_ ( `;` | [_BlockExpression_] )
>
> _TraitMethod_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _TraitMethodDecl_ ( `;` | [_BlockExpression_] )
>
> _TraitFunctionDecl_ :\
> &nbsp;&nbsp; [_FunctionFront_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _TraitFunctionParameters_<sup>?</sup> `)`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup>
>
> _TraitMethodDecl_ :\
> &nbsp;&nbsp; [_FunctionFront_] `fn` [IDENTIFIER]&nbsp;[_Generics_]<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; `(` [_SelfParam_] (`,` _TraitFunctionParam_)<sup>\*</sup> `,`<sup>?</sup> `)`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_FunctionReturnType_]<sup>?</sup> [_WhereClause_]<sup>?</sup>
>
> _TraitFunctionParameters_ :\
> &nbsp;&nbsp; _TraitFunctionParam_ (`,` _TraitFunctionParam_)<sup>\*</sup> `,`<sup>?</sup>
>
> _TraitFunctionParam_<sup>[†](#parameter-patterns)</sup> :\
> &nbsp;&nbsp; ( [_Pattern_] `:` )<sup>?</sup> [_Type_]
>
> _TraitConst_ :\
> &nbsp;&nbsp; `const` [IDENTIFIER] ( ( `:` [_Type_] ) ( `=` [_Expression_] )<sup>?</sup> )<sup>?</sup> `;`
>
> _TraitType_ :\
> &nbsp;&nbsp; `type` [IDENTIFIER] ( `:` [_TypeParamBounds_] )<sup>?</sup> `;`

A _trait_ describes an abstract interface that types can implement. This
interface consists of [associated items], which come in three varieties:

Expand Down Expand Up @@ -115,6 +154,63 @@ let circle = Box::new(circle) as Box<dyn Circle>;
let nonsense = circle.radius() * circle.area();
```

## Unsafe traits

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.

[`Sync`] and [`Send`] are examples of unsafe traits.

## Parameter 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.
<!-- https://github.com/rust-lang/rust/issues/35203 -->

In the 2015 edition, the pattern for a trait function or method parameter is
optional:

```rust
trait T {
fn f(i32); // Parameter identifiers are not required.
}
```

The kinds of patterns for parameters is limited to one of the following:

* [IDENTIFIER]
* `mut` [IDENTIFIER]
* [`_`][WildcardPattern]
* `&` [IDENTIFIER]
* `&&` [IDENTIFIER]

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.

```rust,edition2018
trait T {
fn f1((a, b): (i32, i32)) {}
fn f2(_: (i32, i32)); // Cannot use tuple pattern without a body.
}
```

[IDENTIFIER]: identifiers.html
[WildcardPattern]: patterns.html#wildcard-pattern
[_BlockExpression_]: expressions/block-expr.html
[_Expression_]: expressions.html
[_FunctionFront_]: items/functions.html
[_FunctionParam_]: items/functions.html
[_FunctionReturnType_]: items/functions.html
[_Generics_]: items/generics.html
[_OuterAttribute_]: attributes.html
[_Pattern_]: patterns.html
[_SelfParam_]: items/associated-items.html#methods
[_TypeParamBounds_]: trait-bounds.html
[_Type_]: types.html
[_WhereClause_]: items/generics.html#where-clauses
[bounds]: trait-bounds.html
[trait object]: types.html#trait-objects
[explicit]: expressions/operator-expr.html#type-cast-expressions
Expand All @@ -125,3 +221,7 @@ let nonsense = circle.radius() * circle.area();
[generics]: items/generics.html
[where clauses]: items/generics.html#where-clauses
[generic functions]: items/functions.html#generic-functions
[unsafe]: unsafety.html
[trait implementation]: items/implementations.html#trait-implementations
[`Send`]: special-types-and-traits.html#send
[`Sync`]: special-types-and-traits.html#sync
16 changes: 11 additions & 5 deletions src/unsafety.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@ guarantees of Rust's static semantics.
The following language level features cannot be used in the safe subset of
Rust:

- Dereferencing a [raw pointer](types.html#pointer-types).
- Reading or writing a [mutable static variable](items/static-items.html#mutable-statics).
- Reading a field of a [`union`](items/unions.html), or writing to a field of a
union that isn't [`Copy`](special-types-and-traits.html#copy).
- Dereferencing a [raw pointer].
- Reading or writing a [mutable static variable].
- Reading a field of a [`union`], or writing to a field of a
union that isn't [`Copy`].
- Calling an unsafe function (including an intrinsic or foreign function).
- Implementing an unsafe trait.
- Implementing an [unsafe trait].

[`Copy`]: special-types-and-traits.html#copy
[`union`]: items/unions.html
[mutable static variable]: items/static-items.html#mutable-statics
[raw pointer]: types.html#pointer-types
[unsafe trait]: items/traits.html#unsafe-traits