Skip to content

Commit 92d99c3

Browse files
committed
Retrieve and parse --print=check-cfg in target info
1 parent 8cded28 commit 92d99c3

File tree

1 file changed

+55
-13
lines changed

1 file changed

+55
-13
lines changed

src/cargo/core/compiler/build_context/target_info.rs

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::util::context::{GlobalContext, StringList, TargetConfig};
1414
use crate::util::interning::InternedString;
1515
use crate::util::{CargoResult, Rustc};
1616
use anyhow::Context as _;
17-
use cargo_platform::{Cfg, CfgExpr};
17+
use cargo_platform::{Cfg, CfgExpr, CheckCfg};
1818
use cargo_util::{ProcessBuilder, paths};
1919
use serde::{Deserialize, Serialize};
2020
use std::cell::RefCell;
@@ -43,6 +43,8 @@ pub struct TargetInfo {
4343
crate_types: RefCell<HashMap<CrateType, Option<(String, String)>>>,
4444
/// `cfg` information extracted from `rustc --print=cfg`.
4545
cfg: Vec<Cfg>,
46+
/// `check-cfg` informations extracted from `rustc --print=check-cfg`.
47+
check_cfg: Option<CheckCfg>,
4648
/// `supports_std` information extracted from `rustc --print=target-spec-json`
4749
pub supports_std: Option<bool>,
4850
/// Supported values for `-Csplit-debuginfo=` flag, queried from rustc
@@ -208,6 +210,14 @@ impl TargetInfo {
208210
process.arg("--print=crate-name"); // `___` as a delimiter.
209211
process.arg("--print=cfg");
210212

213+
if gctx.cli_unstable().check_target_cfgs {
214+
process.arg("--print=crate-name"); // `___` as a delimiter.
215+
process.arg("--print=check-cfg");
216+
217+
process.arg("--check-cfg=cfg()"); // otherwise `--print=check-cfg` won't output
218+
process.arg("-Zunstable-options"); // required by `--print=check-cfg`
219+
}
220+
211221
// parse_crate_type() relies on "unsupported/unknown crate type" error message,
212222
// so make warnings always emitted as warnings.
213223
process.arg("-Wwarnings");
@@ -261,16 +271,42 @@ impl TargetInfo {
261271
res
262272
};
263273

264-
let cfg = lines
265-
.map(|line| Ok(Cfg::from_str(line)?))
266-
.filter(TargetInfo::not_user_specific_cfg)
267-
.collect::<CargoResult<Vec<_>>>()
268-
.with_context(|| {
269-
format!(
270-
"failed to parse the cfg from `rustc --print=cfg`, got:\n{}",
271-
output
272-
)
273-
})?;
274+
let cfg = {
275+
let mut res = Vec::new();
276+
for line in &mut lines {
277+
// HACK: abuse `--print=crate-name` to use `___` as a delimiter.
278+
if line == "___" {
279+
break;
280+
}
281+
282+
let cfg = Cfg::from_str(line).with_context(|| {
283+
format!(
284+
"failed to parse the cfg from `rustc --print=cfg`, got:\n{}",
285+
output
286+
)
287+
})?;
288+
if TargetInfo::not_user_specific_cfg(&cfg) {
289+
res.push(cfg);
290+
}
291+
}
292+
res
293+
};
294+
295+
let check_cfg = if gctx.cli_unstable().check_target_cfgs {
296+
let mut check_cfg = CheckCfg::default();
297+
check_cfg.exhaustive = true;
298+
299+
for line in lines {
300+
check_cfg
301+
.parse_print_check_cfg_line(line)
302+
.with_context(|| {
303+
format!("unable to parse a line from `--print=check-cfg`")
304+
})?;
305+
}
306+
Some(check_cfg)
307+
} else {
308+
None
309+
};
274310

275311
// recalculate `rustflags` from above now that we have `cfg`
276312
// information
@@ -356,14 +392,15 @@ impl TargetInfo {
356392
)?
357393
.into(),
358394
cfg,
395+
check_cfg,
359396
supports_std,
360397
support_split_debuginfo,
361398
});
362399
}
363400
}
364401

365-
fn not_user_specific_cfg(cfg: &CargoResult<Cfg>) -> bool {
366-
if let Ok(Cfg::Name(cfg_name)) = cfg {
402+
fn not_user_specific_cfg(cfg: &Cfg) -> bool {
403+
if let Cfg::Name(cfg_name) = cfg {
367404
// This should also include "debug_assertions", but it causes
368405
// regressions. Maybe some day in the distant future it can be
369406
// added (and possibly change the warning to an error).
@@ -379,6 +416,11 @@ impl TargetInfo {
379416
&self.cfg
380417
}
381418

419+
/// The [`CheckCfg`] settings.
420+
pub fn check_cfg(&self) -> &Option<CheckCfg> {
421+
&self.check_cfg
422+
}
423+
382424
/// Returns the list of file types generated by the given crate type.
383425
///
384426
/// Returns `None` if the target does not support the given crate type.

0 commit comments

Comments
 (0)