mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #124320 - Urgau:print-check-cfg, r=petrochenkov
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: https://github.com/rust-lang/compiler-team/issues/743 ``@rustbot`` label +F-check-cfg +S-waiting-on-MCP r? ``@petrochenkov``
This commit is contained in:
commit
7e441a11a1
@ -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();
|
||||
|
@ -773,6 +773,7 @@ pub enum PrintKind {
|
||||
TargetLibdir,
|
||||
CrateName,
|
||||
Cfg,
|
||||
CheckCfg,
|
||||
CallingConventions,
|
||||
TargetList,
|
||||
TargetCPUs,
|
||||
@ -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]",
|
||||
@ -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),
|
||||
@ -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 =
|
||||
|
25
src/doc/unstable-book/src/compiler-flags/print-check-cfg.md
Normal file
25
src/doc/unstable-book/src/compiler-flags/print-check-cfg.md
Normal file
@ -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
tests/run-make/print-check-cfg/lib.rs
Normal file
1
tests/run-make/print-check-cfg/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
// empty crate
|
106
tests/run-make/print-check-cfg/rmake.rs
Normal file
106
tests/run-make/print-check-cfg/rmake.rs
Normal file
@ -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
tests/ui/feature-gates/feature-gate-print-check-cfg.rs
Normal file
3
tests/ui/feature-gates/feature-gate-print-check-cfg.rs
Normal file
@ -0,0 +1,3 @@
|
||||
//@ compile-flags: --print=check-cfg
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,2 @@
|
||||
error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option
|
||||
|
@ -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`
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user