@@ -7,7 +7,7 @@ use arrayvec::ArrayVec;
77use rustc_abi:: { ExternAbi , VariantIdx } ;
88use rustc_ast:: ast:: { LitKind , MetaItemInner , MetaItemKind } ;
99use rustc_attr_parsing:: { AttributeKind , ConstStability , Deprecation , Stability , StableSince } ;
10- use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
10+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap , FxIndexSet } ;
1111use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
1212use rustc_hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE , LocalDefId } ;
1313use rustc_hir:: lang_items:: LangItem ;
@@ -1030,17 +1030,50 @@ impl Default for CfgInfo {
10301030 }
10311031}
10321032
1033- fn handle_auto_cfg_hide_show ( cfg_info : & mut CfgInfo , sub_attr : & MetaItemInner , is_show : bool ) {
1033+ fn show_hide_show_conflict_error (
1034+ tcx : TyCtxt < ' _ > ,
1035+ item_span : rustc_span:: Span ,
1036+ previous : rustc_span:: Span ,
1037+ ) {
1038+ tcx. sess
1039+ . dcx ( )
1040+ . struct_span_err (
1041+ item_span,
1042+ format ! (
1043+ "same `cfg` was in `auto_cfg(hide(...))` and `auto_cfg(show(...))` on the same item"
1044+ ) ,
1045+ )
1046+ . span_note ( previous, "first change was here" ) ;
1047+ }
1048+
1049+ fn handle_auto_cfg_hide_show (
1050+ tcx : TyCtxt < ' _ > ,
1051+ cfg_info : & mut CfgInfo ,
1052+ sub_attr : & MetaItemInner ,
1053+ is_show : bool ,
1054+ new_show_attrs : & mut FxHashMap < ( Symbol , Option < Symbol > ) , rustc_span:: Span > ,
1055+ new_hide_attrs : & mut FxHashMap < ( Symbol , Option < Symbol > ) , rustc_span:: Span > ,
1056+ ) {
10341057 if let MetaItemInner :: MetaItem ( item) = sub_attr
10351058 && let MetaItemKind :: List ( items) = & item. kind
10361059 {
10371060 for item in items {
1038- // Errors should already have been reported in `rustc_passes::check_attr`.
1039- if let Ok ( cfg ) = Cfg :: parse ( item) {
1061+ // Cfg parsing errors should already have been reported in `rustc_passes::check_attr`.
1062+ if let Ok ( Cfg :: Cfg ( key , value ) ) = Cfg :: parse ( item) {
10401063 if is_show {
1041- cfg_info. hidden_cfg . remove ( & cfg) ;
1064+ if let Some ( span) = new_hide_attrs. get ( & ( key, value) ) {
1065+ show_hide_show_conflict_error ( tcx, item. span ( ) , * span) ;
1066+ } else {
1067+ new_hide_attrs. insert ( ( key, value) , item. span ( ) ) ;
1068+ }
1069+ cfg_info. hidden_cfg . remove ( & Cfg :: Cfg ( key, value) ) ;
10421070 } else {
1043- cfg_info. hidden_cfg . insert ( cfg) ;
1071+ if let Some ( span) = new_show_attrs. get ( & ( key, value) ) {
1072+ show_hide_show_conflict_error ( tcx, item. span ( ) , * span) ;
1073+ } else {
1074+ new_show_attrs. insert ( ( key, value) , item. span ( ) ) ;
1075+ }
1076+ cfg_info. hidden_cfg . insert ( Cfg :: Cfg ( key, value) ) ;
10441077 }
10451078 }
10461079 }
@@ -1061,6 +1094,8 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
10611094 Some ( item)
10621095 }
10631096
1097+ let mut new_show_attrs = FxHashMap :: default ( ) ;
1098+ let mut new_hide_attrs = FxHashMap :: default ( ) ;
10641099 let mut enable_auto_cfg = true ;
10651100 let mut cfg = Cfg :: True ;
10661101
@@ -1172,9 +1207,12 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
11721207 && ( ident. name == sym:: show || ident. name == sym:: hide)
11731208 {
11741209 handle_auto_cfg_hide_show (
1210+ tcx,
11751211 cfg_info,
11761212 & sub_attr,
11771213 ident. name == sym:: show,
1214+ & mut new_show_attrs,
1215+ & mut new_hide_attrs,
11781216 ) ;
11791217 }
11801218 }
0 commit comments