Skip to content

Rust 2015 type dyn + dyn wrongly rejected by the parser due to "helpful" diagnostic #157565

@fmease

Description

@fmease

In Rust 2015, dyn is only a contextual keyword. It is only meant to be active if it appears in a type context and is followed by a token in the following set: {PathIdentSegment, LIFETIME_OR_LABEL, for, (, ?} as dictated by can_begin_dyn_bound_in_edition_2015 (cc rust-lang/reference#2257) (side note: RFC 2113 doesn't actually define the rules).

Despite that fact, since 1.54 rustc rejects the following Rust 2015 program:

#[cfg(false)]
type X = dyn + dyn;
error: invalid `dyn` keyword
 --> src/lib.rs:2:16
  |
2 | type X = dyn + dyn;
  |                ^^^
  |
  = help: `dyn` is only needed at the start of a trait `+`-separated list
help: remove this keyword
  |
2 - type X = dyn + dyn;
2 + type X = dyn + ;
  |

error: expected identifier, found `;`
 --> src/lib.rs:2:19
  |
2 | type X = dyn + dyn;
  |                   ^ expected identifier

More concretely, rustc erroneously rejects this code since PR #84896 which only meant to improve diagnostics, not alter the stable grammar of Rust.

Note that dyn + dyn can be semantically well-formed, too (assuming this parser bug has been fixed). Consider the following contrived Rust 2015 code:

use std::marker::Sync as dyn;
type Y = dyn + dyn;

Metadata

Metadata

Assignees

Labels

A-dyn-traitArea: trait objects, vtable layoutA-edition-2015Area: The 2015 edition (the first edition)A-parserArea: The lexing & parsing of Rust source code to an ASTC-bugCategory: This is a bug.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.P-lowLow priorityS-has-bisectionStatus: A bisection has been found for this issueT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions