@@ -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
@@ -206,6 +208,14 @@ impl TargetInfo {
206208 process. arg ( "--print=crate-name" ) ; // `___` as a delimiter.
207209 process. arg ( "--print=cfg" ) ;
208210
211+ if gctx. cli_unstable ( ) . check_target_cfgs {
212+ process. arg ( "--print=crate-name" ) ; // `___` as a delimiter.
213+ process. arg ( "--print=check-cfg" ) ;
214+
215+ process. arg ( "--check-cfg=cfg()" ) ; // otherwise `--print=check-cfg` won't output
216+ process. arg ( "-Zunstable-options" ) ; // required by `--print=check-cfg`
217+ }
218+
209219 let ( output, error) = rustc
210220 . cached_output ( & process, extra_fingerprint)
211221 . with_context ( || {
@@ -258,6 +268,11 @@ impl TargetInfo {
258268 let cfg = {
259269 let mut res = Vec :: new ( ) ;
260270 for line in & mut lines {
271+ // HACK: abuse `--print=crate-name` to use `___` as a delimiter.
272+ if line == "___" {
273+ break ;
274+ }
275+
261276 let cfg = Cfg :: from_str ( line) . with_context ( || {
262277 format ! (
263278 "failed to parse the cfg from `rustc --print=cfg`, got:\n {}" ,
@@ -271,6 +286,22 @@ impl TargetInfo {
271286 res
272287 } ;
273288
289+ let check_cfg = if gctx. cli_unstable ( ) . check_target_cfgs {
290+ let mut check_cfg = CheckCfg :: default ( ) ;
291+ check_cfg. exhaustive = true ;
292+
293+ for line in lines {
294+ check_cfg
295+ . parse_print_check_cfg_line ( line)
296+ . with_context ( || {
297+ format ! ( "unable to parse a line from `--print=check-cfg`" )
298+ } ) ?;
299+ }
300+ Some ( check_cfg)
301+ } else {
302+ None
303+ } ;
304+
274305 // recalculate `rustflags` from above now that we have `cfg`
275306 // information
276307 let new_flags = extra_args (
@@ -355,6 +386,7 @@ impl TargetInfo {
355386 ) ?
356387 . into ( ) ,
357388 cfg,
389+ check_cfg,
358390 supports_std,
359391 support_split_debuginfo,
360392 } ) ;
@@ -378,6 +410,11 @@ impl TargetInfo {
378410 & self . cfg
379411 }
380412
413+ /// The [`CheckCfg`] settings.
414+ pub fn check_cfg ( & self ) -> & Option < CheckCfg > {
415+ & self . check_cfg
416+ }
417+
381418 /// Returns the list of file types generated by the given crate type.
382419 ///
383420 /// Returns `None` if the target does not support the given crate type.
0 commit comments