Skip to content

Commit c8e07ab

Browse files
committed
add miration plan requirement, describing tying to syntax
1 parent 00ec487 commit c8e07ab

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

text/0000-edition-2021.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,55 @@ The expected workflow for upgrading to a new edition is as follows:
127127
* In some cases, these lints may be cleaning up "non-idiomatic" code produced by a migration.
128128
* **Manual changes:** As the final step, resolve any remaining lints or errors manually (hopefully these will be quite limited). Idiom lints, in particular, may not have automated suggestions, though you can always add an `#![allow]` at the crate level to silence them if you are in a hurry.
129129

130+
## Specifying edition changes and migration plans
131+
132+
Any RFC or other proposal that will cause code that used to compile on edition `N` no longer compiles on edition `N+1` must include detais of how the "current edition" for that change is determined as well a migration plan.
133+
134+
### Determining the current edition
135+
136+
Altough there is an "ambient" edition for the crate that is specified as part of `Cargo.toml`, individual bits of code can be tied to earlier editions due to the interactions of macros. For example, if a Rust 2021 crate invokes a macro from a Rust 2018 crate, the body of that macro may be interpreted using Rust 2018 rules. For this reason, whenever an edition change is proposed, it's important to specify the tokens from which the edition is determined.
137+
138+
As an example, if we are introducing a new keyword, then the edition will be taken from the keyword itself. If we were to make a change to the semantics of the `+` operator, we might say that the current edition is determined from the `+` token. This way, if a macro author were to write `$a + $b`, then this expression would use the edition rules from the macro definition (which contained the `+` token). Additions that defined in the `$a` expression would use the edition from which `$a` was derived.
139+
140+
### Migration plans
141+
142+
These migration plans should be structured as the answer to three questions; these questions are designed to compartmentalize review and implementation.
143+
144+
The three questions are:
145+
146+
* What code patterns no longer compile (or change meaning) in the new edition?
147+
* Which code patterns will you migrate from the old to the new edition?
148+
* This should be some subset of the answer to the first question.
149+
* What is your plan to migrate each code pattern?
150+
* The plan should include automated suggestions targeting the intersection of Edition N and Edition N+1.
151+
* The plan may also include lints specific to Edition N+1 that will cleanup the code to make it more idiomatic.
152+
153+
More details on these questions follow.
154+
155+
#### What code patterns no longer compile (or change meaning) in the new edition?
156+
157+
The RFC should list **all** known code patterns that are affected by the change in edition, either because they no longer compile or because their meaning changes. This should include unusual breakage that is not expected in practice.
158+
159+
Answering this question is not a commitment to automatically migrate every instance of these code atterns, but it is important for this research to be done during the design phase such that it can be considered when evaluating migration strategies.
160+
161+
Listing these code patterns allows us to make sure the migration is premised on the full set of breakages. This help avoid confusion where people don't recognize what code may be affected.
162+
163+
#### Which code patterns will you migrate from the old to the new edition?
164+
165+
The proposal should then declare what its intended scope for migration is. This may involve declaring some of the listed breakages as out of scope.
166+
167+
Historically we have considered macro-heavy code to be something that edition migrations can try to fix but are not expected to be successful in working on. Similarly, there may be niche breakages that the designers do not expect to crop up in practice.
168+
169+
Listing all this helps correctly set expectations, and also gives people a venue to discuss whether the choice of scope is correct without having to glean the scope from the design of the migrations. Furthermore, if we later discover that an out-of-scope breakage is actually somewhat common, this provides a clean separation in the proposal to work on addressing this.
170+
171+
#### What is your plan to migrate each code pattern?
172+
173+
The proposal should then contain a detailed design for one or more compatibility lints that migrate code such that it will compile on both editions. Such lints can be specified by listing the kinds of code they should catch, and the changes that should be programmatically made to them.
174+
175+
If needed, the proposal may also contain designs for idiom lints that clean up the migrated code (potentially making it compile on the new edition only).
176+
177+
Listing all of this helps allow reviewers to check if the lints seem feasible and whether they do indeed cover the desired code patterns. It also allows implementors to implement a concrete migration plan rather than having to come up with one on the spot.
178+
130179
## Limits of edition changes
131180

132181
Edition changes cannot make arbitrary changes. First and foremost, they must always respect the constraint that crates in different editions can interoperate; this implies that the changes must be "skin deep". In terms of the compiler implementation, what this means is that Edition can change the way that concrete Rust syntax is desugared into MIR (the compiler's internal representation for Rust code), but doesn't change the semantics of MIR itself (or trait matching, etc).

0 commit comments

Comments
 (0)