Skip to content
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
4 changes: 2 additions & 2 deletions src/items/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ GenericParams -> `<` ( GenericParam (`,` GenericParam)* `,`? )? `>`

GenericParam -> OuterAttribute* ( LifetimeParam | TypeParam | ConstParam )

LifetimeParam -> Lifetime ( `:` LifetimeBounds )?
LifetimeParam -> Lifetime ( `:` LifetimeBounds? )?

TypeParam -> IDENTIFIER ( `:` Bounds? )? ( `=` Type )?

Expand Down Expand Up @@ -234,7 +234,7 @@ WhereClauseItem ->
LifetimeWhereClauseItem
| TypeBoundWhereClauseItem

LifetimeWhereClauseItem -> Lifetime `:` LifetimeBounds
LifetimeWhereClauseItem -> Lifetime `:` LifetimeBounds?

TypeBoundWhereClauseItem -> ForLifetimes? Type `:` Bounds?
```
Expand Down
2 changes: 1 addition & 1 deletion src/items/type-aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ r[items.type]
r[items.type.syntax]
```grammar,items
TypeAlias ->
`type` IDENTIFIER GenericParams? ( `:` Bounds )?
`type` IDENTIFIER GenericParams? ( `:` Bounds? )?
WhereClause?
( `=` Type WhereClause?)? `;`
```
Expand Down
2 changes: 1 addition & 1 deletion src/paths.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ GenericArgsBinding ->
TypePathSegment `=` Type

GenericArgsBounds ->
TypePathSegment `:` Bounds
TypePathSegment `:` Bounds?
```

r[paths.expr.intro]
Expand Down
8 changes: 6 additions & 2 deletions src/types/impl-trait.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ r[type.impl-trait]

r[type.impl-trait.syntax]
```grammar,types
ImplTraitType -> `impl` Bounds
ImplTraitType -> `impl` Bounds?

ImplTraitTypeOneBound -> `impl` TraitBound
ImplTraitTypeOneBound -> `impl` TraitBound?
```

r[type.impl-trait.intro]
Expand All @@ -23,6 +23,10 @@ fn foo(arg: impl Trait) {
fn bar() -> impl Trait {
}
```

r[type.impl-trait.bounds]
There must be at least one trait bound, no more than one `use<..>` bound, and no more than one opt-out bound (e.g., `?Sized`).

r[type.impl-trait.param]
## Anonymous type parameters

Expand Down
20 changes: 11 additions & 9 deletions src/types/trait-object.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ r[type.trait-object]

r[type.trait-object.syntax]
```grammar,types
TraitObjectType -> `dyn`? Bounds
TraitObjectType -> Bounds[^bare-2021] | `dyn`[^dyn-2018] Bounds?

TraitObjectTypeOneBound -> `dyn`? TraitBound
TraitObjectTypeOneBound -> TraitBound[^bare-2021] | `dyn`[^dyn-2018] TraitBound?
```

[^bare-2021]: See [type.trait-object.syntax-edition2021].
[^dyn-2018]: See [type.trait-object.syntax-edition2018].

r[type.trait-object.intro]
A *trait object* is an opaque value of another type that implements a set of traits. The set of traits is made up of a [dyn compatible] *base trait* plus any number of [auto traits].

r[type.trait-object.impls]
Trait objects implement the base trait, its auto traits, and any [supertraits] of the base trait.

r[type.trait-object.name]
Trait objects are written as the keyword `dyn` followed by a set of trait bounds, but with the following restrictions on the trait bounds.

r[type.trait-object.constraint]
There may not be more than one non-auto trait, no more than one lifetime, and opt-out bounds (e.g. `?Sized`) are not allowed. Furthermore, paths to traits may be parenthesized.
r[type.trait-object.bounds]
There must be at least one trait bound, there may not be more than one non-auto trait, no more than one lifetime, and opt-out bounds (e.g., `?Sized`) and `use<..>` bounds are not allowed.

For example, given a trait `Trait`, the following are all trait objects:

Expand All @@ -33,11 +33,13 @@ For example, given a trait `Trait`, the following are all trait objects:

r[type.trait-object.syntax-edition2021]
> [!EDITION-2021]
> Before the 2021 edition, the `dyn` keyword may be omitted.
> Before the 2021 edition, the `dyn` keyword may be omitted. In the 2021 edition and beyond, the `dyn` keyword is required semantically.

r[type.trait-object.syntax-edition2018]
> [!EDITION-2018]
> In the 2015 edition, if the first bound of the trait object is a path that starts with `::`, then the `dyn` will be treated as a part of the path. The first path can be put in parenthesis to get around this. As such, if you want a trait object with the trait `::your_module::Trait`, you should write it as `dyn (::your_module::Trait)`.
> In the 2015 edition, `dyn` must be followed by [PathIdentSegment], [LIFETIME_TOKEN], `for`, `(` or `?` to be interpreted as a keyword instead of a regular identifier.
>
> Most notably, `dyn`, `dyn::T` and `dyn<T>` will all be treated as type paths. As such, if you want a trait object type with the trait `::module::Trait`, you need to put the path in parentheses and write it as `dyn (::module::Trait)`.
>
> Beginning in the 2018 edition, `dyn` is a true keyword and is not allowed in paths, so the parentheses are not necessary.

Expand Down
Loading