Skip to content

Commit

Permalink
Auto merge of #10566 - Urgau:check-cfg-improvements, r=ehuss
Browse files Browse the repository at this point in the history
Improve support of condition compilation checking

This PR is a series of improvements to the check-cfg implementation.

### What does this PR try to resolve?

This PR resolve the concern expressed in #10486 (comment) that is:
 * Fixing the tests on Windows: e8aa51d
 * Merging all the -Z flags under -Zcheck-cfg: 969e282
 * Moving of all of the check-cfg tests into a separate module: c18b442
 * And removing of an unused parameter: 068bdf4

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

This PR should be reviewed commit by commit and tested with the automated tests or examples.

### Additional information

I decided to use a custom macro to make the test functional under Windows, the macro generate a contains line with the correct escaping depending on the platform (windows or not windows).
  • Loading branch information
bors committed May 6, 2022
2 parents 08b8fe5 + 6f2fae1 commit 6878c43
Show file tree
Hide file tree
Showing 10 changed files with 530 additions and 626 deletions.
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
65 changes: 32 additions & 33 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand All @@ -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> {
Expand Down
29 changes: 23 additions & 6 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)?,
Expand Down
43 changes: 13 additions & 30 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 6878c43

Please sign in to comment.