Skip to content
Open
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
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 @@ -68,7 +68,7 @@ GenericArgsBinding ->
IDENTIFIER GenericArgs? `=` Type

GenericArgsBounds ->
IDENTIFIER GenericArgs? `:` Bounds
IDENTIFIER GenericArgs? `:` Bounds?
```

r[paths.expr.intro]
Expand Down
4 changes: 2 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 Down
8 changes: 5 additions & 3 deletions src/types/trait-object.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ r[type.trait-object]

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

TraitObjectTypeOneBound -> `dyn`? TraitBound
TraitObjectTypeOneBound -> TraitBound | `dyn` TraitBound?
```

r[type.trait-object.intro]
Expand Down Expand Up @@ -37,7 +37,9 @@ r[type.trait-object.syntax-edition2021]

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][grammar-PathIdentSegment], [LIFETIME_OR_LABEL][grammar-LIFETIME_OR_LABEL], `for`, `(` or `?` to be interpreted as the start of a trait object type. Otherwise, it will be interpreted as a regular identifier.
Copy link
Copy Markdown
Member Author

@fmease fmease May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I wrote Otherwise, it will be interpreted as a regular identifier and thus as the start of a type path. However the final clause wasn't correct strictly speaking: In Rust 2015 in a type context, dyn that's not followed by one of those tokens could start a TypePath (e.g., dyn, dyn::X), a TraitObjectType (e.g., dyn+, dyn + X) or a MacroInvocation (e.g., dyn!(), dyn::m!()), so I've retracted that statement again.

I don't feel like mentioning TypePath, TraitObjectType & MacroInvocation in this sentence since it can easily become outdated. The consequences should be self-evident anyway.

View changes since the review

>
> Most notably, `dyn`, `dyn::T` and `dyn<T>` will all be treated as type paths. The first path can be put in parenthesis to get around this. As such, if you want a trait object with the trait `::module::Trait`, you should 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