Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,45 @@ impl FromStr for Edition {
}
}

/// The value for `-Zfix-edition`.
#[derive(Debug, Deserialize)]
pub enum FixEdition {
/// `-Zfix-edition=start=$INITIAL`
///
/// This mode for `cargo fix` will just run `cargo check` if the current
/// edition is equal to this edition. If it is a different edition, then
/// it just exits with success. This is used for crater integration which
/// needs to set a baseline for the "before" toolchain.
Start(Edition),
/// `-Zfix-edition=end=$INITIAL,$NEXT`
///
/// This mode for `cargo fix` will migrate to the `next` edition if the
/// current edition is `initial`. After migration, it will update
/// `Cargo.toml` and verify that that it works on the new edition. If the
/// current edition is not `initial`, then it immediately exits with
/// success since we just want to ignore those packages.
End { initial: Edition, next: Edition },
}

impl FromStr for FixEdition {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
if let Some(start) = s.strip_prefix("start=") {
Ok(FixEdition::Start(start.parse()?))
} else if let Some(end) = s.strip_prefix("end=") {
let (initial, next) = end
.split_once(',')
.ok_or_else(|| anyhow::format_err!("expected `initial,next`"))?;
Ok(FixEdition::End {
initial: initial.parse()?,
next: next.parse()?,
})
} else {
bail!("invalid `-Zfix-edition, expected start= or end=, got `{s}`");
}
}
}

#[derive(Debug, PartialEq)]
enum Status {
Stable,
Expand Down Expand Up @@ -791,6 +830,7 @@ unstable_cli_options!(
dual_proc_macros: bool = ("Build proc-macros for both the host and the target"),
feature_unification: bool = ("Enable new feature unification modes in workspaces"),
features: Option<Vec<String>>,
fix_edition: Option<FixEdition> = ("Permanently unstable edition migration helper"),
gc: bool = ("Track cache usage and \"garbage collect\" unused files"),
#[serde(deserialize_with = "deserialize_git_features")]
git: Option<GitFeatures> = ("Enable support for shallow git fetch operations"),
Expand Down Expand Up @@ -1298,6 +1338,12 @@ impl CliUnstable {
"doctest-xcompile" => stabilized_warn(k, "1.89", STABILIZED_DOCTEST_XCOMPILE),
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
"feature-unification" => self.feature_unification = parse_empty(k, v)?,
"fix-edition" => {
let fe = v
.ok_or_else(|| anyhow::anyhow!("-Zfix-edition expected a value"))?
.parse()?;
self.fix_edition = Some(fe);
}
"gc" => self.gc = parse_empty(k, v)?,
"git" => {
self.git =
Expand Down
14 changes: 14 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Each new feature described below should explain how to use it.
* [native-completions](#native-completions) --- Move cargo shell completions to native completions.
* [warnings](#warnings) --- controls warning behavior; options for allowing or denying warnings.
* [Package message format](#package-message-format) --- Message format for `cargo package`.
* [`fix-edition`](#fix-edition) --- A permanently unstable edition migration helper.

## allow-features

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

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.

## `fix-edition`

`-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:
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to have any line wrap here, or follow https://sembr.org/?
I am forgetting what the style we currently adopt.

Choose a reason for hiding this comment

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

On the Reference and other documents we're just unwrapping now.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good. Thanks for the clarification. I'll merge as-is.


- `-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.
- `-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.

For example:

```console
cargo +nightly fix -Zfix-edition=end=2024,future
```

# Stabilized and removed features

## Compile progress
Expand Down
62 changes: 32 additions & 30 deletions tests/testsuite/cargo/z_help/stdout.term.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.