Skip to content

Commit

Permalink
Auto merge of #10428 - Urgau:check-cfg-features-rustdoc, r=ehuss
Browse files Browse the repository at this point in the history
Add -Z check-cfg-features support for rustdoc

This PR is a follow to #10408 where support for compile-time checking of features was implemented for `rustc`.

At the time `rustdoc` support wasn't yet merged, but now that it has been [merged](rust-lang/rust#94154), this pull-request add support for it in the `doc` and `test --doc` (doctest) mode.

r? `@alexcrichton`
  • Loading branch information
bors committed Feb 27, 2022
2 parents 1e55490 + e828e85 commit f75d4ea
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 34 deletions.
5 changes: 1 addition & 4 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,8 @@ 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));

for feature in &unit.features {
args.push("--cfg".into());
args.push(format!("feature=\"{}\"", feature).into());
}
let script_meta = self.find_build_script_metadata(unit);
if let Some(meta) = script_meta {
if let Some(output) = self.build_script_outputs.lock().unwrap().get(meta) {
Expand Down
58 changes: 31 additions & 27 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,10 +645,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
paths::create_dir_all(&doc_dir)?;

rustdoc.arg("-o").arg(&doc_dir);

for feat in &unit.features {
rustdoc.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
}
rustdoc.args(&features_args(cx, unit));

add_error_format_and_color(cx, &mut rustdoc);
add_allow_features(cx, &mut rustdoc);
Expand Down Expand Up @@ -791,28 +788,6 @@ fn add_allow_features(cx: &Context<'_, '_>, cmd: &mut ProcessBuilder) {
}
}

/// Add all features as cfg
fn add_features(cx: &Context<'_, '_>, cmd: &mut ProcessBuilder, unit: &Unit) {
for feat in &unit.features {
cmd.arg("--cfg").arg(&format!("feature=\"{}\"", feat));
}

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

cmd.arg("-Zunstable-options").arg("--check-cfg").arg(&arg);
}
}

/// Add error-format flags to the command.
///
/// Cargo always uses JSON output. This has several benefits, such as being
Expand Down Expand Up @@ -990,7 +965,7 @@ fn build_base_args(
cmd.arg("--cfg").arg("test");
}

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

let meta = cx.files().metadata(unit);
cmd.arg("-C").arg(&format!("metadata={}", meta));
Expand Down Expand Up @@ -1064,6 +1039,35 @@ fn build_base_args(
Ok(())
}

/// Features with --cfg and all features with --check-cfg
fn features_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
let mut args = Vec::with_capacity(unit.features.len() + 2);

for feat in &unit.features {
args.push(OsString::from("--cfg"));
args.push(OsString::from(format!("feature=\"{}\"", feat)));
}

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("\"");
}
arg.push(")");

args.push(OsString::from("-Zunstable-options"));
args.push(OsString::from("--check-cfg"));
args.push(arg);
}

args
}

fn lto_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
let mut result = Vec::new();
let mut push = |arg: &str| {
Expand Down
6 changes: 3 additions & 3 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -1132,9 +1132,9 @@ cargo doc -Z unstable-options -Z rustdoc-scrape-examples=examples
* RFC: [#3013](https://github.com/rust-lang/rfcs/pull/3013)

The `-Z check-cfg-features` argument tells Cargo to pass all possible features of a package to
`rustc` 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.
`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:

```
Expand Down
37 changes: 37 additions & 0 deletions tests/testsuite/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2697,3 +2697,40 @@ fn doc_lib_false_dep() {
assert!(p.build_dir().join("doc/foo").exists());
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();
}
39 changes: 39 additions & 0 deletions tests/testsuite/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4536,3 +4536,42 @@ fn check_cfg_features() {
)
.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();
}

0 comments on commit f75d4ea

Please sign in to comment.