Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upRFC: Evolving Rust through Epochs #2052
Conversation
aturon
added
the
T-core
label
Jul 3, 2017
aturon
self-assigned this
Jul 3, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
People may be interested to review a recent draft from the C++ world, C++ Stability, Velocity, and Deployment Plans, which tries to clarify plans around C++'s evolution and has many similarities with this RFC.
|
People may be interested to review a recent draft from the C++ world, C++ Stability, Velocity, and Deployment Plans, which tries to clarify plans around C++'s evolution and has many similarities with this RFC. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
steveklabnik
Jul 3, 2017
Member
I have long been advocating for a "never Rust 2.0", and I see this RFC as reaffirming our commitment to stability.
I can't tell the future, of course, but for me, this RFC is the nail in the
|
I have long been advocating for a "never Rust 2.0", and I see this RFC as reaffirming our commitment to stability. I can't tell the future, of course, but for me, this RFC is the nail in the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
est31
Jul 3, 2017
Contributor
I came to Rust because it was stable, and value stability greatly. If this RFC means that I don't have to suffer from the new module system but can continue to use the current, magnificent one, I'm a great supporter!
|
I came to Rust because it was stable, and value stability greatly. If this RFC means that I don't have to suffer from the new module system but can continue to use the current, magnificent one, I'm a great supporter! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
steveklabnik
Jul 3, 2017
Member
I don't have to suffer from the new module system but can continue to use the current, magnificent one,
To be clear, there isn't a module system proposal yet
To be clear, there isn't a module system proposal yet |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
cmr
Jul 3, 2017
Member
(amusingly, I was just complaining about the lack of this exact feature and philosophy in the OPLSS chat)
|
(amusingly, I was just complaining about the lack of this exact feature and philosophy in the OPLSS chat) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Jul 3, 2017
Contributor
ATCs,
impl Trait, and specialization all becoming available […] 2018
Be careful what things you put in the same sentence, it could sound like a promise ;)
Be careful what things you put in the same sentence, it could sound like a promise ;) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
cuviper
Jul 3, 2017
Member
Will all newly-stabilized features only go into the current epoch? There could be some new things that would be perfectly fine on the older epochs too. My gut says to only push forward, but I could imagine some cases might be harder to try and isolate their implementations.
Is it a semver-breaking change for a crate to start requiring a new epoch? Bumping rustc requirements at all was controversial in #1619.
Will cargo new always default to the newest epoch right away?
|
Will all newly-stabilized features only go into the current epoch? There could be some new things that would be perfectly fine on the older epochs too. My gut says to only push forward, but I could imagine some cases might be harder to try and isolate their implementations. Is it a semver-breaking change for a crate to start requiring a new epoch? Bumping rustc requirements at all was controversial in #1619. Will |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Ixrec
Jul 3, 2017
Contributor
Rust compilers are expected to support multiple epochs, and a crate dependency graph may involve several different epochs simultaneously. Thus, epochs do not split the ecosystem nor do they break existing code.
existing deprecations may turn into hard errors ... This is the only kind of change a new epoch can make.
the RFC proposes to limit epochal changes to be "superficial", i.e. occurring purely in the early front-end stages of the compiler
That answers every single question and concern I had about epochs in exactly the way I hoped they'd be answered, and even the parts of this RFC that I was not expecting (e.g. epoch previews) make perfect sense. +1000. Let's do this.
Though it might be worth explicitly stating that the pretty graph with green and orange bars is not committing us to actually creating those specific epochs at those specific future dates.
That answers every single question and concern I had about epochs in exactly the way I hoped they'd be answered, and even the parts of this RFC that I was not expecting (e.g. epoch previews) make perfect sense. +1000. Let's do this. Though it might be worth explicitly stating that the pretty graph with green and orange bars is not committing us to actually creating those specific epochs at those specific future dates. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Evidence of @cmr lamenting this missing feature. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Ixrec
Jul 3, 2017
Contributor
@cuviper The cargo question is answered explicitly in the RFC:
cargo new will produce a Cargo.toml with the latest epoch value, including -preview epochs when applicable.
The semver one less explicitly, but I believe it's very strongly implied by this quote that there is no such thing as "requiring" an epoch and merely using a new epoch in your crate won't break any client code:
To be crystal clear: Rust compilers are expected to support multiple epochs, and a crate dependency graph may involve several different epochs simultaneously. Thus, epochs do not split the ecosystem nor do they break existing code.
But it wouldn't hurt to be even more crystal clear and say "there is no such thing as 'requiring' a minimum epoch of client code, only requiring minimum rustc/cargo versions" assuming I am interpreting this right.
|
@cuviper The cargo question is answered explicitly in the RFC:
The semver one less explicitly, but I believe it's very strongly implied by this quote that there is no such thing as "requiring" an epoch and merely using a new epoch in your crate won't break any client code:
But it wouldn't hurt to be even more crystal clear and say "there is no such thing as 'requiring' a minimum epoch of client code, only requiring minimum rustc/cargo versions" assuming I am interpreting this right. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
Will all newly-stabilized features only go into the current epoch? There could be some new things that would be perfectly fine on the older epochs too. My gut says to only push forward, but I could imagine some cases might be harder to try and isolate their implementations.
Ooh, that is a very interesting question that the RFC doesn't address at all. I pretty much agree with both of your sentiments here, and hence suspect we won't have a hard rule, but rather a default tendency. In particular, the benefits of collecting bundles of features together under an umbrella name are decreased somewhat if some of them become available in older epochs.
Is it a semver-breaking change for a crate to start requiring a new epoch? Bumping rustc requirements at all was controversial in #1619.
Another good question. I personally would like to see this issue addressed through LTS releases, which could act as a point of coordination for users wanting to be conservative with their upgrades. I don't think epochs introduce anything particularly new here.
In particular, "requiring" a new epoch means nothing more than requiring a new compiler version, so it reduces to the same question we have today (which we don't have a good answer for yet.)
Will
cargo newalways default to the newest epoch right away?
Yes. Part of the benefit of keeping the rapid release model at the center here is that we should be able to avoid the usual pitfalls of a "X.0" release.
Ooh, that is a very interesting question that the RFC doesn't address at all. I pretty much agree with both of your sentiments here, and hence suspect we won't have a hard rule, but rather a default tendency. In particular, the benefits of collecting bundles of features together under an umbrella name are decreased somewhat if some of them become available in older epochs.
Another good question. I personally would like to see this issue addressed through LTS releases, which could act as a point of coordination for users wanting to be conservative with their upgrades. I don't think epochs introduce anything particularly new here. In particular, "requiring" a new epoch means nothing more than requiring a new compiler version, so it reduces to the same question we have today (which we don't have a good answer for yet.)
Yes. Part of the benefit of keeping the rapid release model at the center here is that we should be able to avoid the usual pitfalls of a "X.0" release. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
cuviper
Jul 3, 2017
Member
Right, a new epoch requires a new compiler, so yes it's basically the same as bumping rustc generally.
One more - If a 2018+ crate wants to use a 2015 crate with catch in its API, are they just out of luck?
|
Right, a new epoch requires a new compiler, so yes it's basically the same as bumping rustc generally. One more - If a 2018+ crate wants to use a 2015 crate with |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
est31
Jul 3, 2017
Contributor
To be clear, there isn't a module system proposal yet
@steveklabnik yes, that's right. The proposals I saw didn't change much in the past few weeks so I'd be suprised if it turned out much different from what was proposed initially on irlo months ago. I don't want to go into the details, as continuing this discussion seems not appropriate for this thread. I only wanted to give motivation for why I like this RFC.
The general point I wanted to make is that I clearly don't want to adapt my code to entirely new concepts/systems every 2 years. Knowing that the proponents of such changes will get them through one way or another, I really do prefer if they were done cleanly (this also helps the feature itself!) and done in newer "epochs" of Rust.
The biggest risk of going with this RFC is I think that it may be misunderstood by people that Rust's stability promise is broken, and making people distrust the promises made by the language, turning them away. To emphasize that epochs are not about breakage but about allowing future evolution, I would really like if it isn't just possible but also accepted and not a sign of bad style to stay with your evolving codebase on an older epoch.
@steveklabnik yes, that's right. The proposals I saw didn't change much in the past few weeks so I'd be suprised if it turned out much different from what was proposed initially on irlo months ago. I don't want to go into the details, as continuing this discussion seems not appropriate for this thread. I only wanted to give motivation for why I like this RFC. The general point I wanted to make is that I clearly don't want to adapt my code to entirely new concepts/systems every 2 years. Knowing that the proponents of such changes will get them through one way or another, I really do prefer if they were done cleanly (this also helps the feature itself!) and done in newer "epochs" of Rust. The biggest risk of going with this RFC is I think that it may be misunderstood by people that Rust's stability promise is broken, and making people distrust the promises made by the language, turning them away. To emphasize that epochs are not about breakage but about allowing future evolution, I would really like if it isn't just possible but also accepted and not a sign of bad style to stay with your evolving codebase on an older epoch. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Ixrec
Jul 3, 2017
Contributor
In particular, the benefits of collecting bundles of features together under an umbrella name are decreased somewhat if some of them become available in older epochs.
I suspect the most useful "bundles of features" are ones where some of the features don't come into their own until the rest of the bundle is also stabilized. Like how impl Trait is useful today, but practically mandatory when futures and async/await are involved. Or how CTFE and const fn aren't that useful without each other. So in that sense I don't think stabilizing some "non-breaking" features will weaken a good "bundle".
I suspect the most useful "bundles of features" are ones where some of the features don't come into their own until the rest of the bundle is also stabilized. Like how |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
est31
Jul 3, 2017
Contributor
One more - If a 2018+ crate wants to use a 2015 crate with catch in its API, are they just out of luck?
I guess there is a limit to the compatibility this RFC can provide?
I guess there is a limit to the compatibility this RFC can provide? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Jul 3, 2017
Contributor
Code that compiles without warnings on the previous epoch (under the latest compiler release) will compile without warnings or errors on the next epoch
As written, I think this excludes ever adding new warnings. You may want to weaken this to "without errors on the next epoch" (but not necessarily without warnings), or "without warnings or errors in the first compiler version that supports the next epoch".
Even then, deprecated stuff cannot be removed or repurposed until two epochs later. This is nice for stability, but maybe a bit heavy for language evolution flexibility. If it is intended, the RFC should mention this.
As written, I think this excludes ever adding new warnings. You may want to weaken this to "without errors on the next epoch" (but not necessarily without warnings), or "without warnings or errors in the first compiler version that supports the next epoch". Even then, deprecated stuff cannot be removed or repurposed until two epochs later. This is nice for stability, but maybe a bit heavy for language evolution flexibility. If it is intended, the RFC should mention this. |
text/0000-epochs.md
| We'll wrap up with the full details of the mechanisms at play. | ||
| - `rustc` will take a new flag, `--epoch`, which can specify the epoch to | ||
| use. This flag will default to the current epoch. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Manishearth
Jul 3, 2017
Member
This is interesting.
I prima facie agree with this choice. It makes sense for the CLI tool to default to the latest epoch for ease of use.
But this does bring into question the stability of said CLI tool. We have thus far treated rustc as a tool with stable flags and behavior; with the stable release not having any unstable flags (etc).
However, this does mean that rustc foo.rs may stop compiling if you upgrade your compiler (for reasons other than soundness bugfixes yada yada), which is not "stable" as I understand the current definition of stability for the rustc CLI tool.
We can, of course, choose to change this definition (or I may simply be wrong as to how we evaluate stability for rustc) but I do think that this is a subtlety that should be highlighted and perhaps discussed more. So far we largely assume that most consumers of rustc are using it through cargo, but we are likely to have more and more direct consumers as it gets integrated with alternate build systems (like Bazel). We can make it the responsibility of these build systems to explicitly set the epoch, but again, this is technically a breaking change.
Manishearth
Jul 3, 2017
Member
This is interesting.
I prima facie agree with this choice. It makes sense for the CLI tool to default to the latest epoch for ease of use.
But this does bring into question the stability of said CLI tool. We have thus far treated rustc as a tool with stable flags and behavior; with the stable release not having any unstable flags (etc).
However, this does mean that rustc foo.rs may stop compiling if you upgrade your compiler (for reasons other than soundness bugfixes yada yada), which is not "stable" as I understand the current definition of stability for the rustc CLI tool.
We can, of course, choose to change this definition (or I may simply be wrong as to how we evaluate stability for rustc) but I do think that this is a subtlety that should be highlighted and perhaps discussed more. So far we largely assume that most consumers of rustc are using it through cargo, but we are likely to have more and more direct consumers as it gets integrated with alternate build systems (like Bazel). We can make it the responsibility of these build systems to explicitly set the epoch, but again, this is technically a breaking change.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
Yeah, I figured that people with stability concerns here would just always pin an epoch in their arguments. However, I think this is a small detail that could easily go either way.
aturon
Jul 3, 2017
Member
Yeah, I figured that people with stability concerns here would just always pin an epoch in their arguments. However, I think this is a small detail that could easily go either way.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
cuviper
Jul 3, 2017
Member
FWIW, this can also happen with GCC when they update the default -std option.
cuviper
Jul 3, 2017
Member
FWIW, this can also happen with GCC when they update the default -std option.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
steveklabnik
Jul 3, 2017
Member
Yes, the drafts I saw here said "default to the 2015 epoch"; we should fix this, IMO.
steveklabnik
Jul 3, 2017
Member
Yes, the drafts I saw here said "default to the 2015 epoch"; we should fix this, IMO.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Jul 3, 2017
Contributor
I read through the entire RFC but missed this detail. I saw that Cargo defaults to epoch = "2015" and assumed that rustc would too.
I think this should be reconsidered. Rust-aware build systems other than Cargo can also decide to enable the latest epoch as part of their template for new projects.
SimonSapin
Jul 3, 2017
Contributor
I read through the entire RFC but missed this detail. I saw that Cargo defaults to epoch = "2015" and assumed that rustc would too.
I think this should be reconsidered. Rust-aware build systems other than Cargo can also decide to enable the latest epoch as part of their template for new projects.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
One more - If a 2018+ crate wants to use a 2015 crate with
catchin its API, are they just out of luck?
Another good one :-)
There are two ways I can see this going:
-
We can introduce some mechanism for referring to identifiers named as keywords. It might be enough to allow use of keywords within renamed imports, e.g.
use foo::catch as catch_;. We'd need to support method renaming, however. -
Worst case, you can write a shim crate that uses epoch 2015 but re-exports renamed APIs. That can get tricky with traits, though...
Another good one :-) There are two ways I can see this going:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
Code that compiles without warnings on the previous epoch (under the latest compiler release) will compile without warnings or errors on the next epoch
As written, I think this excludes ever adding new warnings. You may want to weaken this to "without errors on the next epoch" (but not necessarily without warnings), or "without warnings or errors in the first compiler version that supports the next epoch".
Good point. It's probably enough to say "without errors"
Even then, deprecated stuff cannot be removed or repurposed until two epochs later. This is nice for stability, but maybe a bit heavy for language evolution flexibility. If it is intended, the RFC should mention this.
I don't quite follow this point. Examples like the catch keyword involve deprecation in one epoch, then immediate removal/replacement in the next. I don't see how that violates the rule above.
Good point. It's probably enough to say "without errors"
I don't quite follow this point. Examples like the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Ixrec
Jul 3, 2017
Contributor
@aturon A third option would be adding #[cfg(epoch >= 2018)], which would allow crate authors affected by such unfortunate corner cases to swap their catch method for do_catch or whatever else is needed to support >=2018 clients while still staying on the old epoch for the most part.
My guess is we don't actually want to do that, as I can easily imagine overuse of it in a sufficiently large dependency graph leading to compatibility nightmares, and potentially encouraging "people can just cfg it" arguments for epoch changes we would otherwise rightly reject as too breaking. But it seems worth mentioning.
|
@aturon A third option would be adding My guess is we don't actually want to do that, as I can easily imagine overuse of it in a sufficiently large dependency graph leading to compatibility nightmares, and potentially encouraging "people can just cfg it" arguments for epoch changes we would otherwise rightly reject as too breaking. But it seems worth mentioning. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
Update: per discussion with @Manishearth, I've changed the RFC to default to the 2015 epoch when no flag is given to rustc, since that's more consistent with our general stability story. @nikomatsakis seemed to prefer the latest epoch, but I'll let him argue that point.
|
Update: per discussion with @Manishearth, I've changed the RFC to default to the 2015 epoch when no flag is given to |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
cuviper
Jul 3, 2017
Member
Do macros operate with the epoch in their crate of origin? I guess they must, but there could be some hairy interactions with stuff that's only legal in the epoch that instantiated it. e.g. oldvec![new-expr]
|
Do macros operate with the epoch in their crate of origin? I guess they must, but there could be some hairy interactions with stuff that's only legal in the epoch that instantiated it. e.g. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
Procedural macros, in particular, are going to be "interesting" since we can stitch together token streams potentially coming from a mixture of sources.
I haven't thought extensively about this, but I think the ideal behavior would involve some kind of "coloring" of token trees with their epoch of origin. That works well for keywords, since we make the distinction at the lexer level and don't otherwise mind if an identifier happens to have the same name as a keyword.
Other concerns, such as changes to type inference, would likely be much harder to provide a "coloring" strategy for.
I suspect the best we can do is: any time we make an epoch-dependent change, the RFC should contain a section laying out the plan for handling (procedural) macros.
|
Procedural macros, in particular, are going to be "interesting" since we can stitch together token streams potentially coming from a mixture of sources. I haven't thought extensively about this, but I think the ideal behavior would involve some kind of "coloring" of token trees with their epoch of origin. That works well for keywords, since we make the distinction at the lexer level and don't otherwise mind if an identifier happens to have the same name as a keyword. Other concerns, such as changes to type inference, would likely be much harder to provide a "coloring" strategy for. I suspect the best we can do is: any time we make an epoch-dependent change, the RFC should contain a section laying out the plan for handling (procedural) macros. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Jul 3, 2017
Contributor
Even then, deprecated stuff cannot be removed or repurposed until two epochs later.
I don't quite follow this point. Examples like the catch keyword involve deprecation in one epoch, then immediate removal/replacement in the next. I don't see how that violates the rule above.
Let’s assume that catch didn’t make it for 2018. let catch = 4; was not a warning in epoch 2015, so the bit of RFC text quoted earlier forbids making it a warning in epoch 2018. We’d have to wait for the next one, let’s call it 2020, to deprecate catch as an identifier and then yet another cycle to be able to make it a keyword in 2022.
So I think we want to drop the "code with warning in one epoch emits no warning in the next" rule. (Reduce it to "no hard error in the next".)
Let’s assume that So I think we want to drop the "code with warning in one epoch emits no warning in the next" rule. (Reduce it to "no hard error in the next".) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Jul 3, 2017
Member
@SimonSapin ah I see, it was based on reading the literal words I wrote, as opposed to what I had in my head :-)
I've pushed a fix.
|
@SimonSapin ah I see, it was based on reading the literal words I wrote, as opposed to what I had in my head :-) I've pushed a fix. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
est31
Jul 3, 2017
Contributor
Just for clarity, this will fully replace the current pattern of first linting and then turning that lint into error by default then into a hard error, which is being done right now (also has a tag) for smaller breaking changes?
|
Just for clarity, this will fully replace the current pattern of first linting and then turning that lint into error by default then into a hard error, which is being done right now (also has a tag) for smaller breaking changes? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Aaronepower
Jul 3, 2017
How will multi epoch transitions work, especially in relation to the example of changing the Trait syntax? If for example someone writes a program for a company in current Rust, the program's code isn't touched much for a couple of years till lets say mid 2020 and the programmer decides they want upgrade the code. If they simply added epoch = "2020" to Cargo.toml couldn't they have a program that works in both 2015 Rust and 2020 Rust that behaves differently?
Similarly how will the rustfix handle transitioning from arbitrary epochs to the latest? Does it essentially run older versions of itself till it's just at the last old epoch and then run the new changes?
Aaronepower
commented
Jul 3, 2017
|
How will multi epoch transitions work, especially in relation to the example of changing the Similarly how will the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Jul 3, 2017
Contributor
Presumably rustfix, like rustc, will need to know about all older epochs. It would fix from 2015 to 2020 by going through 2018, at least internally.
|
Presumably |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Aaronepower
Jul 3, 2017
Also what if there is a case where the no need for an epoch on year there should be one? For example, it was decided to spend the year refining existing features and adding features that have no stability impact? I don't know if that'd ever be possible, but would a "empty" epoch be released or would it be simply skipped?
Aaronepower
commented
Jul 3, 2017
|
Also what if there is a case where the no need for an epoch on year there should be one? For example, it was decided to spend the year refining existing features and adding features that have no stability impact? I don't know if that'd ever be possible, but would a "empty" epoch be released or would it be simply skipped? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Jul 3, 2017
Contributor
I think it would be pushed to the next year, or whenever it becomes useful. This is why the "preview" is 2015-next (with the previous number), not 2018-pre (which would put a deadline at December 2018).
|
I think it would be pushed to the next year, or whenever it becomes useful. This is why the "preview" is |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
KiChjang
Jul 4, 2017
Member
A slight tangent to this RFC: if we are not going to follow semver's version breaking changes and instead adopt epochs, should we just simply drop the "1.x" prefixes on rustc's versions?
EDIT: I think as a corollary to that, we should also ditch semver altogether and figure out what rustc's own versioning scheme should be.
|
A slight tangent to this RFC: if we are not going to follow semver's version breaking changes and instead adopt epochs, should we just simply drop the "1.x" prefixes on rustc's versions? EDIT: I think as a corollary to that, we should also ditch semver altogether and figure out what rustc's own versioning scheme should be. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Gankro
Jul 4, 2017
Contributor
Loose Notes:
-
The core proposed machinery is good and I think it should exist.
-
I would like to emphasize that using epochs to break things is a nuclear option (which the text seems to hint at, but isn't totally clear on). I would personally prefer that we proceed with one of the stated policy alternatives -- "no RFC should qualify its acceptance on the creation of a breaking epoch". That is, every RFC must have a non-breaking version, which is the primary proposal. Breaking things should come only if there's public outcry for it. No point in breaking things for a feature our users don't end up caring much about.
-
I flat-out don't believe the claim that random pieces of code on the internet will start mentioning epochs. Notably, it's impossible to predict when I write something if epochs will be relevant to any particular claim. We also can't expect developers to be aware of things that changed before they ever started using Rust. Something that seemingly "always" has been true might have changed in a much earlier epoch. Also there's just lots of relatively low effort content that ends up living forever like Stack Overflow answers. The fact that epochs will always lead to a Rust-1.0 style documentation confusion is why I consider them to be nuclear.
-
I don't like the "regular" epochs that the RFC seems to be suggesting; I would prefer if they were reserved for "ok we actually broke something". I don't want to have muddy epochs where some of them are totally fine and some actually matter. Although epochs are "beyond" SemVer I would like to keep the spirit of it; it should be easy to tell how hard it is to upgrade.
-
I don't understand why we're calling the alpha releases for 2018 to be "2015-next" -- seems incredibly confusing, considering under this proposal we always know what the final release will be called?
-
The difference between rustc and cargo's epoch defaults seems to be suggesting that only Cargo provides support for reproducible builds? This doesn't make sense to me, can you elaborate?
-
I still think epochs should still be called Sonic Generations, after Rust's official mascot.

This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
golddranks
Jul 4, 2017
@kichang there is value in versioning the compiler separately from the language. One could say that the "1." part of the version number becomes futile if there's never going to be 2.0, but it still essentially communicates the intent, as it's a semver-based version number: "this compiler is still 1.x, and therefore still compatible with the good old Rust!"
golddranks
commented
Jul 4, 2017
|
@kichang there is value in versioning the compiler separately from the language. One could say that the "1." part of the version number becomes futile if there's never going to be 2.0, but it still essentially communicates the intent, as it's a semver-based version number: "this compiler is still 1.x, and therefore still compatible with the good old Rust!" |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
stepancheg
Jul 4, 2017
Do we need another concept — year-epoch? Could't simply every release of rust introduce a new epoch? And "epoch" would be simply a version of compiler, e. g.
rust_version = "1.20"
BTW, this will also fix an issue of library compatibility with older rust versions. E. g. if Vec adds function like shuffle in 1.21, program should not compile in compiler version 1.21 if epoch is 1.20. This will guarantee that code is compileable with rust 1.20 (and also compilation shouldn't even start with rust 1.19). Epoch mechanism doesn't solve this issue.
stepancheg
commented
Jul 4, 2017
•
|
Do we need another concept — year-epoch? Could't simply every release of rust introduce a new epoch? And "epoch" would be simply a version of compiler, e. g.
BTW, this will also fix an issue of library compatibility with older rust versions. E. g. if |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Jul 4, 2017
Contributor
A slight tangent to this RFC: if we are not going to follow semver's version breaking changes and instead adopt epochs, should we just simply drop the "1.x" prefixes on rustc's versions?
Staying at 1.x.y forever is a valid use of SemVer. Also I think it helps signal to the outside world that we’re committed to stability.
I’ve said it when 1.0.0 came out and and I still think it: I’m looking forward to the release of Rust 1.100.0 as a proof that our stability story has worked.
Staying at 1.x.y forever is a valid use of SemVer. Also I think it helps signal to the outside world that we’re committed to stability. I’ve said it when 1.0.0 came out and and I still think it: I’m looking forward to the release of Rust 1.100.0 as a proof that our stability story has worked. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Aaronepower
Jul 4, 2017
I don't like the "regular" epochs that the RFC seems to be suggesting; I would prefer if they were reserved for "ok we actually broke something". I don't want to have muddy epochs where some of them are totally fine and some actually matter. Although epochs are "beyond" SemVer I would like to keep the spirit of it; it should be easy to tell how hard it is to upgrade.
If the epochs are only released with a breaking change, what makes this different from having a Rust 2.0, other than the name?
Aaronepower
commented
Jul 4, 2017
If the epochs are only released with a breaking change, what makes this different from having a Rust 2.0, other than the name? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
carols10cents
Jul 4, 2017
Member
If the epochs are only released with a breaking change, what makes this different from having a Rust 2.0, other than the name?
This is a confusion I had when first introduced to this idea as well. The difference is that code written in, say, epoch 2015 Rust will always compile with every later Rust compiler, such as a hypothetical Rust 1.29 that will support epoch 2018 Rust. See the table in this section of the RFC-- if we were actually making a 2.0 Rust compiler, some of the cells in "Status of catch in epoch 2015" would say "compiler error" instead.
Please keep asking questions on this point if this still isn't clear, we very much want the difference between epochs and semver 2.0 to be clear before coming anywhere close to accepting it.
This is a confusion I had when first introduced to this idea as well. The difference is that code written in, say, epoch 2015 Rust will always compile with every later Rust compiler, such as a hypothetical Rust 1.29 that will support epoch 2018 Rust. See the table in this section of the RFC-- if we were actually making a 2.0 Rust compiler, some of the cells in "Status of catch in epoch 2015" would say "compiler error" instead. Please keep asking questions on this point if this still isn't clear, we very much want the difference between epochs and semver 2.0 to be clear before coming anywhere close to accepting it. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ubsan
Aug 31, 2017
Contributor
@aturon That's a good point; I'd still like to minimize churn in this way, and having lots of time to update code for a new epoch definitely does that.
|
@aturon That's a good point; I'd still like to minimize churn in this way, and having lots of time to update code for a new epoch definitely does that. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Sep 1, 2017
Contributor
Wording nit-picking aside this looks much better, thanks @aturon !
|
Wording nit-picking aside this looks much better, thanks @aturon ! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
emk
Sep 1, 2017
@aturon Thank you for the CC!
These new policy changes address the major concerns that I raised on the module and dyn RFCs.
✅ Very low risk of needing to fork unmaintained "dependencies of dependencies" because of an edge case.✅ A good story for Stack Overflow and old documentation. By preferring warnings and "softer" styles of deprecation when possible, this should allow the compiler to educate developers about what has changed.✅ A realistic standard forrustfix. It is neither possible nor desirable forrustfixto handle every imaginable corner case. The last 0.1% of anything can be ruinously expensive. So it's better to analyze these issues at the design stage and usecrater-like tools to get empirical data, and to design new language features around the actual ecosystem. This assumes that crates.io is a reasonable proxy for private Rust code.✅ Enough flexibility to allow truly critical changes. For example, if there's ever a Rust equivalent of C'sgets, there should be a path to remove it. Similarly, one of the great miseries of C++ has always subtle corner-case interactions between old features and major new features. I could easily imagine a case where a feature like-> impl Traitorawait!might require a subtle tweak elsewhere in the language that affects very little code but that has a huge payoff in orthogonality. This latest proposed language provides a good framework for thinking about this.✅ A bias against "medium-payoff" improvements that break a lot of code. Rust developers who aren't on r/rust or Discourse shouldn't need to fear the RFC process as a source of sudden surprises.✅ Cross-crate macros with mixed epochs. I'm kind of amazed that there's a technical solution for this, but it certainly reduces the odds of ugly headaches.
I might have some more thoughts later, but I'm encouraged by the general direction here!
emk
commented
Sep 1, 2017
|
@aturon Thank you for the CC! These new policy changes address the major concerns that I raised on the module and
I might have some more thoughts later, but I'm encouraged by the general direction here! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
konstin
Sep 1, 2017
In addition to the above, compiler error messages should be agnostic to code from old epoch. This means e.g. detecting the usage of newly introduced keywords as identifier.
Another major point is code that is closed source and therefore can't be tested through crater. The rust teams should pair up with the friends of rust companies and gather their feedback before releasing a breaking change. This will avoid unexpected breakage which can be very frustrating otherwise.
konstin
commented
Sep 1, 2017
|
In addition to the above, compiler error messages should be agnostic to code from old epoch. This means e.g. detecting the usage of newly introduced keywords as identifier. Another major point is code that is closed source and therefore can't be tested through crater. The rust teams should pair up with the friends of rust companies and gather their feedback before releasing a breaking change. This will avoid unexpected breakage which can be very frustrating otherwise. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
emk
Sep 4, 2017
Another major point is code that is closed source and therefore can't be tested through crater. The rust teams should pair up with the friends of rust companies and gather their feedback before releasing a breaking change. This will avoid unexpected breakage which can be very frustrating otherwise.
I would imagine that some of the "friends of Rust" companies would be interested in this kind of testing. For my employer, however, here's the reality of how this might work:
- Our continuous integration system builds our proprietary code using stable Rust. For various technical reasons, our CI system is unlikely to ever compile any significant fraction of our proprietary code using beta or nightly Rust.
- I encourage developers to install nightly Rust and run
clippyon all Rust projects. So if something is being actively developed in a given month, it will get tested on nightly Rust. But it's entirely possible for some internal projects to go 6 months or more with no commits. Oddly, this means that if clippy starts working on stable Rust, we'll actually do less testing against nightly Rust! - Even if somebody else volunteered to run a specific
rustcbranch against our internal code, that would be an administrative nuisance to set up. - If any of our internal projects are using Rust features that aren't also used by a public crate somewhere on crates.io, then that actually worries me, and I'd prefer to fix our code. I learned long ago that as an API user, my only long-term safety is to remain safely "with the herd."
So realistically, while I appreciate the thought of testing proposed Rust features against our internal code, we don't actually have our build system set up in such a way as to make this easy. However, we definitely appreciate crater (or cargo bomb, or whatever it's called), because:
- It demonstrates that the Rust core team is exceptionally serious about stability. At this level,
crateris almost a symbolic thing, a conversational shorthand when speaking to people about Rust: "They actually compile the entirely open source ecosystem when releasing new versions of Rust!" People love hearing this. - It means that none of our third-party dependencies are broken by Rust upgrades. And as previously mentioned, I'm actually more concerned about broken dependencies than about needing to fix our own code. Fixing our code is annoying, but at least I have commit bits and won't need to fork anything.
cratertests a very large sample of real-world Rust. It doesn't specifically test our code, but it tests a far larger body of code written by many different people.
So that's why I'm willing to accept crates.io as a "proxy" for our internal code. Of course, other companies might feel differently.
emk
commented
Sep 4, 2017
•
I would imagine that some of the "friends of Rust" companies would be interested in this kind of testing. For my employer, however, here's the reality of how this might work:
So realistically, while I appreciate the thought of testing proposed Rust features against our internal code, we don't actually have our build system set up in such a way as to make this easy. However, we definitely appreciate
So that's why I'm willing to accept crates.io as a "proxy" for our internal code. Of course, other companies might feel differently. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Sep 5, 2017
Member
It seems like folks are generally a fan of the revised policy! There may be some more tweaking to do around the pacing of deprecations, but I think we can hash that out with more concrete cases.
I'm still waiting for one more thing before merging, though: whether to stipulate that an epoch cannot change the "meaning" of an existing code phrase that previously compiled. I use quotes here because there are cases under discussion where the old meaning stays intact as a fallback, but a new meaning is layered on top, and we're still trying to sort through the full implications. Once that discussion draws to a close, I'll wrap this RFC up!
|
It seems like folks are generally a fan of the revised policy! There may be some more tweaking to do around the pacing of deprecations, but I think we can hash that out with more concrete cases. I'm still waiting for one more thing before merging, though: whether to stipulate that an epoch cannot change the "meaning" of an existing code phrase that previously compiled. I use quotes here because there are cases under discussion where the old meaning stays intact as a fallback, but a new meaning is layered on top, and we're still trying to sort through the full implications. Once that discussion draws to a close, I'll wrap this RFC up! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joshtriplett
Sep 5, 2017
Member
@aturon If we don't say that, then at a minimum, I would stipulate that an epoch cannot make a change unless 1) the previous epoch presented it as an on-by-default lint, and 2) it has a rustfix.
|
@aturon If we don't say that, then at a minimum, I would stipulate that an epoch cannot make a change unless 1) the previous epoch presented it as an on-by-default lint, and 2) it has a rustfix. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
konstin
Sep 5, 2017
Our continuous integration system builds our proprietary code using stable Rust. For various technical reasons, our CI system is unlikely to ever compile any significant fraction of our proprietary code using beta or nightly Rust.
While this might be true for some build systems, there are surely others out there where you can easily start a build with a different rust version or even run a rustfix tooĺ. There are three main reasons why I'd suggest promoting testing on closed source code, beside all the difficulties:
The code bases in enterprise applications tend to be huge compared to open source applications. I don't know about the current situation in rust, but I'd assume that they could significantly increase the number of lines tested. Especially if the code with good integration could be extremely helpfull uncovering otherwise hard to find bugs.
Companies also tend to create weird homegrown workarounds custom solutions in complex systems which are fitted to the needs of a particular company or project and can be found only there. This can be easily observed for enterprise java or c++ code. Having those constructs checked wouldn't be too bad. It would also increase the trust in rust as a platform if developers knew that their software will continue working as expected after the the next release. This might seems like something obvious to someone working with java or python, but having worked in frontend development has unfortunately proven that this wrong. We did for example did have multiple occasions where patch version updates broke our build.
Finally, it should also be highly in the interest of the production users to see how well their code plays with new rust versions and with a future rustfix tool.
konstin
commented
Sep 5, 2017
While this might be true for some build systems, there are surely others out there where you can easily start a build with a different rust version or even run a rustfix tooĺ. There are three main reasons why I'd suggest promoting testing on closed source code, beside all the difficulties: The code bases in enterprise applications tend to be huge compared to open source applications. I don't know about the current situation in rust, but I'd assume that they could significantly increase the number of lines tested. Especially if the code with good integration could be extremely helpfull uncovering otherwise hard to find bugs. Companies also tend to create Finally, it should also be highly in the interest of the production users to see how well their code plays with new rust versions and with a future rustfix tool. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
konstin
commented
Sep 5, 2017
|
Btw the rendered link in the original proposal is broken |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
@konstin Fixed; thanks for noticing. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phaylon
Sep 6, 2017
Personally, I would prefer breaking changes behind feature-flags with fine-grained availability and ways to disable them, and have epochs only act as feature bundles that set the defaults. My reasons are:
- It would mean I wouldn't ever have to worry about losing features I care about, since I can always re-activate them, or deactivate the things that took it away.
- It allows me to switch to a new epoch eagerly, and only disable what is currently still in the way of a full upgrade. Then it's easy to refactor piece-by-piece.
- crates.io can be watched for crates with use-cases requiring adjustments, allowing the features to be refined.
- A large number of deactivations of a feature in crates without a specific use-case for a reason would point to ergonomics issues with the feature.
- Having epochs being just points in time where features are defaulted makes them seem more like waypoints in a moving language than a new language version.
- Constant-availability of features will make it a lot easier to refactor projects to a modern style when they are 10-20 years old, since you can work through changes individually.
phaylon
commented
Sep 6, 2017
|
Personally, I would prefer breaking changes behind feature-flags with fine-grained availability and ways to disable them, and have epochs only act as feature bundles that set the defaults. My reasons are:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ssokolow
Sep 6, 2017
It would mean I wouldn't ever have to worry about losing features I care about, since I can always re-activate them, or deactivate the things that took it away.
The problem is that taking this approach encourages a Perl-like or C++-like situation where the language is really many different personal dialects and it takes a disproportionate effort to gain the kind broad-spectrum competency that employers look for when adding new members to existing projects.
ssokolow
commented
Sep 6, 2017
•
The problem is that taking this approach encourages a Perl-like or C++-like situation where the language is really many different personal dialects and it takes a disproportionate effort to gain the kind broad-spectrum competency that employers look for when adding new members to existing projects. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phaylon
Sep 6, 2017
If the changes are small and few, that shouldn't become a problem, since it'd still be quite close. I'd certainly assume ecosystem usage will vary a lot more and have a lot more impact on peoples experiences.
Additionally, for the full experience you'll need to know the previous epochs as well, since you'll touch multiple epochs over the course of years, and you might want to be able to read code for crates in older epochs.
phaylon
commented
Sep 6, 2017
|
If the changes are small and few, that shouldn't become a problem, since it'd still be quite close. I'd certainly assume ecosystem usage will vary a lot more and have a lot more impact on peoples experiences. Additionally, for the full experience you'll need to know the previous epochs as well, since you'll touch multiple epochs over the course of years, and you might want to be able to read code for crates in older epochs. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
vitiral
Sep 7, 2017
I love this idea. I particularily like that it will allow the language to continue to evolve over time. However, I think the proposal as-is misses the primary spirit of what I want epochs to be, and I hope others feel the same way
Spirit of Epochs
While epochs certainly give us the ability to roll out new syntax, keywords and even features I think the most important feature is it's ability to remove old cruft. As is the current proposal focuses almost exlusively on our ability to keep piling on features, but the minimalist in me really wants epoch's to primarily be for stripping out old features and unifying APIs/syntax/design patterns.
Even since 1.0, the language is evolving at a fairly rapid pace. It is probable that extern crate will be removed, the mod keyword may even eventually be removed in favor of a filesystem layout (I know this was rejected for now, but it's possible in the future). Lots of other changes are happening that improve ergonomics and readability and would cause code written in 1.0 rust to be practically unreadable to someone who learned "rust 2019".
Epoch's give us the ability to actually remove this old cruft, and I consider that their strongest selling point. We can simplify the language for newbies so that we no longer have to teach things like this. From a learning persepctive, removing things is (almost) always more valuable than adding things.
I would like this spirit to be better expressed in the RFC. At the very least, the first line item under the header "The basic idea" should be added that states:
- Deprecated APIs and syntax will now generate hard errors, making it easier to teach and read code in the new epoch
vitiral
commented
Sep 7, 2017
|
I love this idea. I particularily like that it will allow the language to continue to evolve over time. However, I think the proposal as-is misses the primary spirit of what I want epochs to be, and I hope others feel the same way Spirit of EpochsWhile epochs certainly give us the ability to roll out new syntax, keywords and even features I think the most important feature is it's ability to remove old cruft. As is the current proposal focuses almost exlusively on our ability to keep piling on features, but the minimalist in me really wants epoch's to primarily be for stripping out old features and unifying APIs/syntax/design patterns. Even since 1.0, the language is evolving at a fairly rapid pace. It is probable that Epoch's give us the ability to actually remove this old cruft, and I consider that their strongest selling point. We can simplify the language for newbies so that we no longer have to teach things like this. From a learning persepctive, removing things is (almost) always more valuable than adding things. I would like this spirit to be better expressed in the RFC. At the very least, the first line item under the header "The basic idea" should be added that states:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ssokolow
Sep 7, 2017
the mod keyword may even eventually be removed in favor of a filesystem layout (I know this was rejected for now, but it's possible in the future)
Hopefully not unless it's replaced by some other keyword which allows the effects of an omitted pub to take effect within the same file. The unfriendliness to non-IDEs is one of the biggest reasons I hate Java's decision to force "err on the side of too many too-tiny files" filesystem layouts based on a metric as simple as "one class per file".
Rust mods can also be ridiculously tiny when their only purpose is to provide visibility isolation for one or more private members.
ssokolow
commented
Sep 7, 2017
Hopefully not unless it's replaced by some other keyword which allows the effects of an omitted Rust |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
SimonSapin
Sep 7, 2017
Contributor
Epoch's give us the ability to actually remove this old cruft
No. The compiler still needs to support previous epochs, so stuff can only be disabled, in new epochs, not actually removed. There is no benefit to removing stuff just for the sake of removing.
Deprecated APIs and syntax will now generate hard errors
This suggests that all deprecated things should be systematically removed. I strongly disagree. Breakage should only be considered when it can make way for other benefits, like making catch a keyword to use it in a new language construct.
No. The compiler still needs to support previous epochs, so stuff can only be disabled, in new epochs, not actually removed. There is no benefit to removing stuff just for the sake of removing.
This suggests that all deprecated things should be systematically removed. I strongly disagree. Breakage should only be considered when it can make way for other benefits, like making |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
vitiral
Sep 7, 2017
No. The compiler still needs to support previous epochs ...
Sorry, I should have been more clear: I meant it can be removed from our heads -- which is arguably even more important :)
This suggests that all deprecated things should be systematically removed. I strongly disagree. Breakage should only be considered when it can make way for other benefits, like making catch a keyword to use it in a new language construct.
I didn't say all things should be removed (and I don't think that should necessarily be the case... although I can't really think of a counter-example), but I strongly disagree with your disagreement. Removing things that are deprecated is a benefit in itself, and a very strong one. It makes the langauge more uniform and easier to learn for newbies.
vitiral
commented
Sep 7, 2017
Sorry, I should have been more clear: I meant it can be removed from our heads -- which is arguably even more important :)
I didn't say all things should be removed (and I don't think that should necessarily be the case... although I can't really think of a counter-example), but I strongly disagree with your disagreement. Removing things that are deprecated is a benefit in itself, and a very strong one. It makes the langauge more uniform and easier to learn for newbies. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
vitiral
Sep 7, 2017
@ssokolow I don't want to get into bikeshedding about removing mod -- I meant it only as an example.
vitiral
commented
Sep 7, 2017
|
@ssokolow I don't want to get into bikeshedding about removing |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ssokolow
Sep 7, 2017
@vitiral Likewise. I just wanted the point raised somewhere since I was unaware the discussion you mentioned even happened and it's possible I might miss it if it comes around again.
ssokolow
commented
Sep 7, 2017
|
@vitiral Likewise. I just wanted the point raised somewhere since I was unaware the discussion you mentioned even happened and it's possible I might miss it if it comes around again. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
aturon
Sep 14, 2017
Member
After a truly epic (epoch?) -- and remarkably civil and deep -- discussion, this RFC has been merged!
It's likely that we'll want to tweak aspects of the policy for changes outlined in this RFC over time (as some of the recent comments reflect), but this RFC gives a reasonable starting point that stakeholders have found acceptable.
Thanks, everyone, for helping make this RFC what it is!
|
After a truly epic (epoch?) -- and remarkably civil and deep -- discussion, this RFC has been merged! It's likely that we'll want to tweak aspects of the policy for changes outlined in this RFC over time (as some of the recent comments reflect), but this RFC gives a reasonable starting point that stakeholders have found acceptable. Thanks, everyone, for helping make this RFC what it is! |
aturon
merged commit a50ada1
into
rust-lang:master
Sep 14, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
mgattozzi
referenced this pull request
Sep 26, 2017
Closed
Should work continue on current rustdoc? #176
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
toothbrush7777777
Oct 3, 2017
@aturon The link to the rendered text of the RFC returns 404 Page Not Found.
toothbrush7777777
commented
Oct 3, 2017
•
|
@aturon The link to the rendered text of the RFC returns 404 Page Not Found. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
@toothbrush7777777 thanks! Fixed! |
scottmcm
referenced this pull request
Oct 7, 2017
Merged
Add "Update rendered link" to RFC merge procedure #105
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sanmai-NL
commented
Nov 17, 2017
|
@carols10cents: Could you also add the tracking issue to the RFC please? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
@sanmai-NL done! |


aturon commentedJul 3, 2017
•
edited by carols10cents
Edited 1 time
-
carols10cents
edited Oct 4, 2017 (most recent)
Rust's ecosystem, tooling, documentation, and compiler are constantly improving. To make it easier to follow development, and to provide a clear, coherent "rallying point" for this work, this RFC proposes that we declare a epoch every two or three years. Epochs are designated by the year in which they occur, and represent a release in which several elements come together:
Sometimes a feature we want to make available in a new epoch would require backwards-incompatible changes, like introducing a new keyword. In that case, the feature is only available by explicitly opting in to the new epoch. Existing code continues to compile, and crates can freely mix dependencies using different epochs.
Rendered
Update: there's a Request for Explanation podcast episode about this RFC, which is a good way to quickly get up to speed!
Edit: fixed rendered link