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


#1

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?


#2

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).


#3

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.


#4

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