From 5825206acf80e4ef63f2faebba4d40193deaf78e Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 7 Jun 2021 13:21:36 -0700 Subject: [PATCH] Enable support for fix --edition for 2021. --- src/cargo/core/features.rs | 8 +++---- src/cargo/ops/fix.rs | 19 +++++++++++----- tests/testsuite/fix.rs | 46 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index b0e28c15f35..224c467c7a3 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -208,15 +208,15 @@ impl Edition { /// Whether or not this edition supports the `rust_*_compatibility` lint. /// - /// Ideally this would not be necessary, but currently 2021 does not have - /// any lints, and thus `rustc` doesn't recognize it. Perhaps `rustc` - /// could create an empty group instead? + /// Ideally this would not be necessary, but editions may not have any + /// lints, and thus `rustc` doesn't recognize it. Perhaps `rustc` could + /// create an empty group instead? pub(crate) fn supports_compat_lint(&self) -> bool { use Edition::*; match self { Edition2015 => false, Edition2018 => true, - Edition2021 => false, + Edition2021 => true, } } diff --git a/src/cargo/ops/fix.rs b/src/cargo/ops/fix.rs index f13ef28b32c..e1910d41d25 100644 --- a/src/cargo/ops/fix.rs +++ b/src/cargo/ops/fix.rs @@ -330,7 +330,7 @@ pub fn fix_maybe_exec_rustc(config: &Config) -> CargoResult { // that we have to back it all out. if !fixes.files.is_empty() { let mut cmd = rustc.build_command(); - args.apply(&mut cmd); + args.apply(&mut cmd, config); cmd.arg("--error-format=json"); let output = cmd.output().context("failed to spawn rustc")?; @@ -369,7 +369,7 @@ pub fn fix_maybe_exec_rustc(config: &Config) -> CargoResult { // - If `--broken-code`, show the error messages. // - If the fix succeeded, show any remaining warnings. let mut cmd = rustc.build_command(); - args.apply(&mut cmd); + args.apply(&mut cmd, config); for arg in args.format_args { // Add any json/error format arguments that Cargo wants. This allows // things like colored output to work correctly. @@ -457,7 +457,7 @@ fn rustfix_crate( // We'll generate new errors below. file.errors_applying_fixes.clear(); } - rustfix_and_fix(&mut fixes, rustc, filename, args)?; + rustfix_and_fix(&mut fixes, rustc, filename, args, config)?; let mut progress_yet_to_be_made = false; for (path, file) in fixes.files.iter_mut() { if file.errors_applying_fixes.is_empty() { @@ -499,6 +499,7 @@ fn rustfix_and_fix( rustc: &ProcessBuilder, filename: &Path, args: &FixArgs, + config: &Config, ) -> Result<(), Error> { // If not empty, filter by these lints. // TODO: implement a way to specify this. @@ -506,7 +507,7 @@ fn rustfix_and_fix( let mut cmd = rustc.build_command(); cmd.arg("--error-format=json"); - args.apply(&mut cmd); + args.apply(&mut cmd, config); let output = cmd.output().with_context(|| { format!( "failed to execute `{}`", @@ -763,7 +764,7 @@ impl FixArgs { }) } - fn apply(&self, cmd: &mut Command) { + fn apply(&self, cmd: &mut Command, config: &Config) { cmd.arg(&self.file); cmd.args(&self.other).arg("--cap-lints=warn"); if let Some(edition) = self.enabled_edition { @@ -775,7 +776,13 @@ impl FixArgs { if let Some(edition) = self.prepare_for_edition { if edition.supports_compat_lint() { - cmd.arg("-W").arg(format!("rust-{}-compatibility", edition)); + if config.nightly_features_allowed { + cmd.arg("--force-warns") + .arg(format!("rust-{}-compatibility", edition)) + .arg("-Zunstable-options"); + } else { + cmd.arg("-W").arg(format!("rust-{}-compatibility", edition)); + } } } } diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index 65583ffb859..b1acd833843 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -1501,3 +1501,49 @@ fn rustfix_handles_multi_spans() { p.cargo("fix --allow-no-vcs").run(); assert!(p.read_file("src/lib.rs").contains(r#"panic!("hey");"#)); } + +#[cargo_test] +fn fix_edition_2021() { + // Can migrate 2021, even when lints are allowed. + if !is_nightly() { + // 2021 is unstable + return; + } + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + "#, + ) + .file( + "src/lib.rs", + r#" + #![allow(ellipsis_inclusive_range_patterns)] + + pub fn f() -> bool { + let x = 123; + match x { + 0...100 => true, + _ => false, + } + } + "#, + ) + .build(); + p.cargo("fix --edition --allow-no-vcs") + .masquerade_as_nightly_cargo() + .with_stderr( + "\ +[CHECKING] foo v0.1.0 [..] +[MIGRATING] src/lib.rs from 2018 edition to 2021 +[FIXED] src/lib.rs (1 fix) +[FINISHED] [..] +", + ) + .run(); + assert!(p.read_file("src/lib.rs").contains(r#"0..=100 => true,"#)); +}