3737
3838use std:: collections:: { HashMap , HashSet } ;
3939use std:: hash:: { Hash , Hasher } ;
40+ use std:: path:: Path ;
41+ use std:: str:: FromStr ;
4042use std:: sync:: Arc ;
4143
44+ use crate :: core:: compiler:: build_context:: { CheckCfg , ExpectedValues } ;
4245use crate :: core:: compiler:: unit_dependencies:: build_unit_dependencies;
4346use crate :: core:: compiler:: unit_graph:: { self , UnitDep , UnitGraph } ;
4447use crate :: core:: compiler:: { standard_lib, CrateType , TargetInfo } ;
@@ -57,6 +60,7 @@ use crate::util::interning::InternedString;
5760use crate :: util:: { CargoResult , StableHasher } ;
5861
5962mod compile_filter;
63+ use cargo_platform:: { Cfg , CfgExpr , Platform } ;
6064pub use compile_filter:: { CompileFilter , FilterRule , LibRule } ;
6165
6266mod unit_generator;
@@ -476,6 +480,49 @@ pub fn create_bcx<'a, 'gctx>(
476480 . extend ( args) ;
477481 }
478482
483+ {
484+ let check_cfg = target_data. check_cfg ( ) ;
485+
486+ if check_cfg. exhaustive {
487+ let target_cfgs = gctx. target_cfgs ( ) ?;
488+ for ( key, _fields) in target_cfgs {
489+ if !key. starts_with ( "cfg(" ) || !key. ends_with ( ')' ) {
490+ continue ;
491+ }
492+
493+ let cfg_expr = & key[ 4 ..key. len ( ) - 1 ] ;
494+ let Ok ( cfg_expr) = CfgExpr :: from_str ( cfg_expr) else {
495+ continue ;
496+ } ;
497+
498+ warn_on_unexpected_cfgs ( gctx, check_cfg, & cfg_expr, None , "" ) ?;
499+ }
500+
501+ for unit in & units {
502+ if !unit. show_warnings ( gctx) {
503+ continue ;
504+ }
505+
506+ for dep in unit. pkg . summary ( ) . dependencies ( ) {
507+ let Some ( platform) = dep. platform ( ) else {
508+ continue ;
509+ } ;
510+ let Platform :: Cfg ( cfg_expr) = platform else {
511+ continue ;
512+ } ;
513+
514+ warn_on_unexpected_cfgs (
515+ gctx,
516+ check_cfg,
517+ cfg_expr,
518+ Some ( unit. pkg . manifest_path ( ) ) ,
519+ ".dependencies" ,
520+ ) ?;
521+ }
522+ }
523+ }
524+ }
525+
479526 if honor_rust_version. unwrap_or ( true ) {
480527 let rustc_version = target_data. rustc . version . clone ( ) . into ( ) ;
481528
@@ -542,6 +589,52 @@ where `<compatible-ver>` is the latest version supporting rustc {rustc_version}"
542589 Ok ( bcx)
543590}
544591
592+ fn warn_on_unexpected_cfgs (
593+ gctx : & GlobalContext ,
594+ check_cfg : & CheckCfg ,
595+ cfg_expr : & CfgExpr ,
596+ path : Option < & Path > ,
597+ suffix : & str ,
598+ ) -> CargoResult < ( ) > {
599+ let prefix = if let Some ( path) = path {
600+ format ! ( "{path}: " , path = path. display( ) )
601+ } else {
602+ "" . to_string ( )
603+ } ;
604+
605+ cfg_expr. fold ( & |cfg| -> CargoResult < ( ) > {
606+ let ( name, value) = match cfg {
607+ Cfg :: Name ( name) => ( name, None ) ,
608+ Cfg :: KeyPair ( name, value) => ( name, Some ( value. to_string ( ) ) ) ,
609+ } ;
610+
611+ match check_cfg. expecteds . get ( name) {
612+ Some ( ExpectedValues :: Some ( values) ) if !values. contains ( & value) => {
613+ let value = if let Some ( ref value) = value {
614+ value
615+ } else {
616+ "(none)"
617+ } ;
618+ gctx. shell ( ) . warn ( format ! (
619+ "{prefix}unexpected `cfg` condition value: `{value}` for `{cfg}` in `[target.'cfg({cfg_expr})'{suffix}]`"
620+ ) ) ?;
621+ }
622+ None => {
623+ gctx. shell ( ) . warn ( format ! (
624+ "{prefix}unexpected `cfg` condition name: `{name}`{cfg} in `[target.'cfg({cfg_expr})'{suffix}]`" ,
625+ cfg = if value. is_some( ) {
626+ format!( " for `{cfg}`" )
627+ } else {
628+ format!( "" )
629+ }
630+ ) ) ?;
631+ }
632+ _ => { /* not unexpected */ }
633+ }
634+ Ok ( ( ) )
635+ } )
636+ }
637+
545638/// This is used to rebuild the unit graph, sharing host dependencies if possible,
546639/// and applying other unit adjustments based on the whole graph.
547640///
0 commit comments