Should we reserve `dyn` as a keyword for the 2018 Edition?


So we’d like to stabilize dyn_trait soonish. The current status quo is, with the feature, you can use stuff like Box<dyn Foo>; i.e. dyn Foo is equivalent to bare Foo for a trait Foo, however we plan to strongly encourage you use dyn.

In its current state, dyn is implemented as a contextual keyword. dyn Foo parses as a trait object in all cases were it should work, except for dyn ::Foo, which gets parsed as the path dyn::Foo instead of the trait object dyn (::Foo). You can explicitly get the trait object by using parentheses.

Fortunately, in the next epoch ::foo will be an antipattern due to the path reforms. Not disallowed, just linted against. So we can continue to have dyn ::Foo parse as a path, since dyn (::Foo) shouldn’t be something we will see anyway.

We’re basically deciding between stabilizing it as a contextual keyword for 2015 and 2018, OR having dyn Trait not work at all on 2015 and work in all cases in 2018 (as dyn becomes a keyword). We have the ability to do “raw identifiers” so that crates on the 2018 epoch can still e.g. interact with APIs on the 2015 epoch that use now-reserved keywords, so both are feasible. But we have to pick.

So far, we have these tradeoffs:

dyn as an edition keyword

  • Cleaner; less technical debt in the parser. As we accumulate contextual keywords their interactions become hairier.
  • We can introduce dyn as a contextual keyword for the 2015 epoch later if we wish, this is forward-compatible
  • This is forward compatible with future syntaxes that interact with dyn, or future extensions to the dyn feature
  • Encourages people to shift editions
  • Probably produces better parser error messages

dyn as a non-gated contextual keyword

  • Diagnostics stay uniform across editions; there is no danger of accidentally telling a 2015 user to use dyn
  • Editions stay closer together; Rust 2018 becomes more of a milestone rather than a different flavor of Rust.
  • No edition-breakage!!111

There’s ongoing discussion about our policy for edition keywords in general, however dyn is a bit special since it’s not a new feature, it’s new, better, syntax for an old feature, so the diagnostics issues (among other things) become relevant.

What do folks think?


Is it an option for dyn to be a contextual keyword in the 2015 Edition and a real keyword in the 2018 Edition? For some reason I was under the impression that’s what we always wanted to do (though now that you’ve asked I’m not sure which option I’d prefer).


It’s an option. I’d prefer not to take it since it complicates edition hygiene issues (how do macros from different editions interact?). It also has most of the downsides of having it as a contextual keyword, so I see it as worse than the other two options.


We discussed this in the lang team meeting today. We settled on the following:

  • when possible, prefer a “true keyword” in the new edition
    • notably, for new features
    • e.g., async, await, try, etc
  • for features that exist on old epoch, use contextual keyword in both
    • hence dyn, union

More detailed minutes available in this paper document