Skip to content

Improve support of condition compilation checking #10566

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 6, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
@@ -224,7 +224,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
let mut unstable_opts = false;
let mut args = compiler::extern_args(&self, unit, &mut unstable_opts)?;
args.extend(compiler::lto_args(&self, unit));
args.extend(compiler::features_args(&self, unit));
args.extend(compiler::features_args(unit));
args.extend(compiler::check_cfg_args(&self, unit));

let script_meta = self.find_build_script_metadata(unit);
65 changes: 32 additions & 33 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
@@ -645,7 +645,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
paths::create_dir_all(&doc_dir)?;

rustdoc.arg("-o").arg(&doc_dir);
rustdoc.args(&features_args(cx, unit));
rustdoc.args(&features_args(unit));
rustdoc.args(&check_cfg_args(cx, unit));

add_error_format_and_color(cx, &mut rustdoc);
@@ -966,7 +966,7 @@ fn build_base_args(
cmd.arg("--cfg").arg("test");
}

cmd.args(&features_args(cx, unit));
cmd.args(&features_args(unit));
cmd.args(&check_cfg_args(cx, unit));

let meta = cx.files().metadata(unit);
@@ -1042,7 +1042,7 @@ fn build_base_args(
}

/// All active features for the unit passed as --cfg
fn features_args(_cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
fn features_args(unit: &Unit) -> Vec<OsString> {
let mut args = Vec::with_capacity(unit.features.len() * 2);

for feat in &unit.features {
@@ -1055,43 +1055,42 @@ fn features_args(_cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {

/// Generate the --check-cfg arguments for the unit
fn check_cfg_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
if !cx.bcx.config.cli_unstable().check_cfg_features
&& !cx.bcx.config.cli_unstable().check_cfg_well_known_names
&& !cx.bcx.config.cli_unstable().check_cfg_well_known_values
if let Some((features, well_known_names, well_known_values)) =
cx.bcx.config.cli_unstable().check_cfg
{
return Vec::new();
}

let mut args = Vec::with_capacity(unit.pkg.summary().features().len() * 2 + 4);
args.push(OsString::from("-Zunstable-options"));
let mut args = Vec::with_capacity(unit.pkg.summary().features().len() * 2 + 4);
args.push(OsString::from("-Zunstable-options"));

if features {
// This generate something like this:
// - values(feature)
// - values(feature, "foo", "bar")
let mut arg = OsString::from("values(feature");
for (&feat, _) in unit.pkg.summary().features() {
arg.push(", \"");
arg.push(&feat);
arg.push("\"");
}
arg.push(")");

if cx.bcx.config.cli_unstable().check_cfg_features {
// This generate something like this:
// - values(feature)
// - values(feature, "foo", "bar")
let mut arg = OsString::from("values(feature");
for (&feat, _) in unit.pkg.summary().features() {
arg.push(", \"");
arg.push(&feat);
arg.push("\"");
args.push(OsString::from("--check-cfg"));
args.push(arg);
}
arg.push(")");

args.push(OsString::from("--check-cfg"));
args.push(arg);
}
if well_known_names {
args.push(OsString::from("--check-cfg"));
args.push(OsString::from("names()"));
}

if cx.bcx.config.cli_unstable().check_cfg_well_known_names {
args.push(OsString::from("--check-cfg"));
args.push(OsString::from("names()"));
}
if well_known_values {
args.push(OsString::from("--check-cfg"));
args.push(OsString::from("values()"));
}

if cx.bcx.config.cli_unstable().check_cfg_well_known_values {
args.push(OsString::from("--check-cfg"));
args.push(OsString::from("values()"));
args
} else {
Vec::new()
}

args
}

fn lto_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
29 changes: 23 additions & 6 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
@@ -641,9 +641,7 @@ unstable_cli_options!(
build_std_features: Option<Vec<String>> = ("Configure features enabled for the standard library itself when building the standard library"),
config_include: bool = ("Enable the `include` key in config files"),
credential_process: bool = ("Add a config setting to fetch registry authentication tokens by calling an external process"),
check_cfg_features: bool = ("Enable compile-time checking of features in `cfg`"),
check_cfg_well_known_names: bool = ("Enable compile-time checking of well known names in `cfg`"),
check_cfg_well_known_values: bool = ("Enable compile-time checking of well known values in `cfg`"),
check_cfg: Option<(/*features:*/ bool, /*well_known_names:*/ bool, /*well_known_values:*/ bool)> = ("Specify scope of compile-time checking of `cfg` names/values"),
doctest_in_workspace: bool = ("Compile doctests with paths relative to the workspace root"),
doctest_xcompile: bool = ("Compile and run doctests for non-host target using runner config"),
dual_proc_macros: bool = ("Build proc-macros for both the host and the target"),
@@ -785,6 +783,27 @@ impl CliUnstable {
}
}

fn parse_check_cfg(value: Option<&str>) -> CargoResult<Option<(bool, bool, bool)>> {
if let Some(value) = value {
let mut features = false;
let mut well_known_names = false;
let mut well_known_values = false;

for e in value.split(',') {
match e {
"features" => features = true,
"names" => well_known_names = true,
"values" => well_known_values = true,
_ => bail!("flag -Zcheck-cfg only takes `features`, `names` or `values` as valid inputs"),
}
}

Ok(Some((features, well_known_names, well_known_values)))
} else {
Ok(None)
}
}

// Asserts that there is no argument to the flag.
fn parse_empty(key: &str, value: Option<&str>) -> CargoResult<bool> {
if let Some(v) = value {
@@ -842,9 +861,7 @@ impl CliUnstable {
"minimal-versions" => self.minimal_versions = parse_empty(k, v)?,
"advanced-env" => self.advanced_env = parse_empty(k, v)?,
"config-include" => self.config_include = parse_empty(k, v)?,
"check-cfg-features" => self.check_cfg_features = parse_empty(k, v)?,
"check-cfg-well-known-names" => self.check_cfg_well_known_names = parse_empty(k, v)?,
"check-cfg-well-known-values" => self.check_cfg_well_known_values = parse_empty(k, v)?,
"check-cfg" => self.check_cfg = parse_check_cfg(v)?,
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
// can also be set in .cargo/config or with and ENV
"mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?,
43 changes: 13 additions & 30 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
@@ -1188,44 +1188,27 @@ For instance:
cargo doc -Z unstable-options -Z rustdoc-scrape-examples=examples
```

### check-cfg-features
### check-cfg

* RFC: [#3013](https://github.com/rust-lang/rfcs/pull/3013)
* Tracking Issue: [#10554](https://github.com/rust-lang/cargo/issues/10554)

The `-Z check-cfg-features` argument tells Cargo to pass all possible features of a package to
`rustc` and `rustdoc` unstable `--check-cfg` command line as `--check-cfg=values(feature, ...)`.
This enables compile time checking of feature values in `#[cfg]`, `cfg!` and `#[cfg_attr]`.
Note than this command line options will probably become the default when stabilizing.
For instance:

```
cargo check -Z unstable-options -Z check-cfg-features
```

### check-cfg-well-known-names

* RFC: [#3013](https://github.com/rust-lang/rfcs/pull/3013)
`-Z check-cfg` command line enables compile time checking of name and values in `#[cfg]`, `cfg!`,
`#[link]` and `#[cfg_attr]` with the `rustc` and `rustdoc` unstable `--check-cfg` command line.

The `-Z check-cfg-well-known-names` argument tells Cargo to activate `rustc` and `rustdoc` unstable
`--check-cfg` command line as `--check-cfg=names()`.
This enables compile time checking of well known names in `#[cfg]`, `cfg!` and `#[cfg_attr]`.
For instance:

```
cargo check -Z unstable-options -Z check-cfg-well-known-names
```

### check-cfg-well-known-values

* RFC: [#3013](https://github.com/rust-lang/rfcs/pull/3013)
It's values are:
- `features`: enables features checking via `--check-cfg=values(feature, ...)`.
Note than this command line options will probably become the default when stabilizing.
- `names`: enables well known names checking via `--check-cfg=names()`.
- `values`: enables well known values checking via `--check-cfg=values()`.

The `-Z check-cfg-well-known-values` argument tells Cargo to activate `rustc` and `rustdoc` unstable
`--check-cfg` command line as `--check-cfg=values()`.
This enables compile time checking of well known values in `#[cfg]`, `cfg!` and `#[cfg_attr]`.
For instance:

```
cargo check -Z unstable-options -Z check-cfg-well-known-values
cargo check -Z unstable-options -Z check-cfg=features
cargo check -Z unstable-options -Z check-cfg=names
cargo check -Z unstable-options -Z check-cfg=values
cargo check -Z unstable-options -Z check-cfg=features,names,values
```

### workspace-inheritance
250 changes: 0 additions & 250 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
@@ -6224,253 +6224,3 @@ fn primary_package_env_var() {

foo.cargo("test").run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_features() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[features]
f_a = []
f_b = []
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values(feature, \"f_a\", \"f_b\")' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_features_with_deps() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[dependencies]
bar = { path = "bar/" }
[features]
f_a = []
f_b = []
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "#[allow(dead_code)] fn bar() {}")
.build();

p.cargo("build -v -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] bar v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values(feature)' [..]
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc --crate-name foo [..] --check-cfg 'values(feature, \"f_a\", \"f_b\")' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_features_with_opt_deps() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[dependencies]
bar = { path = "bar/", optional = true }
[features]
default = ["bar"]
f_a = []
f_b = []
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "#[allow(dead_code)] fn bar() {}")
.build();

p.cargo("build -v -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] bar v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values(feature)' [..]
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc --crate-name foo [..] --check-cfg 'values(feature, \"bar\", \"default\", \"f_a\", \"f_b\")' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_features_with_namespaced_features() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[dependencies]
bar = { path = "bar/", optional = true }
[features]
f_a = ["dep:bar"]
f_b = []
"#,
)
.file("src/main.rs", "fn main() {}")
.file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
.file("bar/src/lib.rs", "#[allow(dead_code)] fn bar() {}")
.build();

p.cargo("build -v -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc --crate-name foo [..] --check-cfg 'values(feature, \"f_a\", \"f_b\")' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_names() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v -Z check-cfg-well-known-names")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'names()' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_values() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v -Z check-cfg-well-known-values")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values()' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_all() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[features]
f_a = []
f_b = []
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v -Z check-cfg-features -Z check-cfg-well-known-names -Z check-cfg-well-known-values")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values(feature, \"f_a\", \"f_b\")' --check-cfg 'names()' --check-cfg 'values()' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
87 changes: 0 additions & 87 deletions tests/testsuite/check.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
use std::fmt::{self, Write};

use cargo_test_support::install::exe;
use cargo_test_support::is_nightly;
use cargo_test_support::paths::CargoPathExt;
use cargo_test_support::registry::Package;
use cargo_test_support::tools;
@@ -1014,89 +1013,3 @@ fn rustc_workspace_wrapper_excludes_published_deps() {
.with_stdout_does_not_contain("WRAPPER CALLED: rustc --crate-name baz [..]")
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_features() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[features]
f_a = []
f_b = []
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("check -v -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[CHECKING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values(feature, \"f_a\", \"f_b\")' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_names() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("check -v -Z check-cfg-well-known-names")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[CHECKING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'names()' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_values() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("check -v -Z check-cfg-well-known-values")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[CHECKING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values()' [..]
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
)
.run();
}
460 changes: 460 additions & 0 deletions tests/testsuite/check_cfg.rs

Large diffs are not rendered by default.

37 changes: 0 additions & 37 deletions tests/testsuite/doc.rs
Original file line number Diff line number Diff line change
@@ -2783,43 +2783,6 @@ fn doc_lib_false_dep() {
assert!(!p.build_dir().join("doc/bar").exists());
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn doc_check_cfg_features() {
if !is_nightly() {
// --check-cfg is a nightly only rustdoc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[features]
default = ["f_a"]
f_a = []
f_b = []
"#,
)
.file("src/lib.rs", "#[allow(dead_code)] fn foo() {}")
.build();

p.cargo("doc -v -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[DOCUMENTING] foo v0.1.0 [..]
[RUNNING] `rustdoc [..] --check-cfg 'values(feature, \"default\", \"f_a\", \"f_b\")' [..]
[FINISHED] [..]
",
)
.run();
}

#[cargo_test]
fn link_to_private_item() {
let main = r#"
1 change: 1 addition & 0 deletions tests/testsuite/main.rs
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ mod cargo_features;
mod cargo_targets;
mod cfg;
mod check;
mod check_cfg;
mod clean;
mod collisions;
mod concurrent;
182 changes: 0 additions & 182 deletions tests/testsuite/test.rs
Original file line number Diff line number Diff line change
@@ -4499,185 +4499,3 @@ fn test_workspaces_cwd() {
.with_stdout_contains("test test_integration_deep_cwd ... ok")
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_features() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[features]
f_a = []
f_b = []
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("test -v -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values(feature, \"f_a\", \"f_b\")' [..]
[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
[RUNNING] [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_features_doc() {
if !is_nightly() {
// --check-cfg is a nightly only rustc and rustdoc command line
return;
}

let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.1.0"
[features]
default = ["f_a"]
f_a = []
f_b = []
"#,
)
.file("src/lib.rs", "#[allow(dead_code)] fn foo() {}")
.build();

p.cargo("test -v --doc -Z check-cfg-features")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values(feature, \"default\", \"f_a\", \"f_b\")' [..]
[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
[DOCTEST] foo
[RUNNING] `rustdoc [..] --check-cfg 'values(feature, \"default\", \"f_a\", \"f_b\")' [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_names() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("test -v -Z check-cfg-well-known-names")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'names()' [..]
[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
[RUNNING] [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_values() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("test -v -Z check-cfg-well-known-values")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values()' [..]
[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
[RUNNING] [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_names_doc() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/lib.rs", "#[allow(dead_code)] fn foo() {}")
.build();

p.cargo("test -v --doc -Z check-cfg-well-known-names")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'names()' [..]
[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
[DOCTEST] foo
[RUNNING] `rustdoc [..] --check-cfg 'names()' [..]
",
)
.run();
}

#[cfg_attr(windows, ignore)] // weird normalization issue with windows and cargo-test-support
#[cargo_test]
fn check_cfg_well_known_values_doc() {
if !is_nightly() {
// --check-cfg is a nightly only rustc command line
return;
}

let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
.file("src/lib.rs", "#[allow(dead_code)] fn foo() {}")
.build();

p.cargo("test -v --doc -Z check-cfg-well-known-values")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo v0.1.0 [..]
[RUNNING] `rustc [..] --check-cfg 'values()' [..]
[FINISHED] test [unoptimized + debuginfo] target(s) in [..]
[DOCTEST] foo
[RUNNING] `rustdoc [..] --check-cfg 'values()' [..]
",
)
.run();
}