Skip to content

Commit

Permalink
Auto merge of #10486 - Urgau:check-cfg-well-known, r=weihanglo
Browse files Browse the repository at this point in the history
Add support for rustc --check-cfg well known names and values

This pull-request add support for `rustc` `--check-cfg` well known names and values.

### What does this PR try to resolve?

This pull-request add support for `rustc` `--check-cfg` well known names and values:

- `-Z check-cfg-well-known-names`: `--check-cfg names()` well known names
- `-Z check-cfg-well-known-values`: `--check-cfg values()` well known values

### How should we test and review this PR?

#### Testing

`cargo check -Z check-cfg-well-known-names` and
`cargo check -Z check-cfg-well-known-values`

#### Review

This PR contains one commit that split `features_args` into `check_cfg_args`, add the well known support in it, adds call to that new function and add documentation and test for those new flags.

### Additional information

This was implemented as two new additional flags because it's most likely that these flags will not be stabilize at the same time and also because some of these flags may become the default.

RFC: rust-lang/rfcs#3013
`-Z check-cfg-features`: #10408
`cargo doc` support: #10428
  • Loading branch information
bors committed Apr 12, 2022
2 parents 50d52eb + 02cd944 commit 403c6bd
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
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::check_cfg_args(&self, unit));

let script_meta = self.find_build_script_metadata(unit);
if let Some(meta) = script_meta {
Expand Down
34 changes: 30 additions & 4 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {

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

add_error_format_and_color(cx, &mut rustdoc);
add_allow_features(cx, &mut rustdoc);
Expand Down Expand Up @@ -966,6 +967,7 @@ fn build_base_args(
}

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

let meta = cx.files().metadata(unit);
cmd.arg("-C").arg(&format!("metadata={}", meta));
Expand Down Expand Up @@ -1039,15 +1041,30 @@ 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);
/// All active features for the unit passed as --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)));
}

args
}

/// 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
{
return Vec::new();
}

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

if cx.bcx.config.cli_unstable().check_cfg_features {
// This generate something like this:
// - values(feature)
Expand All @@ -1060,11 +1077,20 @@ fn features_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
}
arg.push(")");

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

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

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

args
}

Expand Down
4 changes: 4 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,8 @@ unstable_cli_options!(
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`"),
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"),
Expand Down Expand Up @@ -841,6 +843,8 @@ impl CliUnstable {
"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)?,
"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)?,
Expand Down
26 changes: 26 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,32 @@ 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)

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)

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
```

## Stabilized and removed features

### Compile progress
Expand Down
86 changes: 86 additions & 0 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6388,3 +6388,89 @@ fn check_cfg_features_with_namespaced_features() {
)
.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();
}
50 changes: 50 additions & 0 deletions tests/testsuite/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,3 +1050,53 @@ fn check_cfg_features() {
)
.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();
}
106 changes: 106 additions & 0 deletions tests/testsuite/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4575,3 +4575,109 @@ fn check_cfg_features_doc() {
)
.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();
}

0 comments on commit 403c6bd

Please sign in to comment.