Skip to content

Commit ac59bdc

Browse files
committed
Add --print=check-cfg to get the expected configs
1 parent cb3752d commit ac59bdc

File tree

8 files changed

+184
-2
lines changed

8 files changed

+184
-2
lines changed

compiler/rustc_driver_impl/src/lib.rs

+33
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,39 @@ fn print_crate_info(
804804
println_info!("{cfg}");
805805
}
806806
}
807+
CheckCfg => {
808+
let mut check_cfgs: Vec<String> = Vec::with_capacity(410);
809+
810+
// INSTABILITY: We are sorting the output below.
811+
#[allow(rustc::potential_query_instability)]
812+
for (name, expected_values) in &sess.psess.check_config.expecteds {
813+
use crate::config::ExpectedValues;
814+
match expected_values {
815+
ExpectedValues::Any => check_cfgs.push(format!("{name}=any()")),
816+
ExpectedValues::Some(values) => {
817+
check_cfgs.extend(values.iter().map(|value| {
818+
if let Some(value) = value {
819+
format!("{name}=\"{value}\"")
820+
} else {
821+
name.to_string()
822+
}
823+
}))
824+
}
825+
}
826+
}
827+
828+
check_cfgs.sort_unstable();
829+
if !sess.psess.check_config.exhaustive_names {
830+
if !sess.psess.check_config.exhaustive_values {
831+
println_info!("any()=any()");
832+
} else {
833+
println_info!("any()");
834+
}
835+
}
836+
for check_cfg in check_cfgs {
837+
println_info!("{check_cfg}");
838+
}
839+
}
807840
CallingConventions => {
808841
let mut calling_conventions = rustc_target::spec::abi::all_names();
809842
calling_conventions.sort_unstable();

compiler/rustc_session/src/config.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ pub enum PrintKind {
745745
TargetLibdir,
746746
CrateName,
747747
Cfg,
748+
CheckCfg,
748749
CallingConventions,
749750
TargetList,
750751
TargetCPUs,
@@ -1424,7 +1425,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
14241425
"",
14251426
"print",
14261427
"Compiler information to print on stdout",
1427-
"[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\
1428+
"[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\
14281429
target-list|target-cpus|target-features|relocation-models|code-models|\
14291430
tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
14301431
stack-protector-strategies|link-args|deployment-target]",
@@ -1834,6 +1835,7 @@ fn collect_print_requests(
18341835
("all-target-specs-json", PrintKind::AllTargetSpecs),
18351836
("calling-conventions", PrintKind::CallingConventions),
18361837
("cfg", PrintKind::Cfg),
1838+
("check-cfg", PrintKind::CheckCfg),
18371839
("code-models", PrintKind::CodeModels),
18381840
("crate-name", PrintKind::CrateName),
18391841
("deployment-target", PrintKind::DeploymentTarget),
@@ -1883,6 +1885,16 @@ fn collect_print_requests(
18831885
);
18841886
}
18851887
}
1888+
Some((_, PrintKind::CheckCfg)) => {
1889+
if unstable_opts.unstable_options {
1890+
PrintKind::CheckCfg
1891+
} else {
1892+
early_dcx.early_fatal(
1893+
"the `-Z unstable-options` flag must also be passed to \
1894+
enable the check-cfg print option",
1895+
);
1896+
}
1897+
}
18861898
Some(&(_, print_kind)) => print_kind,
18871899
None => {
18881900
let prints =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# `print=check-cfg`
2+
3+
The tracking issue for this feature is: [#XXXXXX](https://github.com/rust-lang/rust/issues/XXXXXX).
4+
5+
------------------------
6+
7+
This option of the `--print` flag print the list of expected cfgs.
8+
9+
This is related to the `--check-cfg` flag which allows specifying arbitrary expected
10+
names and values.
11+
12+
This print option works similarly to `--print=cfg` (modulo check-cfg specifics):
13+
- *check_cfg syntax*: *output of --print=check-cfg*
14+
- `cfg(windows)`: `windows`
15+
- `cfg(feature, values("foo", "bar"))`: `feature="foo"` and `feature="bar"`
16+
- `cfg(feature, values(none(), ""))`: `feature` and `feature=""`
17+
- `cfg(feature, values(any()))`: `feature=any()`
18+
- `cfg(any())`: `any()`
19+
- *nothing*: `any()=any()`
20+
21+
To be used like this:
22+
23+
```bash
24+
rustc --print=check-cfg -Zunstable-options lib.rs
25+
```

tests/run-make/print-check-cfg/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// empty crate
+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//! This checks the output of `--print=check-cfg`
2+
3+
extern crate run_make_support;
4+
5+
use std::collections::HashSet;
6+
use std::iter::FromIterator;
7+
use std::ops::Deref;
8+
9+
use run_make_support::rustc;
10+
11+
fn main() {
12+
check(
13+
/*args*/ &[],
14+
/*has_any*/ false,
15+
/*has_any_any*/ true,
16+
/*contains*/ &[],
17+
);
18+
check(
19+
/*args*/ &["--check-cfg=cfg()"],
20+
/*has_any*/ false,
21+
/*has_any_any*/ false,
22+
/*contains*/ &["unix", "miri"],
23+
);
24+
check(
25+
/*args*/ &["--check-cfg=cfg(any())"],
26+
/*has_any*/ true,
27+
/*has_any_any*/ false,
28+
/*contains*/ &["windows", "test"],
29+
);
30+
check(
31+
/*args*/ &["--check-cfg=cfg(feature)"],
32+
/*has_any*/ false,
33+
/*has_any_any*/ false,
34+
/*contains*/ &["unix", "miri", "feature"],
35+
);
36+
check(
37+
/*args*/ &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#],
38+
/*has_any*/ false,
39+
/*has_any_any*/ false,
40+
/*contains*/ &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""],
41+
);
42+
check(
43+
/*args*/ &[
44+
r#"--check-cfg=cfg(feature, values(any()))"#,
45+
r#"--check-cfg=cfg(feature, values("tmp"))"#
46+
],
47+
/*has_any*/ false,
48+
/*has_any_any*/ false,
49+
/*contains*/ &["unix", "miri", "feature=any()"],
50+
);
51+
check(
52+
/*args*/ &[
53+
r#"--check-cfg=cfg(has_foo, has_bar)"#,
54+
r#"--check-cfg=cfg(feature, values("tmp"))"#,
55+
r#"--check-cfg=cfg(feature, values("tmp"))"#
56+
],
57+
/*has_any*/ false,
58+
/*has_any_any*/ false,
59+
/*contains*/ &["has_foo", "has_bar", "feature=\"tmp\""],
60+
);
61+
}
62+
63+
fn check(args: &[&str], has_any: bool, has_any_any: bool, contains: &[&str]) {
64+
let output = rustc()
65+
.input("lib.rs")
66+
.arg("-Zunstable-options")
67+
.arg("--print=check-cfg")
68+
.args(&*args)
69+
.run();
70+
71+
let stdout = String::from_utf8(output.stdout).unwrap();
72+
73+
let mut found_any = false;
74+
let mut found_any_any = false;
75+
let mut found = HashSet::<String>::new();
76+
let mut recorded = HashSet::<String>::new();
77+
78+
for l in stdout.lines() {
79+
assert!(l == l.trim());
80+
if l == "any()" {
81+
found_any = true;
82+
} else if l == "any()=any()" {
83+
found_any_any = true;
84+
} else if let Some((left, right)) = l.split_once('=') {
85+
if right != "any()" && right != "" {
86+
assert!(right.starts_with("\""));
87+
assert!(right.ends_with("\""));
88+
}
89+
assert!(!left.contains("\""));
90+
} else {
91+
assert!(!l.contains("\""));
92+
}
93+
assert!(recorded.insert(l.to_string()), "{}", &l);
94+
if contains.contains(&l) {
95+
assert!(found.insert(l.to_string()), "{}", &l);
96+
}
97+
}
98+
99+
let should_found = HashSet::<String>::from_iter(contains.iter().map(|s| s.to_string()));
100+
let diff: Vec<_> = should_found.difference(&found).collect();
101+
102+
assert_eq!(found_any, has_any);
103+
assert_eq!(found_any_any, has_any_any);
104+
assert_eq!(found_any_any, recorded.len() == 1);
105+
assert!(diff.is_empty(), "{:?} != {:?} (~ {:?})", &should_found, &found, &diff);
106+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//@ compile-flags: --print=check-cfg
2+
3+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option
2+
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
error: unknown print request: `yyyy`
22
|
3-
= 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`
3+
= 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`
44

0 commit comments

Comments
 (0)