You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We want to reserve a bunch of keywords in the 2018 edition. There's a full list of potential keywords, but for now I'll probably just reserve async, await, and catch.
For edition hygiene reasons this will be done entirely at the lexer level. Keywords in Rust are all lexed as identifiers, however you can have "raw identifiers" which let you create idents treated explicitly as idents. We overload this, so that if the lexer comes across the identifier "async" on Rust 2015, it lexes it as if it were r#async. We may want to fix it up in the pretty printer as well.
An alternate fix is to have a second flag on Ident, which marks whether or not it's allowed to form a keyword. This has the additional benefit of being easier to work with for promoting contextual keywords to full keywords.
Ah, catch is currently implemented in an unstable form as do catch. We can change this whenever we like so that it doesn't work for the 2015 epoch and in 2018 uses a non-contextual catch keyword.
Because I picked the two keywords I knew we definitely wanted 😄 (most of the others are under discussion or otherwise iffy).
I wasn't aware we were fine with them as contextual keywords -- I thought we wanted to epochify anything that we may need as a keyword in the next epoch.
Personally I'd rather add things as full keywords. But thinking about it I guess it would be nice if Rust 2015 got async/await as well.
However, AFAICT await will have to be a real keyword? Or it will be prone to the same issue we have with catch (which causes do catch)? And if await is going to be a 2018-only keyword it seems like the entire feature should just be 2018-only, in which case, why not make async a full keyword.
Yes, this ^. All the way. I think we should make switching to Rust 2018 as enticing as possible, and reduce technical debt if we can. So I'm 👍 for no dyn in edition 2015.
On async: @rpjohnst's pre-RFC has async { .. } blocks; and so this would conflict with struct async { .. } [..] async { .. } wherefore I think async needs to be a real keyword so that we can future proof things.
On catch, the keyword reservation does not seem settled, but whatever we go with (try, catch, trap, .. ) it should be a real keyword for the same problem that async blocks would have.
@nikomatsakis
I think we can visit all idents in AST as soon as NodeIds are assigned and it will be good enough.
This visiting would include right sides of macro definitions which are possibly never expanded in the current crate, but will start generating errors in other crates once the edition of this crate is bumped.
They would be visited as token streams because we don't know anything more about them. Left sides don't need to be checked as you've mentioned above.
There can be false positives in corner cases, e.g. left sides of nested macros defined inside right side of a macro. Regarding the validate_expr example, I'm not even sure it would be a false positive - it certainly wouldn't hurt to rename try into something else in it, in case validate_expr stops dropping arguments.
Does anyone have any idea what work remains to be done here?
We are now linting for the use of 2018 keywords in Rust 2015, for example, at least afaik. Based on the code I see four keywords, and all of them appear to have at least rudimentary tests:
Activity
Manishearth commentedon Apr 3, 2018
An alternate fix is to have a second flag on
Ident, which marks whether or not it's allowed to form a keyword. This has the additional benefit of being easier to work with for promoting contextual keywords to full keywords.Manishearth commentedon Apr 3, 2018
Actually, not doing
catchyet, it's contextual.Manishearth commentedon Apr 3, 2018
Ah,
catchis currently implemented in an unstable form asdo catch. We can change this whenever we like so that it doesn't work for the 2015 epoch and in 2018 uses a non-contextual catch keyword.[-]Implement edition-gated identifiers[/-][+]Implement edition-gated keywords[/+]Manishearth commentedon Apr 3, 2018
#49611
cramertj commentedon Apr 3, 2018
Why do
asyncandawaitneed to be non-contexutal keywords? AFAIK at leastasynccould be added backwards-compatibly as a contextual keyword.Manishearth commentedon Apr 3, 2018
Because I picked the two keywords I knew we definitely wanted 😄 (most of the others are under discussion or otherwise iffy).
I wasn't aware we were fine with them as contextual keywords -- I thought we wanted to epochify anything that we may need as a keyword in the next epoch.
Personally I'd rather add things as full keywords. But thinking about it I guess it would be nice if Rust 2015 got async/await as well.
However, AFAICT await will have to be a real keyword? Or it will be prone to the same issue we have with
catch(which causesdo catch)? And ifawaitis going to be a 2018-only keyword it seems like the entire feature should just be 2018-only, in which case, why not make async a full keyword.idk 😄
cramertj commentedon Apr 3, 2018
Because I have preexisting modules named
async😛 lolManishearth commentedon Apr 3, 2018
r#asyncall the way 😛Manishearth commentedon Apr 3, 2018
@nikomatsakis thoughts on what we should be doing here?
As mentioned in Gitter, we can do this for
dynas well -- nodynat all in 2015, anddynbecomes a full keyword in 2018. I kinda prefer that.cc @Centril
Centril commentedon Apr 3, 2018
@Manishearth
Yes, this ^. All the way. I think we should make switching to Rust 2018 as enticing as possible, and reduce technical debt if we can. So I'm 👍 for no
dynin edition 2015.On
async: @rpjohnst's pre-RFC hasasync { .. }blocks; and so this would conflict withstruct async { .. } [..] async { .. }wherefore I thinkasyncneeds to be a real keyword so that we can future proof things.On
catch, the keyword reservation does not seem settled, but whatever we go with (try,catch,trap, .. ) it should be a real keyword for the same problem thatasyncblocks would have.On
awaitI have no idea.13 remaining items
nikomatsakis commentedon May 23, 2018
(Note: in discussion today, we decided this wasn't a preview blocker per se, though it is an edition blocker.)
petrochenkov commentedon May 23, 2018
@nikomatsakis
I think we can visit all idents in AST as soon as NodeIds are assigned and it will be good enough.
This visiting would include right sides of macro definitions which are possibly never expanded in the current crate, but will start generating errors in other crates once the edition of this crate is bumped.
They would be visited as token streams because we don't know anything more about them. Left sides don't need to be checked as you've mentioned above.
There can be false positives in corner cases, e.g. left sides of nested macros defined inside right side of a macro. Regarding the
validate_exprexample, I'm not even sure it would be a false positive - it certainly wouldn't hurt to renametryinto something else in it, in casevalidate_exprstops dropping arguments.scottmcm commentedon Jul 25, 2018
FWIW,
tryis made an edition keyword by PR #52602.nikomatsakis commentedon Oct 4, 2018
Does anyone have any idea what work remains to be done here?
We are now linting for the use of 2018 keywords in Rust 2015, for example, at least afaik. Based on the code I see four keywords, and all of them appear to have at least rudimentary tests:
async(test)dyn(test)try(test as ident, test as macro)await(migrate tor#awaitin 2105, error in 2018, non-error in 2018 with feature gate)So maybe we can close this?
Centril commentedon Oct 4, 2018
Yes I think we can close this; I filed #54774 for improved diagnostics, but that is tracked separately.