Skip to content

Commit 7cdf534

Browse files
committed
Auto merge of #9588 - ehuss:edition2021-force-warns, r=alexcrichton
Enable support for fix --edition for 2021. This adds support for using `cargo fix --edition` to migrate to 2021. This also uses the new, currently unstable, `--force-warns` flag. This was added because there were a significant number of crates that were "allow"ing lints that are required for migrating the edition. This wasn't a problem for 2018, because its lints were new, and all "allow" to start. For 2021, several older "warn" lints are becoming hard errors. "allow"ing them would cause the migration to fail.
2 parents ee8497b + 5825206 commit 7cdf534

File tree

3 files changed

+63
-10
lines changed

3 files changed

+63
-10
lines changed

src/cargo/core/features.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,15 +208,15 @@ impl Edition {
208208

209209
/// Whether or not this edition supports the `rust_*_compatibility` lint.
210210
///
211-
/// Ideally this would not be necessary, but currently 2021 does not have
212-
/// any lints, and thus `rustc` doesn't recognize it. Perhaps `rustc`
213-
/// could create an empty group instead?
211+
/// Ideally this would not be necessary, but editions may not have any
212+
/// lints, and thus `rustc` doesn't recognize it. Perhaps `rustc` could
213+
/// create an empty group instead?
214214
pub(crate) fn supports_compat_lint(&self) -> bool {
215215
use Edition::*;
216216
match self {
217217
Edition2015 => false,
218218
Edition2018 => true,
219-
Edition2021 => false,
219+
Edition2021 => true,
220220
}
221221
}
222222

src/cargo/ops/fix.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ pub fn fix_maybe_exec_rustc(config: &Config) -> CargoResult<bool> {
330330
// that we have to back it all out.
331331
if !fixes.files.is_empty() {
332332
let mut cmd = rustc.build_command();
333-
args.apply(&mut cmd);
333+
args.apply(&mut cmd, config);
334334
cmd.arg("--error-format=json");
335335
let output = cmd.output().context("failed to spawn rustc")?;
336336

@@ -369,7 +369,7 @@ pub fn fix_maybe_exec_rustc(config: &Config) -> CargoResult<bool> {
369369
// - If `--broken-code`, show the error messages.
370370
// - If the fix succeeded, show any remaining warnings.
371371
let mut cmd = rustc.build_command();
372-
args.apply(&mut cmd);
372+
args.apply(&mut cmd, config);
373373
for arg in args.format_args {
374374
// Add any json/error format arguments that Cargo wants. This allows
375375
// things like colored output to work correctly.
@@ -457,7 +457,7 @@ fn rustfix_crate(
457457
// We'll generate new errors below.
458458
file.errors_applying_fixes.clear();
459459
}
460-
rustfix_and_fix(&mut fixes, rustc, filename, args)?;
460+
rustfix_and_fix(&mut fixes, rustc, filename, args, config)?;
461461
let mut progress_yet_to_be_made = false;
462462
for (path, file) in fixes.files.iter_mut() {
463463
if file.errors_applying_fixes.is_empty() {
@@ -499,14 +499,15 @@ fn rustfix_and_fix(
499499
rustc: &ProcessBuilder,
500500
filename: &Path,
501501
args: &FixArgs,
502+
config: &Config,
502503
) -> Result<(), Error> {
503504
// If not empty, filter by these lints.
504505
// TODO: implement a way to specify this.
505506
let only = HashSet::new();
506507

507508
let mut cmd = rustc.build_command();
508509
cmd.arg("--error-format=json");
509-
args.apply(&mut cmd);
510+
args.apply(&mut cmd, config);
510511
let output = cmd.output().with_context(|| {
511512
format!(
512513
"failed to execute `{}`",
@@ -763,7 +764,7 @@ impl FixArgs {
763764
})
764765
}
765766

766-
fn apply(&self, cmd: &mut Command) {
767+
fn apply(&self, cmd: &mut Command, config: &Config) {
767768
cmd.arg(&self.file);
768769
cmd.args(&self.other).arg("--cap-lints=warn");
769770
if let Some(edition) = self.enabled_edition {
@@ -775,7 +776,13 @@ impl FixArgs {
775776

776777
if let Some(edition) = self.prepare_for_edition {
777778
if edition.supports_compat_lint() {
778-
cmd.arg("-W").arg(format!("rust-{}-compatibility", edition));
779+
if config.nightly_features_allowed {
780+
cmd.arg("--force-warns")
781+
.arg(format!("rust-{}-compatibility", edition))
782+
.arg("-Zunstable-options");
783+
} else {
784+
cmd.arg("-W").arg(format!("rust-{}-compatibility", edition));
785+
}
779786
}
780787
}
781788
}

tests/testsuite/fix.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,3 +1501,49 @@ fn rustfix_handles_multi_spans() {
15011501
p.cargo("fix --allow-no-vcs").run();
15021502
assert!(p.read_file("src/lib.rs").contains(r#"panic!("hey");"#));
15031503
}
1504+
1505+
#[cargo_test]
1506+
fn fix_edition_2021() {
1507+
// Can migrate 2021, even when lints are allowed.
1508+
if !is_nightly() {
1509+
// 2021 is unstable
1510+
return;
1511+
}
1512+
let p = project()
1513+
.file(
1514+
"Cargo.toml",
1515+
r#"
1516+
[package]
1517+
name = "foo"
1518+
version = "0.1.0"
1519+
edition = "2018"
1520+
"#,
1521+
)
1522+
.file(
1523+
"src/lib.rs",
1524+
r#"
1525+
#![allow(ellipsis_inclusive_range_patterns)]
1526+
1527+
pub fn f() -> bool {
1528+
let x = 123;
1529+
match x {
1530+
0...100 => true,
1531+
_ => false,
1532+
}
1533+
}
1534+
"#,
1535+
)
1536+
.build();
1537+
p.cargo("fix --edition --allow-no-vcs")
1538+
.masquerade_as_nightly_cargo()
1539+
.with_stderr(
1540+
"\
1541+
[CHECKING] foo v0.1.0 [..]
1542+
[MIGRATING] src/lib.rs from 2018 edition to 2021
1543+
[FIXED] src/lib.rs (1 fix)
1544+
[FINISHED] [..]
1545+
",
1546+
)
1547+
.run();
1548+
assert!(p.read_file("src/lib.rs").contains(r#"0..=100 => true,"#));
1549+
}

0 commit comments

Comments
 (0)