diff --git a/src/bin/cargo/commands/fix.rs b/src/bin/cargo/commands/fix.rs index 4cbf9b9565e..d2c792c00fa 100644 --- a/src/bin/cargo/commands/fix.rs +++ b/src/bin/cargo/commands/fix.rs @@ -68,7 +68,7 @@ pub fn cli() -> App { ) .after_help( "\ -This Cargo subcommmand will automatically take rustc's suggestions from +This Cargo subcommand will automatically take rustc's suggestions from diagnostics like warnings and apply them to your source code. This is intended to help automate tasks that rustc itself already knows how to tell you to fix! The `cargo fix` subcommand is also being developed for the Rust 2018 edition diff --git a/src/cargo/core/compiler/build_config.rs b/src/cargo/core/compiler/build_config.rs index 0ce9a3a404f..77ed087eee3 100644 --- a/src/cargo/core/compiler/build_config.rs +++ b/src/cargo/core/compiler/build_config.rs @@ -16,6 +16,8 @@ pub struct BuildConfig { pub mode: CompileMode, /// Whether to print std output in json format (for machine reading) pub message_format: MessageFormat, + /// Force cargo to do a full rebuild and treat each target as changed. + pub force_rebuild: bool, /// Output a build plan to stdout instead of actually compiling. pub build_plan: bool, /// Use Cargo itself as the wrapper around rustc, only used for `cargo fix` @@ -79,6 +81,7 @@ impl BuildConfig { release: false, mode, message_format: MessageFormat::Human, + force_rebuild: false, build_plan: false, cargo_as_rustc_wrapper: false, extra_rustc_env: Vec::new(), diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index 3687ee60ff8..197356b2424 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -157,7 +157,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> { // part of this, that's all done next as part of the `execute` // function which will run everything in order with proper // parallelism. - super::compile(&mut self, &mut queue, &mut plan, unit, exec)?; + let force_rebuild = self.bcx.build_config.force_rebuild; + super::compile(&mut self, &mut queue, &mut plan, unit, exec, force_rebuild)?; } // Now that we've figured out everything that we're going to do, do it! diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 787889439d2..742933cb304 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -129,6 +129,7 @@ fn compile<'a, 'cfg: 'a>( plan: &mut BuildPlan, unit: &Unit<'a>, exec: &Arc, + force_rebuild: bool, ) -> CargoResult<()> { let bcx = cx.bcx; let build_plan = bcx.build_config.build_plan; @@ -164,7 +165,7 @@ fn compile<'a, 'cfg: 'a>( let dirty = work.then(link_targets(cx, unit, false)?).then(dirty); let fresh = link_targets(cx, unit, true)?.then(fresh); - if exec.force_rebuild(unit) { + if exec.force_rebuild(unit) || force_rebuild { freshness = Freshness::Dirty; } @@ -175,7 +176,7 @@ fn compile<'a, 'cfg: 'a>( // Be sure to compile all dependencies of this target as well. for unit in cx.dep_targets(unit).iter() { - compile(cx, jobs, plan, unit, exec)?; + compile(cx, jobs, plan, unit, exec, false)?; } if build_plan { plan.add(cx, unit)?; diff --git a/src/cargo/ops/fix.rs b/src/cargo/ops/fix.rs index 275a471bd17..f0bb8931b37 100644 --- a/src/cargo/ops/fix.rs +++ b/src/cargo/ops/fix.rs @@ -48,6 +48,8 @@ pub fn fix(ws: &Workspace, opts: &mut FixOptions) -> CargoResult<()> { )); let _started = lock_server.start()?; + opts.compile_opts.build_config.force_rebuild = true; + if opts.broken_code { let key = BROKEN_CODE_ENV.to_string(); opts.compile_opts.build_config.extra_rustc_env.push((key, "1".to_string())); diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index 0a5f9f2a06f..84161749ff6 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -950,3 +950,134 @@ For more information try --help .with_stderr(stderr) .run(); } + +#[test] +fn shows_warnings_on_second_run_without_changes() { + let p = project() + .file( + "src/lib.rs", + r#" + use std::default::Default; + + pub fn foo() { + } + "#, + ) + .build(); + + p.cargo("fix --allow-no-vcs") + .with_stderr_contains("[..]warning: unused import[..]") + .run(); + + p.cargo("fix --allow-no-vcs") + .with_stderr_contains("[..]warning: unused import[..]") + .run(); +} + +#[test] +fn shows_warnings_on_second_run_without_changes_on_multiple_targets() { + let p = project() + .file( + "src/lib.rs", + r#" + use std::default::Default; + + pub fn a() -> u32 { 3 } + "#, + ) + .file( + "src/main.rs", + r#" + use std::default::Default; + fn main() { println!("3"); } + "#, + ) + .file( + "tests/foo.rs", + r#" + use std::default::Default; + #[test] + fn foo_test() { + println!("3"); + } + "#, + ) + .file( + "tests/bar.rs", + r#" + use std::default::Default; + + #[test] + fn foo_test() { + println!("3"); + } + "#, + ) + .file( + "examples/fooxample.rs", + r#" + use std::default::Default; + + fn main() { + println!("3"); + } + "#, + ) + .build(); + + p.cargo("fix --allow-no-vcs --all-targets") + .with_stderr_contains(" --> examples/fooxample.rs:2:21") + .with_stderr_contains(" --> src/lib.rs:2:21") + .with_stderr_contains(" --> src/main.rs:2:21") + .with_stderr_contains(" --> tests/bar.rs:2:21") + .with_stderr_contains(" --> tests/foo.rs:2:21") + .run(); + + p.cargo("fix --allow-no-vcs --all-targets") + .with_stderr_contains(" --> examples/fooxample.rs:2:21") + .with_stderr_contains(" --> src/lib.rs:2:21") + .with_stderr_contains(" --> src/main.rs:2:21") + .with_stderr_contains(" --> tests/bar.rs:2:21") + .with_stderr_contains(" --> tests/foo.rs:2:21") + .run(); +} + +#[test] +fn doesnt_rebuild_dependencies() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = { path = 'bar' } + + [workspace] + "#, + ).file("src/lib.rs", "extern crate bar;") + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0")) + .file("bar/src/lib.rs", "") + .build(); + + p.cargo("fix --allow-no-vcs -p foo") + .env("__CARGO_FIX_YOLO", "1") + .with_stdout("") + .with_stderr("\ +[CHECKING] bar v0.1.0 ([..]) +[CHECKING] foo v0.1.0 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +") + .run(); + + p.cargo("fix --allow-no-vcs -p foo") + .env("__CARGO_FIX_YOLO", "1") + .with_stdout("") + .with_stderr("\ +[CHECKING] foo v0.1.0 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +") + .run(); +}