Skip to content

Fix grammar rules containing or pertaining to bounds#2257

Open
fmease wants to merge 2 commits intorust-lang:masterfrom
fmease:fix-bounds-grammars
Open

Fix grammar rules containing or pertaining to bounds#2257
fmease wants to merge 2 commits intorust-lang:masterfrom
fmease:fix-bounds-grammars

Conversation

@fmease
Copy link
Copy Markdown
Member

@fmease fmease commented May 5, 2026

At least since PR rust-lang/rust#39158 (2017) bounds are intentionally always optional after "bound heralds" (:, impl, dyn). However, the Reference didn't reflect this fact everywhere. This PR rectifies this.

For example reference@master considers the following snippets to be syntactically ill-formed which directly contradicts rustc:

Furthermore, the edition disclaimer for trait object types is incomplete / imprecise / inaccurate:

It states that token sequence dyn:: will be interpreted as the start of a path in Rust 2015 which is correct in isolation but far from complete in context. Per argumentum e contrario, it would wrongly imply that in Rust 2015 the following snippets all contain (bare) trait object types:

  • type T = dyn;, type T = (dyn);, type T = [dyn];
  • type T = dyn<>;, type T = dyn<()>;, type T = dyn<<T>::S>;

To address this, I've changed the note to use an exhaustive and positive listing of tokens. The follow set is {PathIdentSegment, LIFETIME_OR_LABEL, for, (, ?} as per rustc's can_begin_dyn_bound_in_edition_2015.

@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label May 5, 2026
Comment thread src/types/trait-object.md Outdated
r[type.trait-object.syntax]
```grammar,types
TraitObjectType -> `dyn`? TypeParamBounds
TraitObjectType -> TypeParamBounds | `dyn` TypeParamBounds?
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.

Due to this grammar rule, TypeParamBounds (now: Bounds) must remain non-empty.

View changes since the review

@fmease fmease force-pushed the fix-bounds-grammars branch from 4200b2e to 7b807ac Compare May 5, 2026 10:25
Comment thread src/types/trait-object.md
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

@rustbot

This comment has been minimized.

@fmease fmease force-pushed the fix-bounds-grammars branch from 7b807ac to e8c2309 Compare May 6, 2026 13:38
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 6, 2026

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: The marked PR is awaiting review from a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants