@@ -14,7 +14,7 @@ use crate::util::context::{GlobalContext, StringList, TargetConfig};
1414use crate :: util:: interning:: InternedString ;
1515use crate :: util:: { CargoResult , Rustc } ;
1616use anyhow:: Context as _;
17- use cargo_platform:: { Cfg , CfgExpr } ;
17+ use cargo_platform:: { Cfg , CfgExpr , CheckCfg } ;
1818use cargo_util:: { paths, ProcessBuilder } ;
1919use serde:: { Deserialize , Serialize } ;
2020use 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" ) ;
@@ -264,6 +274,11 @@ impl TargetInfo {
264274 let cfg = {
265275 let mut res = Vec :: new ( ) ;
266276 for line in & mut lines {
277+ // HACK: abuse `--print=crate-name` to use `___` as a delimiter.
278+ if line == "___" {
279+ break ;
280+ }
281+
267282 let cfg = Cfg :: from_str ( line) . with_context ( || {
268283 format ! (
269284 "failed to parse the cfg from `rustc --print=cfg`, got:\n {}" ,
@@ -277,6 +292,22 @@ impl TargetInfo {
277292 res
278293 } ;
279294
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+ } ;
310+
280311 // recalculate `rustflags` from above now that we have `cfg`
281312 // information
282313 let new_flags = extra_args (
@@ -361,6 +392,7 @@ impl TargetInfo {
361392 ) ?
362393 . into ( ) ,
363394 cfg,
395+ check_cfg,
364396 supports_std,
365397 support_split_debuginfo,
366398 } ) ;
@@ -384,6 +416,11 @@ impl TargetInfo {
384416 & self . cfg
385417 }
386418
419+ /// The [`CheckCfg`] settings.
420+ pub fn check_cfg ( & self ) -> & Option < CheckCfg > {
421+ & self . check_cfg
422+ }
423+
387424 /// Returns the list of file types generated by the given crate type.
388425 ///
389426 /// Returns `None` if the target does not support the given crate type.
0 commit comments