mirror of https://github.com/rust-lang/rfcs.git
Replace "epoch" with "edition"
Future readers interested in the design of editions shouldn't have to know that we called them "epochs" for a time. They should be able to find this RFC by searching for "edition", and they shouldn't have to wonder what an "epoch" is if reading another RFC. Not changed: the filename of RFC 2052 so that links don't break, and any usage of the word "epoch" in the "seconds since the epoch" sense.
This commit is contained in:
parent
496a9549f6
commit
6197c2696d
|
@ -6,9 +6,9 @@
|
|||
# Summary
|
||||
[summary]: #summary
|
||||
|
||||
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:
|
||||
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 *edition* every two or three years. Editions are designated by the year in which they occur, and represent a release in which several elements come together:
|
||||
|
||||
- A significant, coherent set of new features and APIs have been stabilized since the previous epoch.
|
||||
- A significant, coherent set of new features and APIs have been stabilized since the previous edition.
|
||||
- Error messages and other important aspects of the user experience around these features are fully polished.
|
||||
- Tooling (IDEs, rustfmt, Clippy, etc) has been updated to work properly with these new features.
|
||||
- There is a guide to the new features, explaining why they're important and how they should influence the way you write Rust code.
|
||||
|
@ -17,7 +17,7 @@ Rust's ecosystem, tooling, documentation, and compiler are constantly improving.
|
|||
- The standard library and other core ecosystem crates have been updated to use the new features as appropriate.
|
||||
- A new edition of the Rust Cookbook has been prepared, providing an updated set of guidance for which crates to use for various tasks.
|
||||
|
||||
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.
|
||||
Sometimes a feature we want to make available in a new edition 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 edition. Existing code continues to compile, and crates can freely mix dependencies using different editions.
|
||||
|
||||
# Motivation
|
||||
[motivation]: #motivation
|
||||
|
@ -85,7 +85,7 @@ At the same time, the commitment to stability and rapid releases has been an
|
|||
incredible boon for Rust, and we don't want to give up those existing mechanisms
|
||||
or their benefits.
|
||||
|
||||
This RFC proposes *epochs* as a mechanism we can layer on top of our existing
|
||||
This RFC proposes *editions* as a mechanism we can layer on top of our existing
|
||||
release process, keeping its guarantees while addressing its gaps.
|
||||
|
||||
# Detailed design
|
||||
|
@ -94,11 +94,11 @@ release process, keeping its guarantees while addressing its gaps.
|
|||
## The basic idea
|
||||
|
||||
To make it easier to follow Rust's evolution, and to provide a clear, coherent
|
||||
"rallying point" for the community, the project declares a *epoch* every
|
||||
two or three years. Epochs are designated by the year in which they occur,
|
||||
"rallying point" for the community, the project declares a *edition* every
|
||||
two or three years. Editions are designated by the year in which they occur,
|
||||
and represent a release in which several elements come together:
|
||||
|
||||
- A significant, coherent set of new features and APIs have been stabilized since the previous epoch.
|
||||
- A significant, coherent set of new features and APIs have been stabilized since the previous edition.
|
||||
- Error messages and other important aspects of the user experience around these features are fully polished.
|
||||
- Tooling (IDEs, rustfmt, Clippy, etc) has been updated to work properly with these new features.
|
||||
- There is a guide to the new features, explaining why they're important and how they should influence the way you write Rust code.
|
||||
|
@ -107,65 +107,65 @@ and represent a release in which several elements come together:
|
|||
- The standard library and other core ecosystem crates have been updated to use the new features as appropriate.
|
||||
- A new edition of the Rust Cookbook has been prepared, providing an updated set of guidance for which crates to use for various tasks.
|
||||
|
||||
The precise list of elements going into an epoch is expected to evolve over
|
||||
The precise list of elements going into an edition is expected to evolve over
|
||||
time, as the Rust project and ecosystem grow.
|
||||
|
||||
Sometimes a feature we want to make available in a new epoch would require
|
||||
Sometimes a feature we want to make available in a new edition 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. Each **crate** can declare an epoch in its `Cargo.toml` like
|
||||
`epoch = "2019"`; otherwise it is assumed to have epoch 2015,
|
||||
coinciding with Rust 1.0. Thus, new epochs are *opt in*, and the
|
||||
dependencies of a crate may use older or newer epochs than the crate
|
||||
edition. Each **crate** can declare an edition in its `Cargo.toml` like
|
||||
`edition = "2019"`; otherwise it is assumed to have edition 2015,
|
||||
coinciding with Rust 1.0. Thus, new editions are *opt in*, and the
|
||||
dependencies of a crate may use older or newer editions than the crate
|
||||
itself.
|
||||
|
||||
To be crystal clear: Rust compilers must support *all* extant epochs, and
|
||||
a crate dependency graph may involve several different epochs
|
||||
simultaneously. Thus, **epochs do not split the ecosystem nor do they break
|
||||
To be crystal clear: Rust compilers must support *all* extant editions, and
|
||||
a crate dependency graph may involve several different editions
|
||||
simultaneously. Thus, **editions do not split the ecosystem nor do they break
|
||||
existing code**.
|
||||
|
||||
Furthermore:
|
||||
|
||||
- As with today, each new version of the compiler may gain stabilizations and deprecations.
|
||||
- When opting in to a new epoch, existing deprecations *may* turn into hard
|
||||
- When opting in to a new edition, existing deprecations *may* turn into hard
|
||||
errors, and the compiler may take advantage of that fact to repurpose existing
|
||||
usage, e.g. by introducing a new keyword. **This is the only kind of *breaking* change a
|
||||
epoch opt-in can make.**
|
||||
usage, e.g. by introducing a new keyword. **This is the only kind of
|
||||
*breaking* change a edition opt-in can make.**
|
||||
|
||||
Thus, code that compiles without warnings on the previous epoch (under the latest
|
||||
compiler release) will compile without errors on the next epoch (modulo the
|
||||
[usual caveats] about type inference changes and so on).
|
||||
Thus, code that compiles without warnings on the previous edition (under the
|
||||
latest compiler release) will compile without errors on the next edition
|
||||
(modulo the [usual caveats] about type inference changes and so on).
|
||||
|
||||
[usual caveats]: https://github.com/rust-lang/rfcs/blob/master/text/1122-language-semver.md
|
||||
|
||||
Alternatively, you can continue working with the previous epoch on new
|
||||
Alternatively, you can continue working with the previous edition on new
|
||||
compiler releases indefinitely, but your code may not have access to new
|
||||
features that require new keywords and the like. New features that *are*
|
||||
backwards compatible, however, will be available on older epochs.
|
||||
backwards compatible, however, will be available on older editions.
|
||||
|
||||
## Epoch timing, stabilizations, and the roadmap process
|
||||
## Edition timing, stabilizations, and the roadmap process
|
||||
|
||||
As mentioned above, we want to retain our rapid release model, in which new
|
||||
features and other improvements are shipped on the stable release channel as
|
||||
soon as they are ready. So, to be clear, **we do not hold features back until
|
||||
the next epoch**.
|
||||
the next edition**.
|
||||
|
||||
Rather, epochs, as their name suggests, represent a point of *global
|
||||
Rather, editions, as their name suggests, represent a point of *global
|
||||
coherence*, where documentation, tooling, the compiler, and core libraries are
|
||||
all fully aligned on a new set of (already stabilized!) features and other
|
||||
changes. This alignment can happen incrementally, but an epoch signals that
|
||||
changes. This alignment can happen incrementally, but an edition signals that
|
||||
it *has* happened.
|
||||
|
||||
At the same time, epochs serve as a rallying point for making sure this
|
||||
At the same time, editions serve as a rallying point for making sure this
|
||||
alignment work gets done in a timely fashion--and helping set scope as
|
||||
needed. To make this work, we use the roadmap process:
|
||||
|
||||
- As today, each year has a [roadmap setting out that year's vision]. Some
|
||||
years---like 2017---the roadmap is mostly about laying down major new
|
||||
groundwork. Some years, however, they roadmap explicitly proposes to produce a
|
||||
new epoch during the year.
|
||||
new edition during the year.
|
||||
|
||||
- Epoch years are focused primarily on *stabilization*, *polish*, and
|
||||
- Edition years are focused primarily on *stabilization*, *polish*, and
|
||||
*coherence*, rather than brand new ideas. We are trying to put together and
|
||||
ship a coherent product, complete with documentation and a well-aligned
|
||||
ecosystem. These goals will provide a rallying point for the whole community,
|
||||
|
@ -174,18 +174,18 @@ needed. To make this work, we use the roadmap process:
|
|||
|
||||
[roadmap laying out that year's vision]: https://github.com/rust-lang/rfcs/pull/1728
|
||||
|
||||
In short, epochs are striking a delicate balance: they're not a cutoff for
|
||||
In short, editions are striking a delicate balance: they're not a cutoff for
|
||||
stabilization, which continues every six weeks, but they still provide a strong
|
||||
impetus for coming together as a community and putting together a polished product.
|
||||
|
||||
### The preview period
|
||||
|
||||
There's an important tension around stabilization and epochs:
|
||||
There's an important tension around stabilization and editions:
|
||||
|
||||
- We want to enable new features, including those that require an epoch
|
||||
- We want to enable new features, including those that require an edition
|
||||
opt-in, to be available on the stable channel as they become ready.
|
||||
|
||||
- That means that we must enable some form of the opt in before the epoch
|
||||
- That means that we must enable some form of the opt in before the edition
|
||||
is fully ready to ship.
|
||||
|
||||
- We want to retain our promise that code compiling on stable will continue to
|
||||
|
@ -193,46 +193,46 @@ There's an important tension around stabilization and epochs:
|
|||
|
||||
- That means that, once *any* form of the opt in is shipped, it cannot introduce *new* hard errors.
|
||||
|
||||
Thus, at some point within an epoch year, we will enable the opt-in on the
|
||||
Thus, at some point within an edition year, we will enable the opt-in on the
|
||||
stable release channel, which must include *all* of the hard errors that will be
|
||||
introduced in the next epoch, but not yet all of the stabilizations (or
|
||||
other artifacts that go into the full epoch release). This is the *preview
|
||||
period* for the epoch, which ends when a release is produced that
|
||||
synchronizes all of the elements that go into an epoch and the epoch is
|
||||
introduced in the next edition, but not yet all of the stabilizations (or
|
||||
other artifacts that go into the full edition release). This is the *preview
|
||||
period* for the edition, which ends when a release is produced that
|
||||
synchronizes all of the elements that go into an edition and the edition is
|
||||
formally announced.
|
||||
|
||||
## A broad policy on epoch changes
|
||||
## A broad policy on edition changes
|
||||
|
||||
There are numerous reasons to limit the scope of changes for new epochs, among them:
|
||||
There are numerous reasons to limit the scope of changes for new editions, among them:
|
||||
|
||||
- **Limiting churn**. Even if you aren't *forced* to update your code, even if there are automated tools to do so, churn is still a pain for existing users. It also invalidates, or at least makes harder to use, existing content on the internet, like StackOverflow answers and blog posts. And finally, it plays against the important and hard work we've done to make Rust stable in both reality and perception. In short, while epochs avoid *ecosystem* splits and make churn opt-in, they do not eliminate *all* drawbacks.
|
||||
- **Limiting churn**. Even if you aren't *forced* to update your code, even if there are automated tools to do so, churn is still a pain for existing users. It also invalidates, or at least makes harder to use, existing content on the internet, like StackOverflow answers and blog posts. And finally, it plays against the important and hard work we've done to make Rust stable in both reality and perception. In short, while editions avoid *ecosystem* splits and make churn opt-in, they do not eliminate *all* drawbacks.
|
||||
|
||||
- **Limiting technical debt**. The compiler retains compatibility for old epochs, and thus must have distinct "modes" for dealing with them. We need to strongly limit the amount and complexity of code needed for these modes, or the compiler will become very difficult to maintain.
|
||||
- **Limiting technical debt**. The compiler retains compatibility for old editions, and thus must have distinct "modes" for dealing with them. We need to strongly limit the amount and complexity of code needed for these modes, or the compiler will become very difficult to maintain.
|
||||
|
||||
- **Limiting deep conceptual changes**. Just as we want to keep the compiler maintainable, so too do we want to keep the conceptual model sustainable. That is, if we make truly radical changes in a new epoch, it will be very difficult for people to reason about code involving different epochs, or to remember the precise differences.
|
||||
- **Limiting deep conceptual changes**. Just as we want to keep the compiler maintainable, so too do we want to keep the conceptual model sustainable. That is, if we make truly radical changes in a new edition, it will be very difficult for people to reason about code involving different editions, or to remember the precise differences.
|
||||
|
||||
These lead to some hard and soft constraints.
|
||||
|
||||
### Hard constraints
|
||||
|
||||
**TL;DR: Warning-free code on epoch N must compile on epoch N+1 and have the
|
||||
**TL;DR: Warning-free code on edition N must compile on edition N+1 and have the
|
||||
same behavior.**
|
||||
|
||||
There are only two things a new epoch can do that a normal release cannot:
|
||||
There are only two things a new edition can do that a normal release cannot:
|
||||
|
||||
- Change an existing deprecation into a hard error.
|
||||
- This option is only available when the deprecation is expected to hit a relatively small percentage of code.
|
||||
- Change an existing deprecation to *deny* by default, and leverage the corresponding lint setting to produce error messages *as if* the feature were removed entirely.
|
||||
|
||||
The second option is to be preferred whenever possible. Note that warning-free code in one epoch might produce warnings in the next epoch, but it should still compile successfully.
|
||||
The second option is to be preferred whenever possible. Note that warning-free code in one edition might produce warnings in the next edition, but it should still compile successfully.
|
||||
|
||||
The Rust compiler supports multiple epochs, but **must only support a single version of "core Rust"**. We identify "core Rust" as being, roughly, MIR and the core trait system; this specification will be made more precise over time. The implication is that the "epoch modes" boil down to keeping around multiple desugarings into this core Rust, which greatly limits the complexity and technical debt involved. Similar, core Rust encompasses the core *conceptual* model of the language, and this constraint guarantees that, even when working with multiple epochs, those core concepts remain fixed.
|
||||
The Rust compiler supports multiple editions, but **must only support a single version of "core Rust"**. We identify "core Rust" as being, roughly, MIR and the core trait system; this specification will be made more precise over time. The implication is that the "edition modes" boil down to keeping around multiple desugarings into this core Rust, which greatly limits the complexity and technical debt involved. Similar, core Rust encompasses the core *conceptual* model of the language, and this constraint guarantees that, even when working with multiple editions, those core concepts remain fixed.
|
||||
|
||||
### Soft constraints
|
||||
|
||||
**TL;DR: *Most* code *with* warnings on epoch N should, after running `rustfix`, compile on epoch N+1 and have the same behavior.**
|
||||
**TL;DR: *Most* code *with* warnings on edition N should, after running `rustfix`, compile on edition N+1 and have the same behavior.**
|
||||
|
||||
The core epoch design avoids an ecosystem split, which is very important. But it's *also* important that upgrading your own code to a new epoch is minimally disruptive. The basic principle is that **changes that cannot be automated must be required only in a small minority of crates, and even there not require extensive work**. This principle applies not just to epochs, but also to cases where we'd like to make a widespread deprecation.
|
||||
The core edition design avoids an ecosystem split, which is very important. But it's *also* important that upgrading your own code to a new edition is minimally disruptive. The basic principle is that **changes that cannot be automated must be required only in a small minority of crates, and even there not require extensive work**. This principle applies not just to editions, but also to cases where we'd like to make a widespread deprecation.
|
||||
|
||||
Note that a `rustfix` tool will never be perfect, because of conditional compilation and code generation. So it's important that, in the cases it inevitably fails, the manual fixes are not too onerous.
|
||||
|
||||
|
@ -240,36 +240,36 @@ In addition, migrations that affect a large percentage of code must be "small tw
|
|||
|
||||
These are "soft constraints" because they use terms like "small minority" and "small tweaks", which are open for interpretation. More broadly, the more disruption involved, the higher the bar for the change.
|
||||
|
||||
### Positive examples: What epoch opt-ins can do
|
||||
### Positive examples: What edition opt-ins can do
|
||||
|
||||
Given those principles, let's look in more detail at a few examples of the kinds of
|
||||
changes epoch opt-ins enable. **These are just examples---this RFC doesn't
|
||||
entail any commitment to these language changes**.
|
||||
Given those principles, let's look in more detail at a few examples of the
|
||||
kinds of changes edition opt-ins enable. **These are just examples---this RFC
|
||||
doesn't entail any commitment to these language changes**.
|
||||
|
||||
#### Example: new keywords
|
||||
|
||||
We've taken as a running example introducing new keywords, which sometimes
|
||||
cannot be done backwards compatibly (because a contextual keyword isn't
|
||||
possible). Let's see how this works out for the case of `catch`, assuming that
|
||||
we're currently in epoch 2015.
|
||||
we're currently in edition 2015.
|
||||
|
||||
- First, we deprecate uses of `catch` as identifiers, preparing it to become a new keyword.
|
||||
- We may, as today, implement the new `catch` feature using a temporary syntax
|
||||
for nightly (like `do catch`).
|
||||
- When the epoch opt-in for `2019` is released, opting into it makes `catch` into a
|
||||
- When the edition opt-in for `2019` is released, opting into it makes `catch` into a
|
||||
keyword, regardless of whether the `catch` feature has been implemented. This
|
||||
means that opting in may require some adjustment to your code.
|
||||
- The `catch` syntax can be hooked into an implementation usable on nightly within the `2019` epoch.
|
||||
- The `catch` syntax can be hooked into an implementation usable on nightly within the `2019` edition.
|
||||
- When we're confident in the `catch` feature on nightly, we can stabilize it
|
||||
*onto the stable channel for users opting into `2019`*. It cannot be stabilized onto the `2015` epoch,
|
||||
*onto the stable channel for users opting into `2019`*. It cannot be stabilized onto the `2015` edition,
|
||||
since it requires a new keyword.
|
||||
- `catch` is now a part of Rust, but may not be *fully* integrated into e.g. the book, IDEs, etc.
|
||||
- At some point, epoch `2019` is fully shipped, and `catch` is now fully
|
||||
- At some point, edition `2019` is fully shipped, and `catch` is now fully
|
||||
incorporated into tooling, documentation, and core libraries.
|
||||
|
||||
To make this even more concrete, let's imagine the following (aligned with the diagram above):
|
||||
|
||||
| Rust version | Latest available epoch | Status of `catch` in `2015` | Status of `catch` in latest epoch
|
||||
| Rust version | Latest available edition | Status of `catch` in `2015` | Status of `catch` in latest edition
|
||||
| ------------ | ---------------------- | -- | -- |
|
||||
| 1.15 | 2015 | Valid identifier | Valid identifier
|
||||
| 1.21 | 2015 | Valid identifier; deprecated | Valid identifier; deprecated
|
||||
|
@ -282,7 +282,7 @@ Now, suppose you have the following code:
|
|||
```
|
||||
Cargo.toml:
|
||||
|
||||
epoch = "2015"
|
||||
edition = "2015"
|
||||
```
|
||||
|
||||
```rust
|
||||
|
@ -302,7 +302,7 @@ identifier.
|
|||
code will fail to compile due to `catch` being a keyword.
|
||||
|
||||
- However, if you leave it at `2015`, you can upgrade to Rust 1.27 **and
|
||||
use libraries that opt in to the `2019` epoch** with no problem.
|
||||
use libraries that opt in to the `2019` edition** with no problem.
|
||||
|
||||
#### Example: repurposing corner cases
|
||||
|
||||
|
@ -312,10 +312,10 @@ hierarchy from the filesystem. But there is a corner case today of providing
|
|||
both a `lib.rs` and a `bin.rs` directly at the top level, which doesn't play
|
||||
well with the new feature.
|
||||
|
||||
Using epochs, we can deprecate such usage (in favor of the `bin` directory),
|
||||
then make it an error during the preview period. The module system change could then
|
||||
be made available (and ultimately stabilized) within the preview period, before
|
||||
fully shipping on the next epoch.
|
||||
Using editions, we can deprecate such usage (in favor of the `bin` directory),
|
||||
then make it an error during the preview period. The module system change could
|
||||
then be made available (and ultimately stabilized) within the preview period,
|
||||
before fully shipping on the next edition.
|
||||
|
||||
#### Example: repurposing syntax
|
||||
|
||||
|
@ -332,8 +332,8 @@ Suppose we wanted to carry out such a change. We could do it over multiple steps
|
|||
|
||||
- First, introduce and stabilize `dyn Trait`.
|
||||
- Deprecate bare `Trait` syntax in favor of `dyn Trait`.
|
||||
- In an epoch preview period, make it an error to use bare `Trait` syntax.
|
||||
- Ship the new epoch, and wait until bare `Trait` syntax is obscure.
|
||||
- In an edition preview period, make it an error to use bare `Trait` syntax.
|
||||
- Ship the new edition, and wait until bare `Trait` syntax is obscure.
|
||||
- Re-introduce bare `Trait` syntax, stabilize it, and deprecate `impl Trait` in
|
||||
favor of it.
|
||||
|
||||
|
@ -352,14 +352,14 @@ There are a number of details about type inference that seem suboptimal:
|
|||
may cause other programs to stop compiling.
|
||||
- In trait selection, where-clauses take precedence over impls; changing this is backwards-incompatible.
|
||||
|
||||
We may or may not be able to change these details on the existing epoch. With
|
||||
We may or may not be able to change these details on the existing edition. With
|
||||
enough effort, we could probably deprecate cases where type inference rules
|
||||
might change and request explicit type annotations, and then—in the new
|
||||
epoch—tweak those rules.
|
||||
edition—tweak those rules.
|
||||
|
||||
### Negative examples: What epoch opt-ins can't do
|
||||
### Negative examples: What edition opt-ins can't do
|
||||
|
||||
There are also changes that epochs don't help with, due to the constraints
|
||||
There are also changes that editions don't help with, due to the constraints
|
||||
we impose. These limitations are extremely important for keeping the compiler
|
||||
maintainable, the language understandable, and the ecosystem compatible.
|
||||
|
||||
|
@ -370,7 +370,7 @@ which crates can provide which `impl`s. It's not possible to change protocol
|
|||
incompatibly, because existing code will assume the current protocol and provide
|
||||
impls accordingly, and there's no way to work around that fact via deprecation.
|
||||
|
||||
More generally, this means that epochs can only be used to make changes to the
|
||||
More generally, this means that editions can only be used to make changes to the
|
||||
language that are applicable *crate-locally*; they cannot impose new
|
||||
requirements or semantics on external crates, since we want to retain
|
||||
compatibility with the existing ecosystem.
|
||||
|
@ -380,7 +380,7 @@ compatibility with the existing ecosystem.
|
|||
See [rust-lang/rust#35943](https://github.com/mozilla/rust/issues/35943). Due to
|
||||
a silly oversight, you can’t currently downcast the “cause” of an error to
|
||||
introspect what it is. We can’t make the trait have stricter requirements; it
|
||||
would break existing impls. And there's no way to do so only in a newer epoch,
|
||||
would break existing impls. And there's no way to do so only in a newer edition,
|
||||
because we must be compatible with the older one, meaning that we cannot rely on
|
||||
downcasting.
|
||||
|
||||
|
@ -392,13 +392,13 @@ More generally, breaking changes to the standard library are not possible.
|
|||
|
||||
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 epoch 2015.
|
||||
- `rustc` will take a new flag, `--edition`, which can specify the edition to
|
||||
use. This flag will default to edition 2015.
|
||||
- This flag should not affect the behavior of the core trait system or passes at the MIR level.
|
||||
- `Cargo.toml` can include an `epoch` value, which is used to pass to `rustc`.
|
||||
- If left off, it will assume epoch 2015.
|
||||
- `cargo new` will produce a `Cargo.toml` with the latest `epoch` value
|
||||
(including an epoch currently in its preview period).
|
||||
- `Cargo.toml` can include an `edition` value, which is used to pass to `rustc`.
|
||||
- If left off, it will assume edition 2015.
|
||||
- `cargo new` will produce a `Cargo.toml` with the latest `edition` value
|
||||
(including an edition currently in its preview period).
|
||||
|
||||
# How We Teach This
|
||||
[how-we-teach-this]: #how-we-teach-this
|
||||
|
@ -406,7 +406,7 @@ We'll wrap up with the full details of the mechanisms at play.
|
|||
First and foremost, if we accept this RFC, we should publicize the plan widely,
|
||||
including on the main Rust blog, in a style simlar to [previous posts] about our
|
||||
release policy. This will require extremely careful messaging, to make clear
|
||||
that epochs are *not* about breaking Rust code, but instead *primarily*
|
||||
that editions are *not* about breaking Rust code, but instead *primarily*
|
||||
about putting together a globally coherent, polished product on a regular basis,
|
||||
while providing some opt-in ways to allow for evolution not possible today.
|
||||
|
||||
|
@ -415,9 +415,9 @@ including:
|
|||
|
||||
- The fact that, if you do nothing, your code should continue to compile (with
|
||||
minimum hassle) when upgrading the compiler.
|
||||
- If you resolve deprecations as they occur, moving to a new epoch should also
|
||||
- If you resolve deprecations as they occur, moving to a new edition should also
|
||||
require minimum hassle.
|
||||
- Best practices about upgrading epochs (TBD).
|
||||
- Best practices about upgrading editions (TBD).
|
||||
|
||||
[previous posts]: https://blog.rust-lang.org/2014/10/30/Stability.html
|
||||
|
||||
|
@ -431,35 +431,35 @@ There are several drawbacks to this proposal:
|
|||
|
||||
- To mitigate this, we need to put front and center that, **if you do nothing,
|
||||
updating to a new `rustc` should not be a hassle**, and **staying on an old
|
||||
epoch doesn't cut you off from the ecosystem**.
|
||||
edition doesn't cut you off from the ecosystem**.
|
||||
|
||||
- It adds a degree of complication to an evolution story that is already
|
||||
somewhat complex (with release channels and rapid releases).
|
||||
|
||||
- On the other hand, epoch releases provide greater clarity about major
|
||||
- On the other hand, edition releases provide greater clarity about major
|
||||
steps in Rust evolution, for those who are not following development
|
||||
closely.
|
||||
|
||||
- New epochs can invalidate existing blog posts and documentation, a problem we
|
||||
suffered a lot around the 1.0 release
|
||||
- New editions can invalidate existing blog posts and documentation, a problem
|
||||
we suffered a lot around the 1.0 release
|
||||
|
||||
- However, this situation already obtains in the sense of changing idioms; a
|
||||
blog post using `try!` these days already feels like it's using "old
|
||||
Rust". Notably, though, the code still compiles on current Rust.
|
||||
|
||||
- A saving grace is that, with epochs, it's more likely that a post will
|
||||
mention what epoch is being used, for context. Moreover, with sufficient
|
||||
- A saving grace is that, with editions, it's more likely that a post will
|
||||
mention what edition is being used, for context. Moreover, with sufficient
|
||||
work on error messages, it seems plausible to detect that code was intended
|
||||
for an earlier epochs and explain the situation.
|
||||
for an earlier editions and explain the situation.
|
||||
|
||||
These downsides are most problematic in cases that involve "breakage" if they
|
||||
were done without opt in. They indicate that, even if we do adopt epochs, we
|
||||
were done without opt in. They indicate that, even if we do adopt editions, we
|
||||
should use them judiciously.
|
||||
|
||||
# Alternatives
|
||||
[alternatives]: #alternatives
|
||||
|
||||
## Within the basic epoch structure
|
||||
## Within the basic edition structure
|
||||
|
||||
There was a significant amount of discussion on the RFC thread about using "2.0"
|
||||
rather than "2019". It's difficult to concisely summarize this discussion, but
|
||||
|
@ -468,18 +468,18 @@ is more honest and easier to understand, while others worry that it will be
|
|||
misconstrued no matter how much we caveat it, and that we cannot risk Rust being
|
||||
perceived as unstable or risky.
|
||||
|
||||
- The "epoch" terminology and current framing arose from this discussion,
|
||||
- The "edition" terminology and current framing arose from this discussion,
|
||||
as a way of clarifying what we intend -- i.e., that the concept is
|
||||
*primarily* about putting together a coherent package -- and as a heads up
|
||||
that the model is different from that of other languages.
|
||||
|
||||
Sticking with the basic idea of epochs, there are a couple alternative setups
|
||||
that avoid "preview" epochs:
|
||||
Sticking with the basic idea of editions, there are a couple alternative setups
|
||||
that avoid "preview" editions:
|
||||
|
||||
- Rather than locking in a set of deprecations up front, we could provide
|
||||
"stable channel feature gates", allowing users to opt in to features of the
|
||||
next epoch in a fine-grained way, which may introduce new errors. When
|
||||
the new epoch is released, one would then upgrade to it and remove all of
|
||||
next edition in a fine-grained way, which may introduce new errors. When
|
||||
the new edition is released, one would then upgrade to it and remove all of
|
||||
the gates.
|
||||
|
||||
- The main downside is lack of clarity about what the current "stable Rust"
|
||||
|
@ -495,25 +495,25 @@ that avoid "preview" epochs:
|
|||
coarse-grained flag at the outset.
|
||||
|
||||
- We could stabilize features using undesirable syntax at first, making way for
|
||||
better syntax only when the new epoch is released, then deprecate the "bad"
|
||||
better syntax only when the new edition is released, then deprecate the "bad"
|
||||
syntax in favor of the "good" syntax.
|
||||
|
||||
- For `catch`, this would look like:
|
||||
- Stabilize `do catch`.
|
||||
- Deprecate `catch` as an identifier.
|
||||
- Ship new epoch, which makes `catch` a keyword.
|
||||
- Ship new edition, which makes `catch` a keyword.
|
||||
- Stabilize `catch` as a syntax for the `catch` feature, and deprecate `do catch` in favor of it.
|
||||
- This approach involves significantly more churn than the one proposed in the RFC.
|
||||
|
||||
- Finally, we could just wait to stabilize features like `catch` until the
|
||||
moment the epoch is released.
|
||||
moment the edition is released.
|
||||
|
||||
- This approach seems likely to introduce all the downsides of "feature-based"
|
||||
releases, making the epoch release extremely high stakes, and preventing
|
||||
usage of "ready to go" feature on the stable channel until the epoch is
|
||||
releases, making the edition release extremely high stakes, and preventing
|
||||
usage of "ready to go" feature on the stable channel until the edition is
|
||||
shipped.
|
||||
|
||||
## Alternatives to epochs
|
||||
## Alternatives to editions
|
||||
|
||||
The larger alternatives include, of course, not trying to solve the problems
|
||||
laid out in the motivation, and instead finding creative alternatives.
|
||||
|
@ -542,12 +542,12 @@ what kinds of changes we want to allow. Downsides:
|
|||
soundness holes? In many cases these are more disruptive than introducing a
|
||||
new keyword.
|
||||
|
||||
- Is "epoch" the right key in Cargo.toml? Would it be more clear to just say `rust = "2019"`?
|
||||
- Is "edition" the right key in Cargo.toml? Would it be more clear to just say `rust = "2019"`?
|
||||
|
||||
- Will we ever consider dropping support for very old epochs? Given the
|
||||
- Will we ever consider dropping support for very old editions? Given the
|
||||
constraints in this RFC, it seems unlikely to ever be worth it.
|
||||
|
||||
- Should `rustc` default to the latest epoch instead?
|
||||
- Should `rustc` default to the latest edition instead?
|
||||
|
||||
- How do we handle macros, particularly procedural macros, that may mix source
|
||||
from multiple epochs?
|
||||
from multiple editions?
|
||||
|
|
|
@ -218,10 +218,10 @@ Although the mechanism for opt-in for the long-term solution is unspecified, the
|
|||
actual usage of tool attributes seems pretty clear. Therefore we can be reasonably
|
||||
confident that this proposal is forward-compatible in its syntax, etc.
|
||||
|
||||
For the white-listed tools, will their names be implicitly imported in the long-
|
||||
term solution? One could imagine either leaving them implicit (similar to the
|
||||
libraries prelude) or using warning cycles or an epoch to move them to explicit
|
||||
opt-in.
|
||||
For the white-listed tools, will their names be implicitly imported in the
|
||||
long-term solution? One could imagine either leaving them implicit (similar to
|
||||
the libraries prelude) or using warning cycles or an edition to move them to
|
||||
explicit opt-in.
|
||||
|
||||
|
||||
# Drawbacks
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
# Summary
|
||||
[summary]: #summary
|
||||
|
||||
Introduce a new `dyn Trait` syntax for trait objects using a contextual `dyn` keyword, and deprecate "bare trait" syntax for trait objects. In a future epoch, `dyn` will become a proper keyword and a lint against bare trait syntax will become deny-by-default.
|
||||
Introduce a new `dyn Trait` syntax for trait objects using a contextual `dyn` keyword, and deprecate "bare trait" syntax for trait objects. In a future edition, `dyn` will become a proper keyword and a lint against bare trait syntax will become deny-by-default.
|
||||
|
||||
# Motivation
|
||||
[motivation]: #motivation
|
||||
|
||||
### In a nutshell
|
||||
|
||||
The current syntax is often ambiguous and confusing, even to veterans, and favors a feature that is not more frequently used than its alternatives, is sometimes slower, and often cannot be used at all when its alternatives can. By itself, that's not enough to make a breaking change to syntax that's already been stabilized. Now that we have epochs, it won't have to be a breaking change, but it will still cause significant churn. However, impl Trait is going to require a significant shift in idioms and teaching materials all on its own, and "dyn Trait vs impl Trait" is much nicer for teaching and ergonomics than "bare trait vs impl Trait", so this author believes it is worthwhile to change trait object syntax too.
|
||||
The current syntax is often ambiguous and confusing, even to veterans, and favors a feature that is not more frequently used than its alternatives, is sometimes slower, and often cannot be used at all when its alternatives can. By itself, that's not enough to make a breaking change to syntax that's already been stabilized. Now that we have editions, it won't have to be a breaking change, but it will still cause significant churn. However, impl Trait is going to require a significant shift in idioms and teaching materials all on its own, and "dyn Trait vs impl Trait" is much nicer for teaching and ergonomics than "bare trait vs impl Trait", so this author believes it is worthwhile to change trait object syntax too.
|
||||
|
||||
Motivation is the key issue for this RFC, so let's expand on some of those claims:
|
||||
|
||||
|
@ -74,15 +74,15 @@ The functionality of `dyn Trait` is identical to today's trait object syntax.
|
|||
|
||||
### Migration
|
||||
|
||||
On the current epoch:
|
||||
On the current edition:
|
||||
- The `dyn` keyword will be added, and will be a contextual keyword
|
||||
- A lint against bare trait syntax will be added
|
||||
|
||||
In the next epoch:
|
||||
In the next edition:
|
||||
- `dyn` becomes a real keyword, uses of it as an identifier become hard errors
|
||||
- The bare trait syntax lint is raised to deny-by-default
|
||||
|
||||
This follows the policy laid out in the epochs RFC, where a hard error is "only available when the deprecation is expected to hit a relatively small percentage of code." Adding the `dyn` keyword is unlikely to affect much code, but removing bare trait syntax will clearly affect a lot of code, so only the latter change is implemented as a deny-by-default lint.
|
||||
This follows the policy laid out in the editions RFC, where a hard error is "only available when the deprecation is expected to hit a relatively small percentage of code." Adding the `dyn` keyword is unlikely to affect much code, but removing bare trait syntax will clearly affect a lot of code, so only the latter change is implemented as a deny-by-default lint.
|
||||
|
||||
# Drawbacks
|
||||
[drawbacks]: #drawbacks
|
||||
|
@ -104,7 +104,7 @@ This author believes that `dyn` is a better choice because the notion of "dynami
|
|||
|
||||
We could also use a more radical syntax for trait objects. `Object<Trait>` was suggested on the original RFC thread but didn't gain much traction, presumably because it adds more "noise" than a keyword and is arguably misleading.
|
||||
|
||||
Finally, we could repurpose bare trait syntax for something other than trait objects. It's been frequently suggested in the past that impl Trait would be a far better candidate for bare trait syntax than trait objects. Even this RFC's motivation section indirectly argues for this, e.g. impl Trait does work with all traits and does not carry a runtime cost, unlike trait objects. However, this RFC does not propose repurposing bare trait syntax yet, only deprecating and removing it. This author believes dyn Trait is worth adding even if we never repurpose bare trait, and repurposing it has some significant downsides that dyn Trait does not (such as creating the possibility of code that compiles in two different epochs with radically different semantics). This author believes the repurposing debate should come later, probably after impl Trait and dyn Trait have been stabilized.
|
||||
Finally, we could repurpose bare trait syntax for something other than trait objects. It's been frequently suggested in the past that impl Trait would be a far better candidate for bare trait syntax than trait objects. Even this RFC's motivation section indirectly argues for this, e.g. impl Trait does work with all traits and does not carry a runtime cost, unlike trait objects. However, this RFC does not propose repurposing bare trait syntax yet, only deprecating and removing it. This author believes dyn Trait is worth adding even if we never repurpose bare trait, and repurposing it has some significant downsides that dyn Trait does not (such as creating the possibility of code that compiles in two different editions with radically different semantics). This author believes the repurposing debate should come later, probably after impl Trait and dyn Trait have been stabilized.
|
||||
|
||||
# Unresolved questions
|
||||
[unresolved]: #unresolved-questions
|
||||
|
|
|
@ -277,7 +277,7 @@ impl<T> VecIter<'_, T> { ... }
|
|||
# Reference-level explanation
|
||||
[reference-level-explanation]: #reference-level-explanation
|
||||
|
||||
**Note: these changes are designed to *not* require a new epoch**. They do
|
||||
**Note: these changes are designed to *not* require a new edition**. They do
|
||||
expand our naming style lint, however.
|
||||
|
||||
## Lifetimes in `impl` headers
|
||||
|
|
|
@ -13,11 +13,11 @@ This RFC seeks to clarify and streamline Rust's story around paths and visibilit
|
|||
- The `crate` keyword also acts as a visibility modifier, equivalent to today's `pub(crate)`. Consequently, uses of bare `pub` on items that are not actually publicly exported are linted, suggesting `crate` visibility instead.
|
||||
- A `foo.rs` and `foo/` subdirectory may coexist; `mod.rs` is no longer needed when placing submodules in a subdirectory.
|
||||
|
||||
**These changes do not require a new epoch**. The new features are purely additive. They can ship with **allow-by-default** lints, which can gradually be moved to warn-by-default and deny-by-default over time, as better tooling is developed and more code has actively made the switch.
|
||||
**These changes do not require a new edition**. The new features are purely additive. They can ship with **allow-by-default** lints, which can gradually be moved to warn-by-default and deny-by-default over time, as better tooling is developed and more code has actively made the switch.
|
||||
|
||||
*This RFC incorporates some text written by @withoutboats and @cramertj, who have both been involved in the long-running discussions on this topic.*
|
||||
|
||||
[new epoch]: https://github.com/rust-lang/rfcs/pull/2052
|
||||
[new edition]: https://github.com/rust-lang/rfcs/pull/2052
|
||||
|
||||
# Motivation
|
||||
[motivation]: #motivation
|
||||
|
@ -447,7 +447,7 @@ The actual changes in this RFC are fairly small tweaks to the current module
|
|||
system; most of the complexity comes from the migration plans.
|
||||
|
||||
The proposed migration plan is minimally disruptive; **it does not require an
|
||||
epoch**.
|
||||
edition**.
|
||||
|
||||
## Basic changes
|
||||
|
||||
|
@ -507,11 +507,11 @@ and Cargo/the ambient build system is needed.
|
|||
This approach is designed for backwards compatibility, but it means that you
|
||||
cannot have a top-level module and an external crate with the same
|
||||
name. Allowing that would require all fully-qualified paths into the current
|
||||
crate to start with `crate`, which can only be done on a future epoch. We can
|
||||
crate to start with `crate`, which can only be done on a future edition. We can
|
||||
and should consider making such a change eventually, but it is not required for
|
||||
this RFC.
|
||||
|
||||
[epoch]: https://github.com/rust-lang/rfcs/pull/2052
|
||||
[edition]: https://github.com/rust-lang/rfcs/pull/2052
|
||||
[macros 2.0]: https://github.com/rust-lang/rfcs/blob/master/text/1561-macro-naming.md#importing-macros
|
||||
[previous RFC]: https://github.com/rust-lang/rfcs/pull/2088
|
||||
|
||||
|
@ -574,14 +574,14 @@ motivation. The crucial insight of the design is that, by making absolute paths
|
|||
unambiguous about which crate they draw from, we can solve a number of
|
||||
confusions and papercuts with the module system.
|
||||
|
||||
## Epoch-based migration story
|
||||
## Edition-based migration story
|
||||
|
||||
We can avoid the need for fallback in resolution by leveraging epochs instead.
|
||||
On the current epoch, we would make `crate::` paths available and start warning
|
||||
about *not* using them for crate-internal paths, but we would not issue warnings
|
||||
about `extern crate`. In the next epoch, we would change absolute path
|
||||
interpretations, such that warning-free code on the previous epoch would
|
||||
continue to compile and have the same meaning.
|
||||
We can avoid the need for fallback in resolution by leveraging editions
|
||||
instead. On the current edition, we would make `crate::` paths available and
|
||||
start warning about *not* using them for crate-internal paths, but we would not
|
||||
issue warnings about `extern crate`. In the next edition, we would change
|
||||
absolute path interpretations, such that warning-free code on the previous
|
||||
edition would continue to compile and have the same meaning.
|
||||
|
||||
## Bike-sheddy choices
|
||||
|
||||
|
@ -652,6 +652,6 @@ ideas off into a separate *experimental* RFC:
|
|||
# Unresolved questions
|
||||
[unresolved]: #unresolved-questions
|
||||
|
||||
- How should we approach migration? Via a fallback, as proposed, or via epochs?
|
||||
It is probably best to make this determination with more experience,
|
||||
- How should we approach migration? Via a fallback, as proposed, or via
|
||||
editions? It is probably best to make this determination with more experience,
|
||||
e.g. after we have a `rustfix` tool in hand.
|
||||
|
|
|
@ -7,16 +7,17 @@
|
|||
[summary]: #summary
|
||||
|
||||
Add a raw identifier format `r#ident`, so crates written in future language
|
||||
epochs/versions can still use an older API that overlaps with new keywords.
|
||||
editions/versions can still use an older API that overlaps with new keywords.
|
||||
|
||||
# Motivation
|
||||
[motivation]: #motivation
|
||||
|
||||
One of the primary examples of breaking changes in the epoch RFC is to add new
|
||||
keywords, and specifically `catch` is the first candidate. However, since
|
||||
that's seeking crate compatibility across epochs, this would leave a crate in a
|
||||
newer epoch unable to use `catch` identifiers in the API of a crate in an older
|
||||
epoch. [@matklad found] 28 crates using `catch` identifiers, some public.
|
||||
One of the primary examples of breaking changes in the edition RFC is to add
|
||||
new keywords, and specifically `catch` is the first candidate. However, since
|
||||
that's seeking crate compatibility across editions, this would leave a crate in
|
||||
a newer edition unable to use `catch` identifiers in the API of a crate in an
|
||||
older edition. [@matklad found] 28 crates using `catch` identifiers, some
|
||||
public.
|
||||
|
||||
A raw syntax that's *always* an identifier would allow these to remain
|
||||
compatible, so one can write `r#catch` where `catch`-as-identifier is needed.
|
||||
|
@ -57,14 +58,14 @@ they are mentioned, making them cumbersome to both the developer and users.
|
|||
Usually an alternate is preferable: `crate` -> `krate`, `const` -> `constant`,
|
||||
etc.
|
||||
|
||||
However, new Rust epochs may add to the list of reserved keywords, making a
|
||||
formerly legal identifier now interpreted otherwise. Since compatibility is
|
||||
maintained between crates of different epochs, this could mean that code written
|
||||
in a new epoch might not be able to name an identifier in the API of another
|
||||
crate. Using a raw identifier, it can still be named and used.
|
||||
However, new Rust editions may add to the list of reserved keywords, making a
|
||||
formerly legal identifier now interpreted otherwise. Since compatibility is
|
||||
maintained between crates of different editions, this could mean that code
|
||||
written in a new edition might not be able to name an identifier in the API of
|
||||
another crate. Using a raw identifier, it can still be named and used.
|
||||
|
||||
```rust
|
||||
//! baseball.rs in epoch 2015
|
||||
//! baseball.rs in edition 2015
|
||||
pub struct Ball;
|
||||
pub struct Player;
|
||||
impl Player {
|
||||
|
@ -74,7 +75,7 @@ impl Player {
|
|||
```
|
||||
|
||||
```rust
|
||||
//! main.rs in epoch 2018 -- `catch` is now a keyword!
|
||||
//! main.rs in edition 2018 -- `catch` is now a keyword!
|
||||
use baseball::*;
|
||||
fn main() {
|
||||
let mut player = Player;
|
||||
|
@ -107,9 +108,10 @@ let bar = r#foo * 2;
|
|||
[alternatives]: #alternatives
|
||||
|
||||
If we don't have any way to refer to identifiers that were legal in prior
|
||||
epochs, but later became keywords, then this may hurt interoperability between
|
||||
crates of different epochs. The `r#ident` syntax enables interoperability, and
|
||||
will hopefully invoke some intuition of being raw, similar to raw strings.
|
||||
editions, but later became keywords, then this may hurt interoperability
|
||||
between crates of different editions. The `r#ident` syntax enables
|
||||
interoperability, and will hopefully invoke some intuition of being raw,
|
||||
similar to raw strings.
|
||||
|
||||
The `br#ident` syntax is also possible, but I see no advantage over `r#ident`.
|
||||
Identifiers don't need the same kind of distinction as `str` and `[u8]`.
|
||||
|
@ -153,12 +155,12 @@ Java also allows Unicode escapes, but they don't avoid keywords.
|
|||
For some new keywords, there may be contextual mitigations. In the case of
|
||||
`catch`, it couldn't be a fully contextual keyword because `catch { ... }` could
|
||||
be a struct literal. That context might be worked around with a path, like
|
||||
`old_epoch::catch { ... }` to use an identifier instead. Contexts that don't
|
||||
`old_edition::catch { ... }` to use an identifier instead. Contexts that don't
|
||||
make sense for a `catch` expression can just be identifiers, like `foo.catch()`.
|
||||
However, this might not be possible for all future keywords.
|
||||
|
||||
There might also be a need for raw keywords in the other direction, e.g. so the
|
||||
older epoch can still use the new `catch` functionality somehow. I think this
|
||||
older edition can still use the new `catch` functionality somehow. I think this
|
||||
particular case is already served well enough by `do catch { ... }`, if we
|
||||
choose to stabilize it that way. Perhaps `br#keyword` could be used for this,
|
||||
but that may not be a good intuitive relationship.
|
||||
|
@ -175,4 +177,4 @@ but that may not be a good intuitive relationship.
|
|||
|
||||
- Do macros need any special care with such identifier tokens?
|
||||
- Should diagnostics use the `r#` syntax when printing identifiers that overlap keywords?
|
||||
- Does rustdoc need to use the `r#` syntax? e.g. to document `pub use old_epoch::*`
|
||||
- Does rustdoc need to use the `r#` syntax? e.g. to document `pub use old_edition::*`
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
This RFC sets the *Rust 2018 Roadmap*, in accordance with [RFC 1728](https://github.com/rust-lang/rfcs/pull/1728). This year's goals are:
|
||||
|
||||
|
||||
- Ship an epoch release: Rust 2018.
|
||||
- Ship an edition release: Rust 2018.
|
||||
- Build resources for intermediate Rustaceans.
|
||||
- Connect and empower Rust’s global community.
|
||||
- Grow Rust’s teams and new leaders within them.
|
||||
|
@ -38,7 +38,7 @@ The motivation and detailed rationale of each piece of the roadmap proposal is e
|
|||
This year will be a focused one for the Rust community, with two overall technical goals, and two social ones. Here we’ll give a brief overview of each goal and some overarching themes, and in the Reference section below we’ll provide full detail.
|
||||
|
||||
|
||||
- **Ship** ***Rust 2018***. We will ship a major marketing (epoch) release in the final third of the year, with the unifying message of *productivity*. We will continue to focus on compiler performance, both from-scratch and incremental rebuilds. We will polish and stabilize a number of already-implemented language features like `impl Trait`, macros 2.0, SIMD, generators, non-lexical lifetimes and the modules revamp—and very few new ones. We will also drive critical tools (like the RLS and rustfmt), libraries, and documentation to 1.0 status. We will overhaul the http://rust-lang.org/ site to help market the release and to support programmer productivity.
|
||||
- **Ship** ***Rust 2018***. We will ship a major marketing (edition) release in the final third of the year, with the unifying message of *productivity*. We will continue to focus on compiler performance, both from-scratch and incremental rebuilds. We will polish and stabilize a number of already-implemented language features like `impl Trait`, macros 2.0, SIMD, generators, non-lexical lifetimes and the modules revamp—and very few new ones. We will also drive critical tools (like the RLS and rustfmt), libraries, and documentation to 1.0 status. We will overhaul the http://rust-lang.org/ site to help market the release and to support programmer productivity.
|
||||
|
||||
|
||||
- **Build resources for intermediate Rustaceans**. We will write documentation and build examples that help programmers go from basic knowledge of Rust’s mechanics to knowing how to wield it effectively.
|
||||
|
@ -66,26 +66,26 @@ Looking at the year as a whole, with our second marketing release of Rust, @nrc
|
|||
|
||||
## Goals
|
||||
|
||||
### Ship Rust epoch 2018
|
||||
### Ship Rust edition 2018
|
||||
|
||||
|
||||
> [Aiming for a major product release gives us an opportunity, as a community, to come together and do something big that goes well beyond the usual six week cycle.](http://aturon.github.io/blog/2018/01/09/rust-2018/)
|
||||
>
|
||||
> [Releasing “Rust 2018” gives us a chance to say to the world that “Rust has taken a major step since 1.0; it’s time to take another look”.](http://aturon.github.io/blog/2018/01/09/rust-2018/) (@aturon)
|
||||
|
||||
The Rust epoch 2018 release encompasses every aspect of the work we do, so we’ll look at each area in turn. **This RFC is not intended as a** ***promise*** **about what will ship, but rather a strong (and realistic) intention.** The core team will ultimately oversee the precise timing and feature set of the release.
|
||||
The Rust edition 2018 release encompasses every aspect of the work we do, so we’ll look at each area in turn. **This RFC is not intended as a** ***promise*** **about what will ship, but rather a strong (and realistic) intention.** The core team will ultimately oversee the precise timing and feature set of the release.
|
||||
|
||||
It’s important to keep in mind two additional factors:
|
||||
|
||||
|
||||
- “Shipping” features in this context means they must be *stable*. We may land additional unstable features this year (like `const` generics), but these are separate from the Rust 2018 product. **We will stabilize features individually as they become ready,** ***not*** **in a rush before the epoch release.**
|
||||
- “Shipping” features in this context means they must be *stable*. We may land additional unstable features this year (like `const` generics), but these are separate from the Rust 2018 product. **We will stabilize features individually as they become ready,** ***not*** **in a rush before the edition release.**
|
||||
|
||||
|
||||
- The intent is to ship Rust 2018 in the latter part of the year. The tentative target date is the 1.29 release, which goes into beta on 2018-08-02 and ships on 2018-09-13. That gives us approximately six months to put the product together.
|
||||
|
||||
**These two factors together suggest that Rust 2018 will ship largely with** ***language*** **features that are already in nightly in some form today.** Other, faster-moving areas of the product will be developing new material throughout the year.
|
||||
|
||||
As always, we will continue to push out new Rust releases on a six week cadence, so a given feature missing the epoch release is by no means fatal. On the other hand, we need to carefully coordinate the work so that the features we *do* ship sit together coherently across the compiler, tools, documentation, libraries and marketing materials.
|
||||
As always, we will continue to push out new Rust releases on a six week cadence, so a given feature missing the edition release is by no means fatal. On the other hand, we need to carefully coordinate the work so that the features we *do* ship sit together coherently across the compiler, tools, documentation, libraries and marketing materials.
|
||||
|
||||
#### Language
|
||||
|
||||
|
@ -104,7 +104,7 @@ Among these productivity features are a few “headliners” that will form the
|
|||
- **Generators**. “Beta” state on nightly, but some design issues need resolution.
|
||||
- **Module system changes**. Largely usable on nightly; will need testing, feedback, and bikeshedding.
|
||||
|
||||
In addition, there are some other headlining features which are nearing stabilization and should ship prior to the epoch:
|
||||
In addition, there are some other headlining features which are nearing stabilization and should ship prior to the edition:
|
||||
|
||||
|
||||
- **SIMD**. The core SIMD intrinsics are nearing readiness for stabilization, and with luck we may be able to stabilize some vendor-agnostic primitives as well.
|
||||
|
@ -113,11 +113,11 @@ In addition, there are some other headlining features which are nearing stabiliz
|
|||
|
||||
Between generators and macros 2.0, we will have *some* support for async/await on stable Rust (possibly using macros, possibly some other way).
|
||||
|
||||
Finally, there are several highly-awaited features that are **unlikely to ship** **in the Rust 2018** **epoch release** **(though they may ship later in the year):**
|
||||
Finally, there are several highly-awaited features that are **unlikely to ship** **in the Rust 2018** **edition release** **(though they may ship later in the year):**
|
||||
|
||||
|
||||
- **Generic associated types**. This feature will almost certainly land in *nightly* in 2018, and may even stabilize during the year. However, enough implementation work remains that it’s unlikely to be stable prior to the epoch release.
|
||||
- **Specialization**. Stabilization is blocked on a number of *extremely* subtle issues, including a revamp of the trait system and [finding a route to soundness](http://aturon.github.io/blog/2017/07/08/lifetime-dispatch/). We cannot afford to spend time on these issues until after the epoch release ships.
|
||||
- **Generic associated types**. This feature will almost certainly land in *nightly* in 2018, and may even stabilize during the year. However, enough implementation work remains that it’s unlikely to be stable prior to the edition release.
|
||||
- **Specialization**. Stabilization is blocked on a number of *extremely* subtle issues, including a revamp of the trait system and [finding a route to soundness](http://aturon.github.io/blog/2017/07/08/lifetime-dispatch/). We cannot afford to spend time on these issues until after the edition release ships.
|
||||
- **const generics**. This feature is likely to land in *nightly* in 2018, but will not be ready to stabilize this year given the substantial work that remains.
|
||||
|
||||
#### Compiler
|
||||
|
@ -128,10 +128,10 @@ Finally, there are several highly-awaited features that are **unlikely to ship**
|
|||
Compiler work will center on:
|
||||
|
||||
|
||||
- A steady focus on compiler performance leading up to the epoch release. We will pursue two strategies in parallel: continuing to push incremental recompilation into earlier stages of the compiler, but also looking for general improvements that help even with from-scratch compilation. For the latter, avenues include compiler parallelization and MIR-only rlibs, amongst others. We will formulate a comprehensive set of compilation scenarios and corresponding benchmarks and set targets for the epoch release (see the [tracking issue](https://github.com/rust-lang/rust/issues/48547) for some details). Finally, we will spin up a dedicated Compiler Performance Working Group to focus on this area.
|
||||
- A steady focus on compiler performance leading up to the edition release. We will pursue two strategies in parallel: continuing to push incremental recompilation into earlier stages of the compiler, but also looking for general improvements that help even with from-scratch compilation. For the latter, avenues include compiler parallelization and MIR-only rlibs, amongst others. We will formulate a comprehensive set of compilation scenarios and corresponding benchmarks and set targets for the edition release (see the [tracking issue](https://github.com/rust-lang/rust/issues/48547) for some details). Finally, we will spin up a dedicated Compiler Performance Working Group to focus on this area.
|
||||
- Completing and polishing the language features mentioned above.
|
||||
- Another push on improving error messages.
|
||||
- Epoch tooling: adding an epoch flag and building `rustfix`, likely by leveraging lints.
|
||||
- Edition tooling: adding an edition flag and building `rustfix`, likely by leveraging lints.
|
||||
|
||||
#### Libraries
|
||||
|
||||
|
@ -147,7 +147,7 @@ Compiler work will center on:
|
|||
|
||||
> [The core team should participate in prioritizing and implementing quality crates for productivity needs.](https://medium.com/@nimtiazm/rust-and-crate-of-wishes-for-2018-1258f6977d42) (@nimtiazm)
|
||||
|
||||
In preparation for the epoch release, we will continue to invest in Rust’s library ecosystem in three ways:
|
||||
In preparation for the edition release, we will continue to invest in Rust’s library ecosystem in three ways:
|
||||
|
||||
|
||||
- **Quality**. Building on our 2017 work, we will bring the API Guidelines to a 1.0 status and build out additional resources to aid library authors.
|
||||
|
@ -156,19 +156,19 @@ In preparation for the epoch release, we will continue to invest in Rust’s lib
|
|||
|
||||
#### Documentation
|
||||
|
||||
Documentation plays a *critical* role in the epoch release, as it’s often an entry point for people who are taking a look at Rust thanks to our marketing push. With regards to the epoch specifically, this mostly means updating the online version of “The Rust Programming Language” to include all of the new things that are being stabilized in the first part of the year.
|
||||
Documentation plays a *critical* role in the edition release, as it’s often an entry point for people who are taking a look at Rust thanks to our marketing push. With regards to the edition specifically, this mostly means updating the online version of “The Rust Programming Language” to include all of the new things that are being stabilized in the first part of the year.
|
||||
|
||||
We’ll also be doing a lot of work on Rust By Example. This resource is both critical for our users and also slightly neglected; we’re starting to put together a small team to give it some love, and so we hope to improve it significantly from there.
|
||||
|
||||
There are two additional areas of vital documentation work for 2018, which are not *necessarily* tied to the epoch release:
|
||||
There are two additional areas of vital documentation work for 2018, which are not *necessarily* tied to the edition release:
|
||||
|
||||
|
||||
- **Resources for intermediate Rustaceans**. This topic is covered in detail below. It’s possible that some of these resources will be ready to go by the epoch release.
|
||||
- **Overhauled rustdoc**. There’s ongoing work on an RLS-based edition of rustdoc with internationalization support, and the ability to seamlessly integrate “guide” and “reference”-style documentation. As a stretch goal for the epoch, we could aim to have this shipped and major libraries using it to provide a better documentation experience.
|
||||
- **Resources for intermediate Rustaceans**. This topic is covered in detail below. It’s possible that some of these resources will be ready to go by the edition release.
|
||||
- **Overhauled rustdoc**. There’s ongoing work on an RLS-based edition of rustdoc with internationalization support, and the ability to seamlessly integrate “guide” and “reference”-style documentation. As a stretch goal for the edition, we could aim to have this shipped and major libraries using it to provide a better documentation experience.
|
||||
|
||||
#### Tools
|
||||
|
||||
As part of the Rust 2018 epoch release, we will:
|
||||
As part of the Rust 2018 edition release, we will:
|
||||
|
||||
|
||||
- Ship 1.0 editions of the RLS and `rustfmt`, distributed via `rustup`.
|
||||
|
@ -177,13 +177,13 @@ As part of the Rust 2018 epoch release, we will:
|
|||
- Implement and stabilize [public dependencies](https://github.com/rust-lang/rfcs/pull/1977) in Cargo.
|
||||
- Revise Cargo profiles.
|
||||
|
||||
Beyond these clear-cut items, there are a number of ongoing efforts, some of which *may* ship as part of the epoch:
|
||||
Beyond these clear-cut items, there are a number of ongoing efforts, some of which *may* ship as part of the edition:
|
||||
|
||||
|
||||
- **Xargo/Cargo integration**. Alternatively, this can be viewed as allowing `std` to be treated as an explicit dependency in Cargo, which has long been a requested feature and which is very helpful for cross-compilation (and hence for embedded device work).
|
||||
- **Build system integration improvements**. Seek to incrementally deliver on the [work laid out in 2017](https://github.com/rust-lang/rfcs/pull/2136). It’s unclear what pieces might be ready for stabilization prior to the epoch release.
|
||||
- **Build system integration improvements**. Seek to incrementally deliver on the [work laid out in 2017](https://github.com/rust-lang/rfcs/pull/2136). It’s unclear what pieces might be ready for stabilization prior to the edition release.
|
||||
|
||||
And a couple of goals that are probably a stretch for 2018 at all, let alone for the epoch release:
|
||||
And a couple of goals that are probably a stretch for 2018 at all, let alone for the edition release:
|
||||
|
||||
- **Custom test frameworks**. There’s been [a lot of interest in this area](https://internals.rust-lang.org/t/past-present-and-future-for-rust-testing/6354/1), and it may be possible that with a dedicated working group we can implement and stabilize test frameworks in 2018.
|
||||
- **Compiler-driven code completion for the RLS**. Today the RLS still uses a purely heuristic approach for auto-completion. If the compiler’s new “query-based” architecture can be pushed far enough during the year, it maybe become feasible to start using it to deliver precise auto-complete information.
|
||||
|
@ -210,7 +210,7 @@ Many, many of the #Rust2018 posts talked about improving our web presence and th
|
|||
|
||||
> [I suggest in 2018, we kick the idea of wrestling with the Rust compiler to the curb and focus on how it helps us rather than the idea of it beating us down.](http://www.jonathanturner.org/2018/01/how-we-talk-about-rust-in-2018.html) (@jonathandturner)
|
||||
|
||||
As part of the 2018 epoch release, we will **completely overhaul the main Rust web site** with:
|
||||
As part of the 2018 edition release, we will **completely overhaul the main Rust web site** with:
|
||||
|
||||
|
||||
- **A new, striking visual design**, which will eventually be used across all of our web sites (including crates.io).
|
||||
|
@ -337,17 +337,17 @@ The remainder of the year will be broken up into four chunks:
|
|||
- Feb — Mar: **Design and early work**.
|
||||
- Apr — July: **Buckling down**.
|
||||
- Aug — Nov: **Fun**!
|
||||
- August 2: **Epoch in beta**
|
||||
- September 13: **Epoch released**
|
||||
- August 2: **Edition in beta**
|
||||
- September 13: **Edition released**
|
||||
- Dec — EOY: **Reflection**.
|
||||
|
||||
**Design and early work**. Coming off of the impl period, for the start of this year we’ll take some time to process RFCs, to plan, and to spike any late-breaking design ideas that could possibly ship in the Rust 2018 epoch release. We will, of course, continue to push on implementation and stabilization work at the same time. By the end of this period, we should have a very clear picture of what we will ship in the epoch, and what needs to happen to do that.
|
||||
**Design and early work**. Coming off of the impl period, for the start of this year we’ll take some time to process RFCs, to plan, and to spike any late-breaking design ideas that could possibly ship in the Rust 2018 edition release. We will, of course, continue to push on implementation and stabilization work at the same time. By the end of this period, we should have a very clear picture of what we will ship in the edition, and what needs to happen to do that.
|
||||
|
||||
This period culminates with the Rust Team All Hands in Berlin at the end of March.
|
||||
|
||||
**Buckling down**. Structured much like the impl period, we will be laser-focused on making the epoch release as good as it can be. It will be a community-wide effort. Little to no design or RFC work will happen during this time. RustFest Paris and a Mozilla all-hands will happen during this time, and we will likely try to host “impl days” similar to last year.
|
||||
**Buckling down**. Structured much like the impl period, we will be laser-focused on making the edition release as good as it can be. It will be a community-wide effort. Little to no design or RFC work will happen during this time. RustFest Paris and a Mozilla all-hands will happen during this time, and we will likely try to host “impl days” similar to last year.
|
||||
|
||||
This period culminates with cutting the beta epoch release at the beginning of August, with RustConf following shortly after.
|
||||
This period culminates with cutting the beta edition release at the beginning of August, with RustConf following shortly after.
|
||||
|
||||
**Fun**! Having pushed hard up to this point, for the remainder of the year we will relax our tight focus and allow for more exploration, as well as work on fun features like const generics, GATs, and specialization. Rust Belt Rust will happen during this period.
|
||||
|
||||
|
|
Loading…
Reference in New Issue