diff --git a/src/cargo/core/compiler/context/unit_dependencies.rs b/src/cargo/core/compiler/context/unit_dependencies.rs index 7f44ff85aab..61b03ff8e67 100644 --- a/src/cargo/core/compiler/context/unit_dependencies.rs +++ b/src/cargo/core/compiler/context/unit_dependencies.rs @@ -148,6 +148,46 @@ fn compute_deps<'a, 'b, 'cfg>( } ret.extend(maybe_lib(unit, bcx, profile_for)); + // If any integration tests/benches are being run, make sure that + // binaries are built as well. + if !unit.mode.is_check() && unit.mode.is_any_test() + && (unit.target.is_test() || unit.target.is_bench()) + { + ret.extend( + unit.pkg + .targets() + .iter() + .filter(|t| { + let no_required_features = Vec::new(); + + t.is_bin() && + // Skip binaries with required features that have not been selected. + t.required_features().unwrap_or(&no_required_features).iter().all(|f| { + bcx.resolve.features(id).contains(f) + }) + }) + .map(|t| { + ( + // TODO: Should not be using profile_for here. Should + // instead use ProfileFor::Any so that bins are built + // with panic, but this aggravates + // https://github.com/rust-lang/cargo/issues/5444 + // Switching it will fix + // https://github.com/rust-lang/cargo/issues/5435 + new_unit( + bcx, + unit.pkg, + t, + profile_for, + unit.kind.for_target(t), + CompileMode::Build, + ), + profile_for, + ) + }), + ); + } + Ok(ret) } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 0703b0873a5..62732e5b169 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -614,19 +614,6 @@ fn generate_targets<'a>( } } - // If any integration tests/benches are being run, make sure that - // binaries are built as well. - if !build_config.mode.is_check() && proposals.iter().any(|&(ref unit, _)| { - unit.mode.is_any_test() && (unit.target.is_test() || unit.target.is_bench()) - }) { - proposals.extend( - pkg.targets() - .iter() - .filter(|t| t.is_bin()) - .map(|t| (new_unit(pkg, t, CompileMode::Build), false)), - ); - } - // Only include targets that are libraries or have all required // features available. for (unit, required) in proposals { diff --git a/tests/testsuite/rustc.rs b/tests/testsuite/rustc.rs index 95691b8dfb1..67bcb4c6b7d 100644 --- a/tests/testsuite/rustc.rs +++ b/tests/testsuite/rustc.rs @@ -1,4 +1,4 @@ -use cargotest::support::{basic_lib_manifest, execs, project}; +use cargotest::support::{basic_bin_manifest, basic_lib_manifest, execs, project}; use hamcrest::assert_that; const CARGO_RUSTC_ERROR: &'static str = @@ -649,3 +649,40 @@ fn rustc_fingerprint() { ), ); } + +#[test] +fn rustc_test_with_implicit_bin() { + let p = project("foo") + .file("Cargo.toml", &basic_bin_manifest("foo")) + .file( + "src/main.rs", + r#" + #[cfg(foo)] + fn f() { compile_fail!("Foo shouldn't be set."); } + fn main() {} + "#, + ) + .file( + "tests/test1.rs", + r#" + #[cfg(not(foo))] + fn f() { compile_fail!("Foo should be set."); } "#, + ) + .build(); + + assert_that( + p.cargo("rustc --test test1 -v -- --cfg foo"), + execs() + .with_status(0) + .with_stderr_contains( + "\ +[RUNNING] `rustc --crate-name test1 tests[/]test1.rs [..] --cfg foo [..] +", + ) + .with_stderr_contains( + "\ +[RUNNING] `rustc --crate-name foo src[/]main.rs [..] +", + ), + ); +}