diff --git a/src/bin/cargo/commands/fix.rs b/src/bin/cargo/commands/fix.rs index 38bd75497a4..8850c8b018f 100644 --- a/src/bin/cargo/commands/fix.rs +++ b/src/bin/cargo/commands/fix.rs @@ -81,8 +81,11 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { let mut opts = args.compile_options(gctx, mode, Some(&ws), ProfileChecking::LegacyTestOnly)?; - if !opts.filter.is_specific() { - // cargo fix with no target selection implies `--all-targets`. + let edition = args.flag("edition") || args.flag("edition-idioms"); + if !opts.filter.is_specific() && edition { + // When `cargo fix` is run without specifying targets but with `--edition` or `--edition-idioms`, + // it should default to fixing all targets. + // See: https://github.com/rust-lang/cargo/issues/13527 opts.filter = ops::CompileFilter::new_all_targets(); } diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index 7d9c4610c92..e97ec1ca116 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -197,6 +197,103 @@ fn prepare_for_2018() { .contains("let x = crate::foo::FOO;")); } +#[cargo_test] +fn fix_tests_with_edition() { + 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 foo() {} + + #[cfg(test)] + mod tests { + #[test] + fn it_works() { + f(); + } + fn f() -> bool { + let x = 123; + match x { + 0...100 => true, + _ => false, + } + } + } + "#, + ) + .build(); + + p.cargo("fix --edition --allow-no-vcs") + .with_stderr_data(str![[r#" +[MIGRATING] Cargo.toml from 2018 edition to 2021 +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[MIGRATING] src/lib.rs from 2018 edition to 2021 +[FIXED] src/lib.rs (1 fix) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .with_stdout_data("") + .run(); + // Check that the test is fixed. + assert!(p.read_file("src/lib.rs").contains(r#"0..=100 => true,"#)); +} + +#[cargo_test] +fn fix_tests_with_edition_idioms() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = 'foo' + version = '0.1.0' + edition = '2018' + "#, + ) + .file( + "src/lib.rs", + r#" + pub fn foo() {} + + #[cfg(test)] + mod tests { + #[test] + fn it_works() { + f(); + } + + use std::any::Any; + pub fn f() { + let _x: Box = Box::new(3); + } + } + "#, + ) + .build(); + + p.cargo("fix --edition-idioms --allow-no-vcs") + .with_stderr_data(str![[r#" +[CHECKING] foo v0.1.0 ([ROOT]/foo) +[FIXED] src/lib.rs (1 fix) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .with_stdout_data("") + .run(); + // Check that the test is fixed. + assert!(p.read_file("src/lib.rs").contains("Box")); +} + #[cargo_test] fn local_paths() { let p = project() @@ -708,7 +805,7 @@ fn does_not_warn_about_dirty_ignored_files() { } #[cargo_test] -fn fix_all_targets_by_default() { +fn do_not_fix_tests_by_default() { let p = project() .file("src/lib.rs", "pub fn foo() { let mut x = 3; let _ = x; }") .file("tests/foo.rs", "pub fn foo() { let mut x = 3; let _ = x; }") @@ -717,7 +814,7 @@ fn fix_all_targets_by_default() { .env("__CARGO_FIX_YOLO", "1") .run(); assert!(!p.read_file("src/lib.rs").contains("let mut x")); - assert!(!p.read_file("tests/foo.rs").contains("let mut x")); + assert!(p.read_file("tests/foo.rs").contains("let mut x")); } #[cargo_test] @@ -1330,7 +1427,6 @@ fn fix_to_broken_code() { p.cargo("fix --allow-no-vcs --broken-code") .cwd("bar") .env("RUSTC", p.root().join("foo/target/debug/foo")) - .with_status(101) .with_stderr_data(str![[r#" ... [WARNING] failed to automatically apply fixes suggested by rustc to crate `bar`