diff --git a/src/cargo/ops/fix.rs b/src/cargo/ops/fix.rs index 9d721b71759..a56a2c217bb 100644 --- a/src/cargo/ops/fix.rs +++ b/src/cargo/ops/fix.rs @@ -431,7 +431,10 @@ fn rustfix_crate( args: &FixArgs, config: &Config, ) -> Result { - args.check_edition_and_send_status(config)?; + if !args.can_run_rustfix(config)? { + // This fix should not be run. Skipping... + return Ok(FixedCrate::default()); + } // First up, we want to make sure that each crate is only checked by one // process at a time. If two invocations concurrently check a crate then @@ -834,15 +837,16 @@ impl FixArgs { } /// Validates the edition, and sends a message indicating what is being - /// done. - fn check_edition_and_send_status(&self, config: &Config) -> CargoResult<()> { + /// done. Returns a flag indicating whether this fix should be run. + fn can_run_rustfix(&self, config: &Config) -> CargoResult { let to_edition = match self.prepare_for_edition { Some(s) => s, None => { return Message::Fixing { file: self.file.display().to_string(), } - .post(); + .post() + .and(Ok(true)); } }; // Unfortunately determining which cargo targets are being built @@ -856,18 +860,31 @@ impl FixArgs { // multiple jobs run in parallel (the error appears multiple // times). Hopefully this doesn't happen often in practice. if !to_edition.is_stable() && !config.nightly_features_allowed { - bail!( - "cannot migrate {} to edition {to_edition}\n\ - Edition {to_edition} is unstable and not allowed in this release, \ - consider trying the nightly release channel.", - self.file.display(), + let message = format!( + "`{file}` is on the latest edition, but trying to \ + migrate to edition {to_edition}.\n\ + Edition {to_edition} is unstable and not allowed in \ + this release, consider trying the nightly release channel.", + file = self.file.display(), to_edition = to_edition ); + return Message::EditionAlreadyEnabled { + message, + edition: to_edition.previous().unwrap(), + } + .post() + .and(Ok(false)); // Do not run rustfix for this the edition. } let from_edition = self.enabled_edition.unwrap_or(Edition::Edition2015); if from_edition == to_edition { + let message = format!( + "`{}` is already on the latest edition ({}), \ + unable to migrate further", + self.file.display(), + to_edition + ); Message::EditionAlreadyEnabled { - file: self.file.display().to_string(), + message, edition: to_edition, } .post() @@ -879,5 +896,6 @@ impl FixArgs { } .post() } + .and(Ok(true)) } } diff --git a/src/cargo/util/diagnostic_server.rs b/src/cargo/util/diagnostic_server.rs index 69fcf7e0115..22bbf0ca223 100644 --- a/src/cargo/util/diagnostic_server.rs +++ b/src/cargo/util/diagnostic_server.rs @@ -55,7 +55,7 @@ pub enum Message { message: String, }, EditionAlreadyEnabled { - file: String, + message: String, edition: Edition, }, } @@ -186,18 +186,13 @@ impl<'a> DiagnosticPrinter<'a> { )?; Ok(()) } - Message::EditionAlreadyEnabled { file, edition } => { + Message::EditionAlreadyEnabled { message, edition } => { if !self.dedupe.insert(msg.clone()) { return Ok(()); } - let warning = format!( - "`{}` is already on the latest edition ({}), \ - unable to migrate further", - file, edition - ); // Don't give a really verbose warning if it has already been issued. if self.dedupe.insert(Message::EditionAlreadyEnabled { - file: "".to_string(), // Dummy, so that this only long-warns once. + message: "".to_string(), // Dummy, so that this only long-warns once. edition: *edition, }) { self.config.shell().warn(&format!("\ @@ -214,10 +209,10 @@ process requires following these steps: More details may be found at https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html ", - warning, this_edition=edition, prev_edition=edition.previous().unwrap() + message, this_edition=edition, prev_edition=edition.previous().unwrap() )) } else { - self.config.shell().warn(warning) + self.config.shell().warn(message) } } } diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index a1a72971b8a..9a543edf24e 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -809,6 +809,7 @@ fn prepare_for_unstable() { } }; let latest_stable = Edition::LATEST_STABLE; + let prev = latest_stable.previous().unwrap(); let p = project() .file( "Cargo.toml", @@ -828,13 +829,24 @@ fn prepare_for_unstable() { // -j1 to make the error more deterministic (otherwise there can be // multiple errors since they run in parallel). p.cargo("fix --edition --allow-no-vcs -j1") - .with_status(101) - .with_stderr(&format!("\ + .with_stderr(&format_args!("\ [CHECKING] foo [..] -[ERROR] cannot migrate src/lib.rs to edition {next} +[WARNING] `src/lib.rs` is on the latest edition, but trying to migrate to edition {next}. Edition {next} is unstable and not allowed in this release, consider trying the nightly release channel. -error: could not compile `foo` -", next=next)) + +If you are trying to migrate from the previous edition ({prev}), the +process requires following these steps: + +1. Start with `edition = \"{prev}\"` in `Cargo.toml` +2. Run `cargo fix --edition` +3. Modify `Cargo.toml` to set `edition = \"{latest_stable}\"` +4. Run `cargo build` or `cargo test` to verify the fixes worked + +More details may be found at +https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html + +[FINISHED] [..] +", next=next, latest_stable=latest_stable, prev=prev)) .run(); if !is_nightly() {