Skip to content
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

Adjust -Zcheck-cfg for new rustc syntax and behavior #12845

Merged
merged 2 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
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
10 changes: 2 additions & 8 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
paths::create_dir_all(&script_out_dir)?;

let nightly_features_allowed = cx.bcx.config.nightly_features_allowed;
let extra_check_cfg = match cx.bcx.config.cli_unstable().check_cfg {
Some((_, _, _, output)) => output,
None => false,
};
let extra_check_cfg = cx.bcx.config.cli_unstable().check_cfg;
let targets: Vec<Target> = unit.pkg.targets().to_vec();
// Need a separate copy for the fresh closure.
let targets_fresh = targets.clone();
Expand Down Expand Up @@ -1126,10 +1123,7 @@ fn prev_build_output(cx: &mut Context<'_, '_>, unit: &Unit) -> (Option<BuildOutp
&unit.pkg.to_string(),
&prev_script_out_dir,
&script_out_dir,
match cx.bcx.config.cli_unstable().check_cfg {
Some((_, _, _, output)) => output,
None => false,
},
cx.bcx.config.cli_unstable().check_cfg,
cx.bcx.config.nightly_features_allowed,
unit.pkg.targets(),
)
Expand Down
53 changes: 23 additions & 30 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1167,39 +1167,32 @@ fn features_args(unit: &Unit) -> Vec<OsString> {
///
/// [`check-cfg`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#check-cfg
fn check_cfg_args(cx: &Context<'_, '_>, unit: &Unit) -> Vec<OsString> {
if let Some((features, well_known_names, well_known_values, _output)) =
cx.bcx.config.cli_unstable().check_cfg
{
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("\"");
if cx.bcx.config.cli_unstable().check_cfg {
// This generate something like this:
// - cfg(feature, values())
// - cfg(feature, values("foo", "bar"))
//
// NOTE: Despite only explicitly specifying `feature`, well known names and values
// are implicitly enabled when one or more `--check-cfg` argument is passed.

let gross_cap_estimation = unit.pkg.summary().features().len() * 7 + 25;
let mut arg_feature = OsString::with_capacity(gross_cap_estimation);
arg_feature.push("cfg(feature, values(");
for (i, feature) in unit.pkg.summary().features().keys().enumerate() {
if i != 0 {
arg_feature.push(", ");
}
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 well_known_values {
args.push(OsString::from("--check-cfg"));
args.push(OsString::from("values()"));
arg_feature.push("\"");
arg_feature.push(feature);
arg_feature.push("\"");
}
arg_feature.push("))");

args
vec![
OsString::from("-Zunstable-options"),
OsString::from("--check-cfg"),
arg_feature,
]
} else {
Vec::new()
}
Expand Down
45 changes: 2 additions & 43 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,8 +731,7 @@ unstable_cli_options!(
#[serde(deserialize_with = "deserialize_build_std")]
build_std: Option<Vec<String>> = ("Enable Cargo to compile the standard library itself as part of a crate graph compilation"),
build_std_features: Option<Vec<String>> = ("Configure features enabled for the standard library itself when building the standard library"),
#[serde(deserialize_with = "deserialize_check_cfg")]
check_cfg: Option<(/*features:*/ bool, /*well_known_names:*/ bool, /*well_known_values:*/ bool, /*output:*/ bool)> = ("Specify scope of compile-time checking of `cfg` names/values"),
check_cfg: bool = ("Enable compile-time checking of `cfg` names/values/features"),
epage marked this conversation as resolved.
Show resolved Hide resolved
codegen_backend: bool = ("Enable the `codegen-backend` option in profiles in .cargo/config.toml file"),
config_include: bool = ("Enable the `include` key in config files"),
direct_minimal_versions: bool = ("Resolve minimal dependency versions instead of maximum (direct dependencies only)"),
Expand Down Expand Up @@ -842,20 +841,6 @@ where
))
}

fn deserialize_check_cfg<'de, D>(
deserializer: D,
) -> Result<Option<(bool, bool, bool, bool)>, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de::Error;
let Some(crates) = <Option<Vec<String>>>::deserialize(deserializer)? else {
return Ok(None);
};

parse_check_cfg(crates.into_iter()).map_err(D::Error::custom)
}

#[derive(Debug, Copy, Clone, Default, Deserialize)]
pub struct GitoxideFeatures {
/// All fetches are done with `gitoxide`, which includes git dependencies as well as the crates index.
Expand Down Expand Up @@ -924,32 +909,6 @@ fn parse_gitoxide(
Ok(Some(out))
}

fn parse_check_cfg(
it: impl Iterator<Item = impl AsRef<str>>,
) -> CargoResult<Option<(bool, bool, bool, bool)>> {
let mut features = false;
let mut well_known_names = false;
let mut well_known_values = false;
let mut output = false;

for e in it {
match e.as_ref() {
"features" => features = true,
"names" => well_known_names = true,
"values" => well_known_values = true,
"output" => output = true,
_ => bail!("unstable check-cfg only takes `features`, `names`, `values` or `output` as valid inputs"),
}
}

Ok(Some((
features,
well_known_names,
well_known_values,
output,
)))
}

impl CliUnstable {
pub fn parse(
&mut self,
Expand Down Expand Up @@ -1107,7 +1066,7 @@ impl CliUnstable {
}
"build-std-features" => self.build_std_features = Some(parse_features(v)),
"check-cfg" => {
self.check_cfg = v.map_or(Ok(None), |v| parse_check_cfg(v.split(',')))?
self.check_cfg = parse_empty(k, v)?;
}
"codegen-backend" => self.codegen_backend = parse_empty(k, v)?,
"config-include" => self.config_include = parse_empty(k, v)?,
Expand Down
6 changes: 1 addition & 5 deletions src/cargo/util/config/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,6 @@ fn parse_links_overrides(
config: &Config,
) -> CargoResult<BTreeMap<String, BuildOutput>> {
let mut links_overrides = BTreeMap::new();
let extra_check_cfg = match config.cli_unstable().check_cfg {
Some((_, _, _, output)) => output,
None => false,
};

for (lib_name, value) in links {
// Skip these keys, it shares the namespace with `TargetConfig`.
Expand Down Expand Up @@ -207,7 +203,7 @@ fn parse_links_overrides(
output.cfgs.extend(list.iter().map(|v| v.0.clone()));
}
"rustc-check-cfg" => {
if extra_check_cfg {
if config.cli_unstable().check_cfg {
let list = value.list(key)?;
output.check_cfgs.extend(list.iter().map(|v| v.0.clone()));
} else {
Expand Down
45 changes: 18 additions & 27 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -1080,34 +1080,14 @@ you are ok with dev-deps being build for `cargo doc`.
* RFC: [#3013](https://github.com/rust-lang/rfcs/pull/3013)
* Tracking Issue: [#10554](https://github.com/rust-lang/cargo/issues/10554)

`-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.
`-Z check-cfg` command line enables compile time checking of Cargo features as well as `rustc`
well known names and values in `#[cfg]`, `cfg!`, `#[link]` and `#[cfg_attr]` with the `rustc`
and `rustdoc` unstable `--check-cfg` command line.

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()`.
- `output`: enable the use of `rustc-check-cfg` in build script.

For instance:

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

Or for `output`:

```rust,no_run
// build.rs
println!("cargo:rustc-check-cfg=names(foo, bar)");
```
You can use the flag like this:

```
cargo check -Z unstable-options -Z check-cfg=output
cargo check -Z unstable-options -Z check-cfg
```

### `cargo:rustc-check-cfg=CHECK_CFG`
Expand All @@ -1116,12 +1096,23 @@ The `rustc-check-cfg` instruction tells Cargo to pass the given value to the
`--check-cfg` flag to the compiler. This may be used for compile-time
detection of unexpected conditional compilation name and/or values.

This can only be used in combination with `-Zcheck-cfg=output` otherwise it is ignored
This can only be used in combination with `-Zcheck-cfg` otherwise it is ignored
with a warning.

If you want to integrate with Cargo features, use `-Zcheck-cfg=features` instead of
If you want to integrate with Cargo features, only use `-Zcheck-cfg` instead of
trying to do it manually with this option.

You can use the instruction like this:

```rust,no_run
// build.rs
println!("cargo:rustc-check-cfg=cfg(foo, bar)");
```

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

## codegen-backend

The `codegen-backend` feature makes it possible to select the codegen backend used by rustc using a profile.
Expand Down
Loading