@@ -14,7 +14,7 @@ use crate::util::context::{GlobalContext, StringList, TargetConfig};
14
14
use crate :: util:: interning:: InternedString ;
15
15
use crate :: util:: { CargoResult , Rustc } ;
16
16
use anyhow:: Context as _;
17
- use cargo_platform:: { Cfg , CfgExpr } ;
17
+ use cargo_platform:: { Cfg , CfgExpr , CheckCfg } ;
18
18
use cargo_util:: { ProcessBuilder , paths} ;
19
19
use serde:: { Deserialize , Serialize } ;
20
20
use std:: cell:: RefCell ;
@@ -43,6 +43,8 @@ pub struct TargetInfo {
43
43
crate_types : RefCell < HashMap < CrateType , Option < ( String , String ) > > > ,
44
44
/// `cfg` information extracted from `rustc --print=cfg`.
45
45
cfg : Vec < Cfg > ,
46
+ /// `check-cfg` informations extracted from `rustc --print=check-cfg`.
47
+ check_cfg : Option < CheckCfg > ,
46
48
/// `supports_std` information extracted from `rustc --print=target-spec-json`
47
49
pub supports_std : Option < bool > ,
48
50
/// Supported values for `-Csplit-debuginfo=` flag, queried from rustc
@@ -208,6 +210,14 @@ impl TargetInfo {
208
210
process. arg ( "--print=crate-name" ) ; // `___` as a delimiter.
209
211
process. arg ( "--print=cfg" ) ;
210
212
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
+
211
221
// parse_crate_type() relies on "unsupported/unknown crate type" error message,
212
222
// so make warnings always emitted as warnings.
213
223
process. arg ( "-Wwarnings" ) ;
@@ -261,16 +271,42 @@ impl TargetInfo {
261
271
res
262
272
} ;
263
273
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
+ } ;
274
310
275
311
// recalculate `rustflags` from above now that we have `cfg`
276
312
// information
@@ -356,14 +392,15 @@ impl TargetInfo {
356
392
) ?
357
393
. into ( ) ,
358
394
cfg,
395
+ check_cfg,
359
396
supports_std,
360
397
support_split_debuginfo,
361
398
} ) ;
362
399
}
363
400
}
364
401
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 {
367
404
// This should also include "debug_assertions", but it causes
368
405
// regressions. Maybe some day in the distant future it can be
369
406
// added (and possibly change the warning to an error).
@@ -379,6 +416,11 @@ impl TargetInfo {
379
416
& self . cfg
380
417
}
381
418
419
+ /// The [`CheckCfg`] settings.
420
+ pub fn check_cfg ( & self ) -> & Option < CheckCfg > {
421
+ & self . check_cfg
422
+ }
423
+
382
424
/// Returns the list of file types generated by the given crate type.
383
425
///
384
426
/// Returns `None` if the target does not support the given crate type.
0 commit comments