Skip to content

Commit

Permalink
Rollup merge of rust-lang#124320 - Urgau:print-check-cfg, r=petrochenkov
Browse files Browse the repository at this point in the history
Add `--print=check-cfg` to get the expected configs

This PR adds a new `--print` variant `check-cfg` to get the expected configs.

Details and rational can be found on the MCP: rust-lang/compiler-team#743

`@rustbot` label +F-check-cfg +S-waiting-on-MCP
r? `@petrochenkov`
  • Loading branch information
jieyouxu committed May 28, 2024
2 parents 7c82b4d + ac59bdc commit ddcc5bd
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 2 deletions.
33 changes: 33 additions & 0 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,39 @@ fn print_crate_info(
println_info!("{cfg}");
}
}
CheckCfg => {
let mut check_cfgs: Vec<String> = Vec::with_capacity(410);

// INSTABILITY: We are sorting the output below.
#[allow(rustc::potential_query_instability)]
for (name, expected_values) in &sess.psess.check_config.expecteds {
use crate::config::ExpectedValues;
match expected_values {
ExpectedValues::Any => check_cfgs.push(format!("{name}=any()")),
ExpectedValues::Some(values) => {
check_cfgs.extend(values.iter().map(|value| {
if let Some(value) = value {
format!("{name}=\"{value}\"")
} else {
name.to_string()
}
}))
}
}
}

check_cfgs.sort_unstable();
if !sess.psess.check_config.exhaustive_names {
if !sess.psess.check_config.exhaustive_values {
println_info!("any()=any()");
} else {
println_info!("any()");
}
}
for check_cfg in check_cfgs {
println_info!("{check_cfg}");
}
}
CallingConventions => {
let mut calling_conventions = rustc_target::spec::abi::all_names();
calling_conventions.sort_unstable();
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ pub enum PrintKind {
TargetLibdir,
CrateName,
Cfg,
CheckCfg,
CallingConventions,
TargetList,
TargetCPUs,
Expand Down Expand Up @@ -1443,7 +1444,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
"",
"print",
"Compiler information to print on stdout",
"[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\
"[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\
target-list|target-cpus|target-features|relocation-models|code-models|\
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
stack-protector-strategies|link-args|deployment-target]",
Expand Down Expand Up @@ -1859,6 +1860,7 @@ fn collect_print_requests(
("all-target-specs-json", PrintKind::AllTargetSpecs),
("calling-conventions", PrintKind::CallingConventions),
("cfg", PrintKind::Cfg),
("check-cfg", PrintKind::CheckCfg),
("code-models", PrintKind::CodeModels),
("crate-name", PrintKind::CrateName),
("deployment-target", PrintKind::DeploymentTarget),
Expand Down Expand Up @@ -1908,6 +1910,16 @@ fn collect_print_requests(
);
}
}
Some((_, PrintKind::CheckCfg)) => {
if unstable_opts.unstable_options {
PrintKind::CheckCfg
} else {
early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \
enable the check-cfg print option",
);
}
}
Some(&(_, print_kind)) => print_kind,
None => {
let prints =
Expand Down
25 changes: 25 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/print-check-cfg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# `print=check-cfg`

The tracking issue for this feature is: [#XXXXXX](https://github.com/rust-lang/rust/issues/XXXXXX).

------------------------

This option of the `--print` flag print the list of expected cfgs.

This is related to the `--check-cfg` flag which allows specifying arbitrary expected
names and values.

This print option works similarly to `--print=cfg` (modulo check-cfg specifics):
- *check_cfg syntax*: *output of --print=check-cfg*
- `cfg(windows)`: `windows`
- `cfg(feature, values("foo", "bar"))`: `feature="foo"` and `feature="bar"`
- `cfg(feature, values(none(), ""))`: `feature` and `feature=""`
- `cfg(feature, values(any()))`: `feature=any()`
- `cfg(any())`: `any()`
- *nothing*: `any()=any()`

To be used like this:

```bash
rustc --print=check-cfg -Zunstable-options lib.rs
```
1 change: 1 addition & 0 deletions tests/run-make/print-check-cfg/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty crate
106 changes: 106 additions & 0 deletions tests/run-make/print-check-cfg/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
//! This checks the output of `--print=check-cfg`

extern crate run_make_support;

use std::collections::HashSet;
use std::iter::FromIterator;
use std::ops::Deref;

use run_make_support::rustc;

fn main() {
check(
/*args*/ &[],
/*has_any*/ false,
/*has_any_any*/ true,
/*contains*/ &[],
);
check(
/*args*/ &["--check-cfg=cfg()"],
/*has_any*/ false,
/*has_any_any*/ false,
/*contains*/ &["unix", "miri"],
);
check(
/*args*/ &["--check-cfg=cfg(any())"],
/*has_any*/ true,
/*has_any_any*/ false,
/*contains*/ &["windows", "test"],
);
check(
/*args*/ &["--check-cfg=cfg(feature)"],
/*has_any*/ false,
/*has_any_any*/ false,
/*contains*/ &["unix", "miri", "feature"],
);
check(
/*args*/ &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#],
/*has_any*/ false,
/*has_any_any*/ false,
/*contains*/ &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""],
);
check(
/*args*/ &[
r#"--check-cfg=cfg(feature, values(any()))"#,
r#"--check-cfg=cfg(feature, values("tmp"))"#
],
/*has_any*/ false,
/*has_any_any*/ false,
/*contains*/ &["unix", "miri", "feature=any()"],
);
check(
/*args*/ &[
r#"--check-cfg=cfg(has_foo, has_bar)"#,
r#"--check-cfg=cfg(feature, values("tmp"))"#,
r#"--check-cfg=cfg(feature, values("tmp"))"#
],
/*has_any*/ false,
/*has_any_any*/ false,
/*contains*/ &["has_foo", "has_bar", "feature=\"tmp\""],
);
}

fn check(args: &[&str], has_any: bool, has_any_any: bool, contains: &[&str]) {
let output = rustc()
.input("lib.rs")
.arg("-Zunstable-options")
.arg("--print=check-cfg")
.args(&*args)
.run();

let stdout = String::from_utf8(output.stdout).unwrap();

let mut found_any = false;
let mut found_any_any = false;
let mut found = HashSet::<String>::new();
let mut recorded = HashSet::<String>::new();

for l in stdout.lines() {
assert!(l == l.trim());
if l == "any()" {
found_any = true;
} else if l == "any()=any()" {
found_any_any = true;
} else if let Some((left, right)) = l.split_once('=') {
if right != "any()" && right != "" {
assert!(right.starts_with("\""));
assert!(right.ends_with("\""));
}
assert!(!left.contains("\""));
} else {
assert!(!l.contains("\""));
}
assert!(recorded.insert(l.to_string()), "{}", &l);
if contains.contains(&l) {
assert!(found.insert(l.to_string()), "{}", &l);
}
}

let should_found = HashSet::<String>::from_iter(contains.iter().map(|s| s.to_string()));
let diff: Vec<_> = should_found.difference(&found).collect();

assert_eq!(found_any, has_any);
assert_eq!(found_any_any, has_any_any);
assert_eq!(found_any_any, recorded.len() == 1);
assert!(diff.is_empty(), "{:?} != {:?} (~ {:?})", &should_found, &found, &diff);
}
3 changes: 3 additions & 0 deletions tests/ui/feature-gates/feature-gate-print-check-cfg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//@ compile-flags: --print=check-cfg

fn main() {}
2 changes: 2 additions & 0 deletions tests/ui/feature-gates/feature-gate-print-check-cfg.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option

2 changes: 1 addition & 1 deletion tests/ui/invalid-compile-flags/print.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: unknown print request: `yyyy`
|
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`
= help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models`

0 comments on commit ddcc5bd

Please sign in to comment.