Skip to content

Commit 9d93b42

Browse files
committed
Add the -Zfix-edition flag
This adds support for parsing the `-Zfix-edition` flag.
1 parent 778ff68 commit 9d93b42

File tree

3 files changed

+92
-30
lines changed

3 files changed

+92
-30
lines changed

src/cargo/core/features.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,45 @@ impl FromStr for Edition {
362362
}
363363
}
364364

365+
/// The value for `-Zfix-edition`.
366+
#[derive(Debug, Deserialize)]
367+
pub enum FixEdition {
368+
/// `-Zfix-edition=start=$INITIAL`
369+
///
370+
/// This mode for `cargo fix` will just run `cargo check` if the current
371+
/// edition is equal to this edition. If it is a different edition, then
372+
/// it just exits with success. This is used for crater integration which
373+
/// needs to set a baseline for the "before" toolchain.
374+
Start(Edition),
375+
/// `-Zfix-edition=end=$INITIAL,$NEXT`
376+
///
377+
/// This mode for `cargo fix` will migrate to the `next` edition if the
378+
/// current edition is `initial`. After migration, it will update
379+
/// `Cargo.toml` and verify that that it works on the new edition. If the
380+
/// current edition is not `initial`, then it immediately exits with
381+
/// success since we just want to ignore those packages.
382+
End { initial: Edition, next: Edition },
383+
}
384+
385+
impl FromStr for FixEdition {
386+
type Err = anyhow::Error;
387+
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
388+
if let Some(start) = s.strip_prefix("start=") {
389+
Ok(FixEdition::Start(start.parse()?))
390+
} else if let Some(end) = s.strip_prefix("end=") {
391+
let (initial, next) = end
392+
.split_once(',')
393+
.ok_or_else(|| anyhow::format_err!("expected `initial,next`"))?;
394+
Ok(FixEdition::End {
395+
initial: initial.parse()?,
396+
next: next.parse()?,
397+
})
398+
} else {
399+
bail!("invalid `-Zfix-edition, expected start= or end=, got `{s}`");
400+
}
401+
}
402+
}
403+
365404
#[derive(Debug, PartialEq)]
366405
enum Status {
367406
Stable,
@@ -791,6 +830,7 @@ unstable_cli_options!(
791830
dual_proc_macros: bool = ("Build proc-macros for both the host and the target"),
792831
feature_unification: bool = ("Enable new feature unification modes in workspaces"),
793832
features: Option<Vec<String>>,
833+
fix_edition: Option<FixEdition> = ("Permanently unstable edition migration helper"),
794834
gc: bool = ("Track cache usage and \"garbage collect\" unused files"),
795835
#[serde(deserialize_with = "deserialize_git_features")]
796836
git: Option<GitFeatures> = ("Enable support for shallow git fetch operations"),
@@ -1298,6 +1338,12 @@ impl CliUnstable {
12981338
"doctest-xcompile" => stabilized_warn(k, "1.89", STABILIZED_DOCTEST_XCOMPILE),
12991339
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
13001340
"feature-unification" => self.feature_unification = parse_empty(k, v)?,
1341+
"fix-edition" => {
1342+
let fe = v
1343+
.ok_or_else(|| anyhow::anyhow!("-Zfix-edition expected a value"))?
1344+
.parse()?;
1345+
self.fix_edition = Some(fe);
1346+
}
13011347
"gc" => self.gc = parse_empty(k, v)?,
13021348
"git" => {
13031349
self.git =

src/doc/src/reference/unstable.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ Each new feature described below should explain how to use it.
126126
* [native-completions](#native-completions) --- Move cargo shell completions to native completions.
127127
* [warnings](#warnings) --- controls warning behavior; options for allowing or denying warnings.
128128
* [Package message format](#package-message-format) --- Message format for `cargo package`.
129+
* [`fix-edition`](#fix-edition) --- A permanently unstable edition migration helper.
129130

130131
## allow-features
131132

@@ -1915,6 +1916,19 @@ When new editions are introduced, the `unstable-editions` feature is required un
19151916

19161917
The special "future" edition is a home for new features that are under development, and is permanently unstable. The "future" edition also has no new behavior by itself. Each change in the future edition requires an opt-in such as a `#![feature(...)]` attribute.
19171918

1919+
## `fix-edition`
1920+
1921+
`-Zfix-edition` is a permanently unstable flag to assist with testing edition migrations, particularly with the use of crater. It only works with the `cargo fix` subcommand. It takes two different forms:
1922+
1923+
- `-Zfix-edition=start=$INITIAL` --- This form checks if the current edition is equal to the given number. If not, it exits with success (because we want to ignore older editions). If it is, then it runs the equivalent of `cargo check`. This is intended to be used with crater's "start" toolchain to set a baseline for the "before" toolchain.
1924+
- `-Zfix-edition=end=$INITIAL,$NEXT` --- This form checks if the current edition is equal to the given `$INITIAL` value. If not, it exits with success. If it is, then it performs an edition migration to the edition specified in `$NEXT`. Afterwards, it will modify `Cargo.toml` to add the appropriate `cargo-features = ["unstable-edition"]`, update the `edition` field, and run the equivalent of `cargo check` to verify that the migration works on the new edition.
1925+
1926+
For example:
1927+
1928+
```console
1929+
cargo +nightly fix -Zfix-edition=end=2024,future
1930+
```
1931+
19181932
# Stabilized and removed features
19191933

19201934
## Compile progress

tests/testsuite/cargo/z_help/stdout.term.svg

Lines changed: 32 additions & 30 deletions
Loading

0 commit comments

Comments
 (0)