Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edition 2021 and beyond #2966

Closed

Conversation

nikomatsakis
Copy link
Contributor

@nikomatsakis nikomatsakis commented Jul 30, 2020

This RFC proposes revised rules and plans for editions:

  • Announce plans for a Rust 2021 Edition, and for a regular cadence of editions every 3 years thereafter.
    • We will roll out an edition regardless of whether there are breaking changes.
  • Unlike Rust 2018, we will avoid using editions as a "deadline" to tie together high-priority projects.
    • Instead, we embrace the train model, but editions are effectively a "somewhat bigger release", giving us an opportunity to give an overview of all the work that has landed over the previous three years.
  • We specify a cadence for Edition lints.
    • "Edition idiom" lints for Edition N will warn for editions before N, and become "deny by default" in Edition N.
    • Since it would be disruptive to introduce deny-by-default lints for Rust 2018 now, the Rust 2018 lints are repurposed into Rust 2021 Edition lints.
  • We specify a policy on reserving keywords and other prospective changes.
    • In short, reserving keywords is allowed only as part of an active project group.

Co-authored with @steveklabnik.

Rendered view

Pending edits

  • Clarify the lint policy (context).
  • Clarify that changing edition is not considered a "major semver" change except insofar as it implies that a newer version of rustc is needed. (context)

Co-authored-by: Steve Klabnik <steve@steveklabnik.com>

Small tweaks to the 2021 edition RFC

add a section with core concepts of an edition
@nikomatsakis nikomatsakis added the T-core Relevant to the core team, which will review and decide on the RFC. label Jul 30, 2020
@Lokathor

This comment has been minimized.

@QuietMisdreavus

This comment has been minimized.

@Lokathor

This comment has been minimized.

Copy link

@matu3ba matu3ba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structure looks very good, but the question on macros is not really explained and [bikeshedding/nitpicking] questions not numbered and not reformulated or copied.

text/0000-edition-2021-and-beyond.md Outdated Show resolved Hide resolved
text/0000-edition-2021-and-beyond.md Outdated Show resolved Hide resolved
Copy link

@jrheard jrheard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found a couple small typos :)

text/0000-edition-2021-and-beyond.md Outdated Show resolved Hide resolved
text/0000-edition-2021-and-beyond.md Outdated Show resolved Hide resolved
@Aloso
Copy link

Aloso commented Jul 30, 2020

When Rust 2018 was released, there was an "extended beta" (internals thread), so the features could be tested more thoroughly before releasing them on stable.

I'd like to know if something like this is planned in future editions as well; I think the RFC should explain the process how new editions are implemented and released.


We use this section to try and convey the story that average users will need to understand.

## What is a Rust edition?
Copy link
Member

@AlexEne AlexEne Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me the paragraphs here don't really answer the question "What is a Rust edition?".
It is briefly touched in the last pragraph but not in detail. So it is just that year's version that allows us to introduce features that would otherwise be impossible (so are these breaking changes I assume or just big features e.g. should async go here? -- this isn't clear).

Then the question remains, if there are no breaking changes, why do we want a new edition? Wouldn't that cause confusion? For example, do we need to still set the edition number in my cargo.toml if there are 0 breaking changes?
Would crates that don't change the edition number miss on potential improvements that are tagged with an edition 201X in that case (in the 0 breakage case)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that you can always know to set your edition value to 2015+3x and you'll get a valid number.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could should probably start here with: "A rust edition is ..." and maybe also mention what it is not, and the other paragraphs regarding name, cadence and opportunity to look back and celebrate can follow.

Copy link
Member

@AlexEne AlexEne Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess my main worry (besides the lack of a definition) is the dual meaning of an edition, it can be a breaking change or can be a non-breaking changes at the same time (depending on the year).

This is the main reason that makes me ask all the questions above and I am sure that other users of rust may have the same dificulties.

I am more of a fan where things have a clean meaning in all situations:

  • a compiler update is always a non-braking change (at least not intentional)
  • rust editions are breaking changes that give you some help in porting and also make it worth to invest the effort due to new features + compatibility + auto-changes from tools + etc.

Copy link
Contributor

@pickfire pickfire Dec 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking at the patch and noticed that the change is just changing from 2018 to 2021. I wonder what is the point of editions if there are no breaking change? Why would one change from 2018 to 2021 if it is the same thing? If it is the same thing then most likely some crates will be 2018 and some will be 2021, will that slow down the compile time? But from the RFC looks like we have breaking change.

I posted this in the PR which I should ask here. I am thinking that if there are no breaking change, means that people may not change to the newer edition since it is the same. Questions

  • Why would one change the edition to a newer one which is the same?
  • Is it necessary to have a new edition which only breaking change is changing 2018 to 2021?
  • Will it slow down the compilation time?

@fintelia
Copy link

This RFC seems to be imagining a rough timeline for when during the year the next edition would be released, but doesn't actually come out and say so.

Marketing-wise I'd argue that future editions should come out as close to the start of the year as possible. It might feel like a silly detail, but once the calendar year rolls over it is easy to think the edition is already a year old (even for Rust 2018 which came out only weeks before 2019 started...) There is a reason that car for a given model year come out before the calendar year even starts.

In other words, it would be better to have Rust 2022 with a January release rather than Rust 2021 with a November/December release.

@Lokathor
Copy link
Contributor

I think moving the the release to the start of 2021 would be difficult, and changing the year to 2022 would also be ill advised, but moving the release to one release sooner in 2021 seems possible, and aiming editions 2024+ for the start of the year would absolutely be better.

@nikomatsakis
Copy link
Contributor Author

Timing is a good question. I think that having releases very early in the year is a bad idea -- it's hard to coordinate work around December. Shooting for spring or summer is probably ideal. I suspect we want to give ourselves a bit of leeway -- i.e., have a projected date for the edition and "size" the work to that date, along with some milestones along the way, but it's also ok to slip if it comes to that (though of course it doesn't look great).

I think one of the key things that the RFC alludes to but which can't really be written in an RFC per se is that we have to get better at managing the editions. I mentioned created creating a group dedicated to managing the Edition, I think this is crucial, but also we have to develop some "project management best practices" for that group. That will come with time I guess.

@nikomatsakis
Copy link
Contributor Author

It's also true that 2021 may be distinct from 2024, i.e., we'll be able to move earlier and earlier in the year. =)

@steveklabnik
Copy link
Member

Timing is a good question; for me, I saw this RFC as trying to set out broad policy, and then it's up to the teams to implement said policy. I'm not sure if the timing, other than being in a certain year, is worth encoding into policy yet. That being said, we do have some data that planning so late in the year makes things likely to turn into a crunch, so it's probably a good idea to try and shoot for the middle of the year, so maybe that should just be policy.

The primary drawbacks of doing editions at all are as follows:

* Coordinating an edition release is a stressor on the organization, as we have to coordinate the transition tooling, documentation, and other changes. This was particularly true in the original formulation of the editions, which put a heavy emphasis on the "feature-driven" nature of the 2018 Edition (i.e., the goal was to release new and exciting features, not to look back on work that had already been completed).
* Transitioning to a new edition, even if optional, is an ask for our users. Some production users expressed frustration at having to spend the time upgading their crates to the new edition. Even with tooling, the task requires time and effort to coordinate. At this stage in Rust's life, "production use" often implies "commercial use," and time and effort means "money" to them. Asking too much could harm Rust's commercial prospects, with all of the secondary impacts that has on the not-for-profit ecosystem as well.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some production users expressed frustration at having to spend the time upgading their crates > to the new edition

For me, this is not about upgrading our crates to a new edition, but this frustration is also probably about upgrading dependencies (e.g. random projects where we could raise a PR but it can also be ignored for a very long time) to a new edition (especially if that edition has 0 breaking changes). I think this is a drawback in my view that's not acurately captured in the text.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would there be a need to upgrade dependencies? Dependencies being on an older edition doesn't prevent crates that depend on those crates from using a newer edition (and vice-versa).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's the entire point of the system.

Copy link
Member

@AlexEne AlexEne Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well are there improvements that are edition specific (even with 0 breaking change)? That's not at all clear.

Before this, 0 breaking change and a compiler upgrade means that all of my dependencies get compiled with the new compiler and get all the benefits of that, e.g. some optimizations are better generated

This edition system with the text in this rfc makes no guarantee that any improvements that are not breaking changes apply to all editions.

This likely is tied to the lack of a clear definition of what an edition is that I highlighted in another comment. Once that's clarified, these worries may not exist

Copy link
Member

@AlexEne AlexEne Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put it another way, can things like adding an option for -ffast-math or some equivalent option discussed here be edition-specific? If the math library library we depend on doesn't change it's edition, how can i enable those (let's say it's a feature available from certain editions forward).

Is this a case that could happen under the edition system? (it would have no breaking change, e.g. it adds a compiler feature flag).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think as someone that's an in production user of Rust, I would rather have stronger guarantees on what can change in an edition and what can't be an edition change, just so I don't have to chase my dependencies to upgrade editions to get the benefits that today i'd get with a compiler upgrade.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have to admit I don't really understand the question. The general goal of the system is that you don't care, or even know what edition your dependencies are using. That is basically not relevant to you. What is relevant is what version of rustc they require, but that is true whether or not a new edition has been published (i.e., we may stabilize some new feature in rustc verson 1.X, and if they use it, then you must also use a rustc version >= 1.X). There is some talk of adding "minimum rustc version" metadata in Cargo.toml, but it's an orthogonal concern.

(Caveat: there could be some features that are difficult to access without using the new edition. For example, if a crate uses async fn, and you wish to interact with it by writing other async fn, you both have to be using Rust 2018 to get access to the async keyword. These features are quite unusual.)

Copy link
Member

@AlexEne AlexEne Jul 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to refresh to get the new longer answer, and it makes sense from the funcionality perspective now.

There is something that I still don't understand:
Let's say 2021 has no breaking changes, what is the difference between using that edition flag or the 2018 edition under the same let's say rustc 1.90 version ? that's not clear at all to me what the difference between using the two editions in this scenario would be (given all features should be accessible in both editions as there are no breaking changes).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will have no impact on the supported features, but possibly on the supported Rust version.

For example, if you change edition = "2021" to edition = "2024", your crate will fail to compile on Rust versions that don't support Rust 2024. However, if you already use features that were introduced after Rust 2024 was released, there's no problem.

Copy link
Member

@AlexEne AlexEne Jul 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it's like a super basic way of saying: from now on, my code wants this toolchain version that allows 2021 as a rust edition, in the case where 2021 edition has no breaking changes compared to 2018 edition. (So it is kind of a min-compiler version that you can set every 3 years :) )

In addition to that, @steveklabnik's presentation finally clarified what an edition can change (stuff that comes before MIR). I think that's a kind of important thing to mention, as "shallow changes" mentioned somewhere else in the doc isn't that clear on the impact of an edition-related change vs a normal feature change (e.g. enabling some more optimizations with some flag).

This is kind of needed as now we can have editions with 0 breaking changes, so one may wonder what type of changes are considered edition changes and what type of changes are just normal things that everyone gets, regardless of the edition. As I said, Steve's presentation clarified that but I absolutely didn't get this by just reading the RFC :D.

@nikomatsakis
Copy link
Contributor Author

I too am inclined to leave "timing" for the Edition Group to decide.

@newpavlov
Copy link
Contributor

newpavlov commented Jul 30, 2020

One important thing not covered by this RFC is a recommended semver policy for crates regarding edition updates. Imagine we have a 1.0 crate on 2018 edition, should maintainers release 2.0 after update to 2021 or not? Ideally we would get MSRV-dependent dependency version resolution as suggested in RFC 2495, so they would be able to release 1.1 version without breaking builds on older toolchains, but unfortunately the feature hasn't seen much progress and version resolution changes are not even part of the initial version.

@cuviper
Copy link
Member

cuviper commented Jul 30, 2020

@newpavlov I think MSRV is somewhat orthogonal, because old editions also get new features with newer Rust. I can still use str::strip_prefix in a 2015 crate, as long as Rust is at least 1.45. The edition is just another feature in that sense.

@nikomatsakis
Copy link
Contributor Author

I've added a "Pending Edits" section to the top describing edits that I or @steveklabnik plan to make at some point. I'll add comments once I'm sure I understand what's being requested. =)

@newpavlov
Copy link
Contributor

newpavlov commented Jul 30, 2020

@cuviper
But you will not be able to compile a dependency migrated to 2021 edition using Rust 1.45. So if you are staying on an older toolchain, it would break your build, so such change technically should be considered a breaking one, thus mandating 2.0 release. In other words, edition update is an implicit MSRV bump and there certainly will be pressure to update editions regardless if crate uses new features or not, so in the light of mandatory edition releases to prevent major version inflation or breaking user builds a proper MSRV-dependent version resolution is a must have in my opinion.

Assuming we get it, I think recommended policy should be something like "for post-1.0 crates edition update should be done as part of minor release".

@cuviper
Copy link
Member

cuviper commented Jul 30, 2020

In other words, edition update is an implicit MSRV bump and there certainly will be pressure to update editions regardless if crate uses new features or not,

My point is that an edition update is using a new feature, in and of itself. It should be fine to push back on pressure to update if you need to maintain MSRV.

And if your dependencies don't also cover your MSRV, you have a problem regardless of editions.

@Lokathor
Copy link
Contributor

In the sense that updating minimum rust stops the crate from building on compiler 1.X, they should be considered breaking until cargo is smart enough to not update a crate past your current compiler version.

I think policy should be that edition might determine a minimum rust version for you, and otherwise it should not be a factor at all. Example: if a crate is minimum version 1.45 already, then changing from 2015 to 2018 isn't externally visible at all, and has no semver effect on its own.

@durka
Copy link
Contributor

durka commented Jul 31, 2020

I would advocate for the "skipping editions" or more preferably "feature-based editions" model. I think having a cadence for editions will make breaking changes more common[1]. If something is going to be an edition-level change, then you can always use the refrain "OK, let's just wait for the next edition and we can do it anyway". Much better to do an edition only when necessary and when we can reasonably generate buzz about it.

"But if we accept this, that'll be the only reason to have an edition, and it doesn't seem worth it."

I think this is exactly the consideration that should be made for large RFCs.

[1]: I know the argument is that they aren't really breaking changes because of the opt-in Cargo.toml attribute and automated migration tooling. These are indeed great features of the Rust ecosystem. But it still means that Rust code looks different and means something different to humans, which is a form of breakage.

Copy link

@Aelerinya Aelerinya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found small typos.

text/0000-edition-2021-and-beyond.md Outdated Show resolved Hide resolved
text/0000-edition-2021-and-beyond.md Outdated Show resolved Hide resolved
@steveklabnik
Copy link
Member

Hey everyone,

So, Niko has pushed a few updates to the RFC. We’re making a few changes, and we think this will land things in a good place. We’re going to do a 2021 edition, and do it on the three year pace, but cut some scope that will hopefully help with the “confusion” concern. Namely, the edition guide will be cut back to purely the migration changes. We’ll still talk about major features in the related blog post, but clearly separating them from the specific migrations. With those changes in place, we intend to move to FCP in the near future; please review the last few commits. Thank you!

@SimonSapin
Copy link
Contributor

These changes look good. Thanks!

Having retrospective blog posts on the same cadence and schedule as compiler mode releases sounds ok to me, as long as we’re careful in the messaging to not call "part of the 20XX edition" language features that don’t require a changing the compiler mode.

(I’m still not thrilled about using the same term for two different concepts, and still don’t understand the apparent desire to actively keep it that way, but oh well.)


This part of the RFC is unchanged:

We will roll out an edition regardless of whether there are breaking changes.

Does that also imply "regardless of whether there are idiom lint changes"? Would we possibly introduce for example edition = "2024" that behaves exactly the same as edition = "2021"?

@Mark-Simulacrum
Copy link
Member

I think this RFC is ready for core team at large to review it; I have read through it and feel it matches my expectations for our planning going forward. I also think that it is feasible for us to adjust very concrete things as we go; for example @SimonSapin's question around whether we would issue an entirely empty edition flag or omit it seems like something that could be settled if we ever have such a situation (I do not personally expect it in the near future).

@rfcbot fcp merge

@rfcbot
Copy link
Collaborator

rfcbot commented Sep 23, 2020

Team member @Mark-Simulacrum has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. labels Sep 23, 2020
@Mark-Simulacrum
Copy link
Member

@rfcbot concern need-full-checkboxes

I am registering a preemptive concern to avoid this going into FCP before everyone on core has a chance to review (unlike typical rules which are all - 2 people).

@nikomatsakis
Copy link
Contributor Author

I'd be happy to move the "what if there is a no-op edition" to be addressed if/when it occurs.


## "Migrations" in an edition vs "idiom lints"

When we release a new edition, it comes together with a certain set of "migrations". Migrations are the "breaking changes" introduced by the edition, except of course that since editions are opt-in, no code actually breaks. For example, if we introduce a new keyword, you will have to rename variables or functions using the old keyword, or else use Rust's `r#keyword` feature (which allows you to use a keyword as a regular variable/function/type name). As mentioned before, the edition comes with tooling that will make these changes for you, though sometimes you will want to cleanup the resulting code afterwards.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A thing worth highlighting somehow:

  • Migration lints take code that compiles on edition X and turn it into code that compiles on edition X AND X+1
  • Idiom lints take code that compiles on edition X+1 and turn it into code that is idiomatic for edition X+1 (but may no longer compile on edition X)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would "but may no longer compile on edition X" work? Code shouldn't suddenly "no longer compile on <specification from the past>"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to read that twice too. I think what @Manishearth meant is that -- once you've applied the idiom lint, the resulting code (in the new edition) may not compile in the old edition anymore.

To be honest, I had forgotten that migrations are supposed to target the "intersection" of editions, so this is perhaps a good addition -- but I'm not sure if it's always true. I remember thinking that we might have to have cases were the migration required you to use the new edition. But I guess we avoided those for the module transition? I'd be ok writing the above as the general rules -- kind of a "unless otherwise stated" sort of thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikomatsakis The migration/idiom split is deliberately designed to deal with this specific problem. Idiom lints do not necessarily produce code that does not compile on older editions, but typically do. That's more central to their working than "will become on by default in the next edition" actually.

how would "but may no longer compile on edition X" work? Code shouldn't suddenly "no longer compile on "

I'm talking about the migration present within those lints.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reasoning here is that it is not always possible to migrate wholesale, so the edition lints migrate it to be compatible with the new edition (while still compiling on the old one so that you can perform any manual fixes). The idiom lints finish off any parts of the migration and apply potentially incompatible changes that make the code more idiomatic (but are not necessary to make the code compile).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is sounding quite familiar. I will add some text to that effect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, I believe that idiom lints can also be used to change the default severity from warning (older editions) to error (newer editions) correct? I'll have to review the code, but I'm pretty sure that's something we also want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I pushed some changes -- @Manishearth please take a look and see if this sounds right to you.

Co-authored-by: Philipp Krones <hello@philkrones.com>
Copy link
Member

@ashleygwilliams ashleygwilliams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first half reviewed. have to run to a meeting but will review the second half once im' out of it.

tl;dr: at least so far, this RFC does a good job of setting up a framework for talking about elements of an edition. where i think it could improve is as a design document it doesn't call out where those elements may be in conflict and create a strategy for resolving those conflicts. i think adding that would be a great improvement to this RFC and make running editions in the future much more straightforward.

- Unlike Rust 2018, we will avoid using editions as a "deadline" to tie together high-priority projects.
- Instead, we embrace the train model, but editions are effectively a "somewhat bigger release", giving us an opportunity to give an overview of all the work that has landed over the previous three years.
- We specify a cadence for Edition lints.
- "Edition idiom" lints for Edition N will warn for editions before N, and become "deny by default" in Edition N.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i could imagine a universe where idiom edition 20XX and idiom 20XX+6 conflict with each other. avoiding this is something i could imagine everyone is motivated by, but not 100% possible. tooling wise this could be really confusing, as we prepare the lints we should probably add a step to audit for this and consider retiring old lints?

- "Edition idiom" lints for Edition N will warn for editions before N, and become "deny by default" in Edition N.
- Since it would be disruptive to introduce deny-by-default lints for Rust 2018 now, the Rust 2018 lints are repurposed into Rust 2021 Edition lints.
- We specify a policy on reserving keywords and other prospective changes.
- In short, reserving keywords is allowed only as part of an active project group.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bullet point feels like it comes out of nowhere and needs context. It doesn't seem like a summary of the previous bullets as the "in short" couching statement would suggest.


## Expected nature of editions to come

We believe the Rust 2018 was somewhat exceptional in that it introduced changes to the module system that affected virtually every crate, even if those changes were almost completely automated. We expect that the changes introduced by most editions will be much more modest and discrete, more analogous to `async fn` (which simply introduced the `async` keyword), or the changes proposed by [RFC 2229] (which tweaks the way that closure captures work to make them more precise).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"expect", while I also expect this, we may want to explain why we expect this and how we intend to maintain this expectation over time as the "we" changes.


We believe the Rust 2018 was somewhat exceptional in that it introduced changes to the module system that affected virtually every crate, even if those changes were almost completely automated. We expect that the changes introduced by most editions will be much more modest and discrete, more analogous to `async fn` (which simply introduced the `async` keyword), or the changes proposed by [RFC 2229] (which tweaks the way that closure captures work to make them more precise).

The "size" of changes to expect is important, because they help inform the best way to ship editions. Since we expect most changes to be relatively small, we would like to design a system that allows us to judge those changes individually, without having to justify an edition by having a large number of changes combined together. Moreover, we'd like to have editions happening on a predictable cadence, so that we can take that cadence into account when designing and implementing features (i.e., so that we can try to tackle changes that may require migrations earlier, to give plenty of time).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think there are 2 very important points here that deserve their own sections:

  1. changes should be judged individually
  2. editions should happen on a regular cadence

they are related (as suggested here) but i think there are several ways in which they may be at odds with each other. for example: if we judge the changes individually, by what mechanism do we decide that the edition is not achievable or "too big" or too many changes, or too many similar/conflicting changes that are hard to explain.


## What is a Rust edition?

Every three years, we introduce a new Rust Edition. These editions are named after the year in which they occur, like Rust 2015 or Rust 2018. Each crate specifies the Rust edition that it requires in its `Cargo.toml` file via a setting like `edition = "2018"`. The purpose of editions is to give us a chance to introduce "opt-in" changes like new keywords that would otherwise have the potential to break existing code.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think a tl;dr here that says "Edition are how Rust introduces changes to the language that may be breaking in a non breaking way."


## How do I upgrade between editions?

Upgrading between editions is meant to be easy. The general rule is, if your code compiles without warnings, you should be able to opt into the new edition, and your code will compile.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/easy/low effort


Upgrading between editions is meant to be easy. The general rule is, if your code compiles without warnings, you should be able to opt into the new edition, and your code will compile.

Along with each edition, we also release support for it in a tool called `rustfix`, which will automatically migrate your code from the old edition to the new edition, preserving semantics along the way. You may have to do a bit of cleanup after the tool runs, but it shouldn't be much.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"You may have to do a bit of cleanup after the tool runs, but it shouldn't be much."

This feels like it doesn't match the language of the rest of the RFC, i might reword

"It is not possible to automate all changes. As a result, some manual changes may be required in addition to the tool. The goal is to keep these as minimal as possible."

questions:

  • if a proposal for an edition change has 2 options, would we be motivated to pick the change that has the more automatable migration?


When we release a new edition, it comes together with a certain set of "migrations". Migrations are the "breaking changes" introduced by the edition, except of course that since editions are opt-in, no code actually breaks. For example, if we introduce a new keyword, you will have to rename variables or functions using the old keyword, or else use Rust's `r#keyword` feature (which allows you to use a keyword as a regular variable/function/type name). As mentioned before, the edition comes with tooling that will make these changes for you, though sometimes you will want to cleanup the resulting code afterwards.

Migrations target the "intersection" of editions. That is, a migration will convert code in Edition N into code that compiles in **both** Edition N and Edition N+1. This permits migrations to be applied in a piecemeal fashion rather than forcing all migrations to occur at once.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about breaking changes, that don't have an intersection, but are still possible to be automatically "migrated"?

@nikomatsakis
Copy link
Contributor Author

Hello all,

In light some recent core team conversation, I've decided to withdraw this RFC. We still intend to do a 2021 edition, but there have been some good suggestions for better ways to structure the RFC. I think the most likely thing is that we'll create a relatively simple RFC that proposes a 2021 Edition specifically and then revisit the question of writing out more general rules.

One specific thing that we were talking is that the current RFC blends some details that aren't really the core team's job (e.g., keyword reservation policy) along with other things that are (overall product direction / end-user experience). We should retool the RFC to focus on the latter, and let the appropriate other teams (e.g., @rust-lang/lang for keywords) decide policy on the former.

@rfcbot rfcbot removed proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. labels Dec 14, 2020
@pravic
Copy link

pravic commented Jan 8, 2021

https://doc.rust-lang.org/nightly/edition-guide/rust-next/index.html since rust-lang/rust#79576 has been merged, you probably want to adjust the edition guide as well.

@trevyn
Copy link

trevyn commented Feb 19, 2021

(For reference, #3085 is the new 2021 Edition RFC)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-core Relevant to the core team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet