Rollup merge of #150840 - print-check-cfg-rework-output, r=nnethercote
Make `--print=check-cfg` output compatible `--check-cfg` arguments This PR changes significantly the output of the unstable `--print=check-cfg` option. Specifically it removes the ad-hoc resemblance with `--print=cfg` in order to output a simplified but still compatible `--check-cfg` arguments. The goal is to future proof the output of `--print=check-cfg` like `--check-cfg` is, and the best way to do that is to use it's syntax. This is particularly relevant for [RFC3905](https://github.com/rust-lang/rfcs/pull/3905) which wants to introduce a new predicate: `version(...)`.
This commit is contained in:
commit
080c7043c1
4 changed files with 89 additions and 57 deletions
|
|
@ -765,30 +765,35 @@ fn print_crate_info(
|
|||
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::Any => {
|
||||
check_cfgs.push(format!("cfg({name}, values(any()))"))
|
||||
}
|
||||
ExpectedValues::Some(values) => {
|
||||
if !values.is_empty() {
|
||||
check_cfgs.extend(values.iter().map(|value| {
|
||||
let mut values: Vec<_> = values
|
||||
.iter()
|
||||
.map(|value| {
|
||||
if let Some(value) = value {
|
||||
format!("{name}=\"{value}\"")
|
||||
format!("\"{value}\"")
|
||||
} else {
|
||||
name.to_string()
|
||||
"none()".to_string()
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
check_cfgs.push(format!("{name}="))
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
values.sort_unstable();
|
||||
|
||||
let values = values.join(", ");
|
||||
|
||||
check_cfgs.push(format!("cfg({name}, values({values}))"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()");
|
||||
}
|
||||
if !sess.psess.check_config.exhaustive_names
|
||||
&& sess.psess.check_config.exhaustive_values
|
||||
{
|
||||
println_info!("cfg(any())");
|
||||
}
|
||||
for check_cfg in check_cfgs {
|
||||
println_info!("{check_cfg}");
|
||||
|
|
|
|||
|
|
@ -9,18 +9,20 @@ This option of the `--print` flag print the list of all the expected cfgs.
|
|||
This is related to the [`--check-cfg` flag][check-cfg] which allows specifying arbitrary expected
|
||||
names and values.
|
||||
|
||||
This print option works similarly to `--print=cfg` (modulo check-cfg specifics).
|
||||
This print option outputs compatible `--check-cfg` arguments with a reduced syntax where all the
|
||||
expected values are on the same line and `values(...)` is always explicit.
|
||||
|
||||
| `--check-cfg` | `--print=check-cfg` |
|
||||
|-----------------------------------|-----------------------------|
|
||||
| `cfg(foo)` | `foo` |
|
||||
| `cfg(foo, values("bar"))` | `foo="bar"` |
|
||||
| `cfg(foo, values(none(), "bar"))` | `foo` & `foo="bar"` |
|
||||
| | *check-cfg specific syntax* |
|
||||
| `cfg(foo, values(any())` | `foo=any()` |
|
||||
| `cfg(foo, values())` | `foo=` |
|
||||
| `cfg(any())` | `any()` |
|
||||
| *none* | `any()=any()` |
|
||||
| `--check-cfg` | `--print=check-cfg` |
|
||||
|-----------------------------------|-----------------------------------|
|
||||
| `cfg(foo)` | `cfg(foo, values(none())) |
|
||||
| `cfg(foo, values("bar"))` | `cfg(foo, values("bar"))` |
|
||||
| `cfg(foo, values(none(), "bar"))` | `cfg(foo, values(none(), "bar"))` |
|
||||
| `cfg(foo, values(any())` | `cfg(foo, values(any())` |
|
||||
| `cfg(foo, values())` | `cfg(foo, values())` |
|
||||
| `cfg(any())` | `cfg(any())` |
|
||||
| *nothing* | *nothing* |
|
||||
|
||||
The print option includes well known cfgs.
|
||||
|
||||
To be used like this:
|
||||
|
||||
|
|
@ -28,4 +30,7 @@ To be used like this:
|
|||
rustc --print=check-cfg -Zunstable-options lib.rs
|
||||
```
|
||||
|
||||
> **Note:** Users should be resilient when parsing, in particular against new predicates that
|
||||
may be added in the future.
|
||||
|
||||
[check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html
|
||||
|
|
|
|||
|
|
@ -1070,11 +1070,27 @@ fn builtin_cfg_names(config: &Config) -> HashSet<String> {
|
|||
Default::default(),
|
||||
)
|
||||
.lines()
|
||||
.map(|l| if let Some((name, _)) = l.split_once('=') { name.to_string() } else { l.to_string() })
|
||||
.map(|l| extract_cfg_name(&l).unwrap().to_string())
|
||||
.chain(std::iter::once(String::from("test")))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Extract the cfg name from `cfg(name, values(...))` lines
|
||||
fn extract_cfg_name(check_cfg_line: &str) -> Result<&str, &'static str> {
|
||||
let trimmed = check_cfg_line.trim();
|
||||
|
||||
#[rustfmt::skip]
|
||||
let inner = trimmed
|
||||
.strip_prefix("cfg(")
|
||||
.ok_or("missing cfg(")?
|
||||
.strip_suffix(")")
|
||||
.ok_or("missing )")?;
|
||||
|
||||
let first_comma = inner.find(',').ok_or("no comma found")?;
|
||||
|
||||
Ok(inner[..first_comma].trim())
|
||||
}
|
||||
|
||||
pub const KNOWN_CRATE_TYPES: &[&str] =
|
||||
&["bin", "cdylib", "dylib", "lib", "proc-macro", "rlib", "staticlib"];
|
||||
|
||||
|
|
|
|||
|
|
@ -14,51 +14,55 @@ struct CheckCfg {
|
|||
|
||||
enum Contains {
|
||||
Some { contains: &'static [&'static str], doesnt_contain: &'static [&'static str] },
|
||||
Only(&'static str),
|
||||
Nothing,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
check(CheckCfg { args: &[], contains: Contains::Only("any()=any()") });
|
||||
check(CheckCfg { args: &[], contains: Contains::Nothing });
|
||||
check(CheckCfg {
|
||||
args: &["--check-cfg=cfg()"],
|
||||
contains: Contains::Some {
|
||||
contains: &["unix", "miri"],
|
||||
doesnt_contain: &["any()", "any()=any()"],
|
||||
contains: &["cfg(unix, values(none()))", "cfg(miri, values(none()))"],
|
||||
doesnt_contain: &["cfg(any())"],
|
||||
},
|
||||
});
|
||||
check(CheckCfg {
|
||||
args: &["--check-cfg=cfg(any())"],
|
||||
contains: Contains::Some {
|
||||
contains: &["any()", "unix", r#"target_feature="crt-static""#],
|
||||
contains: &["cfg(any())", "cfg(unix, values(none()))"],
|
||||
doesnt_contain: &["any()=any()"],
|
||||
},
|
||||
});
|
||||
check(CheckCfg {
|
||||
args: &["--check-cfg=cfg(feature)"],
|
||||
contains: Contains::Some {
|
||||
contains: &["unix", "miri", "feature"],
|
||||
doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="],
|
||||
contains: &[
|
||||
"cfg(unix, values(none()))",
|
||||
"cfg(miri, values(none()))",
|
||||
"cfg(feature, values(none()))",
|
||||
],
|
||||
doesnt_contain: &["cfg(any())", "cfg(feature)"],
|
||||
},
|
||||
});
|
||||
check(CheckCfg {
|
||||
args: &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#],
|
||||
contains: Contains::Some {
|
||||
contains: &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""],
|
||||
doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="],
|
||||
contains: &[r#"cfg(feature, values("", "lol", "test", none()))"#],
|
||||
doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"],
|
||||
},
|
||||
});
|
||||
check(CheckCfg {
|
||||
args: &["--check-cfg=cfg(feature, values())"],
|
||||
contains: Contains::Some {
|
||||
contains: &["feature="],
|
||||
doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature"],
|
||||
contains: &["cfg(feature, values())"],
|
||||
doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"],
|
||||
},
|
||||
});
|
||||
check(CheckCfg {
|
||||
args: &["--check-cfg=cfg(feature, values())", "--check-cfg=cfg(feature, values(none()))"],
|
||||
contains: Contains::Some {
|
||||
contains: &["feature"],
|
||||
doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="],
|
||||
contains: &["cfg(feature, values(none()))"],
|
||||
doesnt_contain: &["cfg(any())", "cfg(feature, values())"],
|
||||
},
|
||||
});
|
||||
check(CheckCfg {
|
||||
|
|
@ -67,8 +71,8 @@ fn main() {
|
|||
r#"--check-cfg=cfg(feature, values("tmp"))"#,
|
||||
],
|
||||
contains: Contains::Some {
|
||||
contains: &["unix", "miri", "feature=any()"],
|
||||
doesnt_contain: &["any()", "any()=any()", "feature", "feature=", "feature=\"tmp\""],
|
||||
contains: &["cfg(feature, values(any()))"],
|
||||
doesnt_contain: &["cfg(any())", r#"cfg(feature, values("tmp"))"#],
|
||||
},
|
||||
});
|
||||
check(CheckCfg {
|
||||
|
|
@ -78,8 +82,12 @@ fn main() {
|
|||
r#"--check-cfg=cfg(feature, values("tmp"))"#,
|
||||
],
|
||||
contains: Contains::Some {
|
||||
contains: &["has_foo", "has_bar", "feature=\"tmp\""],
|
||||
doesnt_contain: &["any()", "any()=any()", "feature"],
|
||||
contains: &[
|
||||
"cfg(has_foo, values(none()))",
|
||||
"cfg(has_bar, values(none()))",
|
||||
r#"cfg(feature, values("tmp"))"#,
|
||||
],
|
||||
doesnt_contain: &["cfg(any())", "cfg(feature)"],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -94,16 +102,15 @@ fn check(CheckCfg { args, contains }: CheckCfg) {
|
|||
|
||||
for l in stdout.lines() {
|
||||
assert!(l == l.trim());
|
||||
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!(found.insert(l.to_string()), "{}", &l);
|
||||
assert!(l.starts_with("cfg("), "{l}");
|
||||
assert!(l.ends_with(")"), "{l}");
|
||||
assert_eq!(
|
||||
l.chars().filter(|c| *c == '(').count(),
|
||||
l.chars().filter(|c| *c == ')').count(),
|
||||
"{l}"
|
||||
);
|
||||
assert!(l.chars().filter(|c| *c == '"').count() % 2 == 0, "{l}");
|
||||
assert!(found.insert(l.to_string()), "{l}");
|
||||
}
|
||||
|
||||
match contains {
|
||||
|
|
@ -131,9 +138,8 @@ fn check(CheckCfg { args, contains }: CheckCfg) {
|
|||
);
|
||||
}
|
||||
}
|
||||
Contains::Only(only) => {
|
||||
assert!(found.contains(&only.to_string()), "{:?} != {:?}", &only, &found);
|
||||
assert!(found.len() == 1, "len: {}, instead of 1", found.len());
|
||||
Contains::Nothing => {
|
||||
assert!(found.len() == 0, "len: {}, instead of 0", found.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue