diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 277039685d6..9d0181bf8c4 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1391,17 +1391,26 @@ fn check_cfg_args(unit: &Unit) -> Vec { } arg_feature.push("))"); - // In addition to the package features, we also include the `test` cfg (since - // compiler-team#785, as to be able to someday apply yt conditionaly), as well - // the `docsrs` cfg from the docs.rs service. + // In addition to the package features, we also conditionaly include the `test` cfg + // based on the unit target "test" field (ie `lib.test = false`, `[[bin]] test = false` and + // others). // - // We include `docsrs` here (in Cargo) instead of rustc, since there is a much closer + // We also include `docsrs` here (in Cargo) instead of rustc, since there is a much closer // relationship between Cargo and docs.rs than rustc and docs.rs. In particular, all // users of docs.rs use Cargo, but not all users of rustc (like Rust-for-Linux) use docs.rs. + let arg_extra = if unit.target.tested() + // Benchmarks default to `test = false` but most of them still use the test crate + // and the `#[test]` attribute, so for now always mark `test` as well known for them. + || unit.target.is_bench() + { + OsString::from("cfg(docsrs,test)") + } else { + OsString::from("cfg(docsrs)") + }; vec![ OsString::from("--check-cfg"), - OsString::from("cfg(docsrs,test)"), + arg_extra, OsString::from("--check-cfg"), arg_feature, ] diff --git a/src/doc/src/reference/cargo-targets.md b/src/doc/src/reference/cargo-targets.md index 8a4ed59e54b..aef7abff26b 100644 --- a/src/doc/src/reference/cargo-targets.md +++ b/src/doc/src/reference/cargo-targets.md @@ -216,7 +216,10 @@ the target name. ### The `test` field The `test` field indicates whether or not the target is tested by default by -[`cargo test`]. The default is `true` for lib, bins, and tests. +[`cargo test`], and whenever the target is expected to have tests. Warnings +may be reported when tests are unexpected (i.e., `test = false`). + +The default is `true` for lib, bins, and tests. > **Note**: Examples are built by [`cargo test`] by default to ensure they > continue to compile, but they are not *tested* by default. Setting `test = diff --git a/tests/testsuite/check_cfg.rs b/tests/testsuite/check_cfg.rs index 2e03254337a..0f76cc3ca7d 100644 --- a/tests/testsuite/check_cfg.rs +++ b/tests/testsuite/check_cfg.rs @@ -317,6 +317,193 @@ fn well_known_names_values_doctest() { .run(); } +#[cargo_test(nightly, reason = "warning currently only on nightly")] +fn test_false_lib() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [lib] + test = false + "#, + ) + .file("src/lib.rs", "#[cfg(test)] mod tests {}") + .build(); + + p.cargo("check -v") + .with_stderr_does_not_contain(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (lib) generated 1 warning +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); + + p.cargo("clean").run(); + p.cargo("test -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (lib) generated 1 warning +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[DOCTEST] foo +[RUNNING] [..] + +"#]]) + .run(); + + p.cargo("clean").run(); + p.cargo("test --lib -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` + --> src/lib.rs:1:7 +... + +[WARNING] `foo` (lib test) generated 1 warning +[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `[ROOT]/foo/target/debug/deps/foo-[HASH][EXE]` + +"#]]) + .run(); +} + +#[cargo_test(nightly, reason = "warning currently only on nightly")] +fn test_false_bins() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [[bin]] + name = "daemon" + test = false + path = "src/deamon.rs" + "#, + ) + .file("src/main.rs", "fn main() {}\n#[cfg(test)] mod tests {}") + .file("src/deamon.rs", "fn main() {}\n#[cfg(test)] mod tests {}") + .build(); + + p.cargo("check -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) // for foo + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) // for deamon + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (bin "daemon") generated 1 warning +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test(nightly, reason = "warning currently only on nightly")] +fn test_false_examples() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [lib] + test = false + + [[example]] + name = "daemon" + test = false + path = "src/deamon.rs" + "#, + ) + .file("src/lib.rs", "#[cfg(test)] mod tests {}") + .file("src/deamon.rs", "fn main() {}\n#[cfg(test)] mod tests {}") + .build(); + + p.cargo("check --examples -v") + .with_stderr_does_not_contain(x!("rustc" => "cfg" of "docsrs,test")) + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs")) + .with_stderr_data(str![[r#" +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (lib) generated 1 warning +... +[WARNING] unexpected `cfg` condition name: `test` +... + +[WARNING] `foo` (example "daemon") generated 1 warning +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test( + nightly, + reason = "bench is nightly & warning currently only on nightly" +)] +fn test_false_benches() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.0" + edition = "2018" + + [[bench]] + name = "ben1" + test = false + path = "benches/ben1.rs" + "#, + ) + .file("src/lib.rs", "") + .file( + "benches/ben1.rs", + r#" + #![feature(test)] + extern crate test; + #[bench] fn run1(_ben: &mut test::Bencher) { } + "#, + ) + .build(); + + // Benches always require the `test` cfg, there should be no warning. + p.cargo("bench --bench ben1") + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.0 ([ROOT]/foo) +[FINISHED] `bench` profile [optimized] target(s) in [ELAPSED]s +[RUNNING] benches/ben1.rs (target/release/deps/ben1-[HASH][EXE]) + +"#]]) + .run(); +} + #[cargo_test] fn features_doc() { let p = project() diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index 48d69526ad7..98212097a2a 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -4191,7 +4191,19 @@ fn test_hint_workspace_virtual() { .file("a/src/lib.rs", "#[test] fn t1() {}") .file("b/Cargo.toml", &basic_manifest("b", "0.1.0")) .file("b/src/lib.rs", "#[test] fn t1() {assert!(false)}") - .file("c/Cargo.toml", &basic_manifest("c", "0.1.0")) + .file( + "c/Cargo.toml", + r#" + [package] + name = "c" + version = "0.1.0" + edition = "2015" + + [[example]] + name = "ex1" + test = true + "#, + ) .file( "c/src/lib.rs", r#" @@ -4275,14 +4287,17 @@ fn test_hint_workspace_virtual() { [ERROR] test failed, to rerun pass `-p c --bin c` [RUNNING] tests/t1.rs (target/debug/deps/t1-[HASH][EXE]) [ERROR] test failed, to rerun pass `-p c --test t1` +[RUNNING] unittests examples/ex1.rs (target/debug/examples/ex1-[HASH][EXE]) +[ERROR] test failed, to rerun pass `-p c --example ex1` [DOCTEST] a [DOCTEST] b [DOCTEST] c [ERROR] doctest failed, to rerun pass `-p c --doc` -[ERROR] 4 targets failed: +[ERROR] 5 targets failed: `-p b --lib` `-p c --bin c` `-p c --test t1` + `-p c --example ex1` `-p c --doc` "#]])