@@ -7,7 +7,7 @@ use arrayvec::ArrayVec;
7
7
use rustc_abi:: { ExternAbi , VariantIdx } ;
8
8
use rustc_ast:: ast:: { LitKind , MetaItemInner , MetaItemKind } ;
9
9
use 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 } ;
11
11
use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
12
12
use rustc_hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE , LocalDefId } ;
13
13
use rustc_hir:: lang_items:: LangItem ;
@@ -1030,17 +1030,50 @@ impl Default for CfgInfo {
1030
1030
}
1031
1031
}
1032
1032
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
+ ) {
1034
1057
if let MetaItemInner :: MetaItem ( item) = sub_attr
1035
1058
&& let MetaItemKind :: List ( items) = & item. kind
1036
1059
{
1037
1060
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) {
1040
1063
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) ) ;
1042
1070
} 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) ) ;
1044
1077
}
1045
1078
}
1046
1079
}
@@ -1061,6 +1094,8 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
1061
1094
Some ( item)
1062
1095
}
1063
1096
1097
+ let mut new_show_attrs = FxHashMap :: default ( ) ;
1098
+ let mut new_hide_attrs = FxHashMap :: default ( ) ;
1064
1099
let mut enable_auto_cfg = true ;
1065
1100
let mut cfg = Cfg :: True ;
1066
1101
@@ -1172,9 +1207,12 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
1172
1207
&& ( ident. name == sym:: show || ident. name == sym:: hide)
1173
1208
{
1174
1209
handle_auto_cfg_hide_show (
1210
+ tcx,
1175
1211
cfg_info,
1176
1212
& sub_attr,
1177
1213
ident. name == sym:: show,
1214
+ & mut new_show_attrs,
1215
+ & mut new_hide_attrs,
1178
1216
) ;
1179
1217
}
1180
1218
}
0 commit comments