@@ -970,8 +970,10 @@ fn show_hide_show_conflict_error(
970970 diag. emit ( ) ;
971971}
972972
973- /// This function checks if a same `cfg` is present in both `auto_cfg(hide(...))` and
974- /// `auto_cfg(show(...))` on the same item. If so, it emits an error.
973+ /// This functions updates the `hidden_cfg` field of the provided `cfg_info` argument.
974+ ///
975+ /// It also checks if a same `cfg` is present in both `auto_cfg(hide(...))` and
976+ /// `auto_cfg(show(...))` on the same item and emits an error if it's the case.
975977///
976978/// Because we go through a list of `cfg`s, we keep track of the `cfg`s we saw in `new_show_attrs`
977979/// and in `new_hide_attrs` arguments.
@@ -1023,6 +1025,31 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
10231025 Some ( item)
10241026 }
10251027
1028+ fn check_changed_auto_active_status (
1029+ changed_auto_active_status : & mut Option < rustc_span:: Span > ,
1030+ attr : & ast:: MetaItem ,
1031+ cfg_info : & mut CfgInfo ,
1032+ tcx : TyCtxt < ' _ > ,
1033+ new_value : bool ,
1034+ ) -> bool {
1035+ if let Some ( first_change) = changed_auto_active_status {
1036+ if cfg_info. auto_cfg_active != new_value {
1037+ tcx. sess
1038+ . dcx ( )
1039+ . struct_span_err (
1040+ vec ! [ * first_change, attr. span] ,
1041+ "`auto_cfg` was disabled and enabled more than once on the same item" ,
1042+ )
1043+ . emit ( ) ;
1044+ return true ;
1045+ }
1046+ } else {
1047+ * changed_auto_active_status = Some ( attr. span ) ;
1048+ }
1049+ cfg_info. auto_cfg_active = new_value;
1050+ false
1051+ }
1052+
10261053 let mut new_show_attrs = FxHashMap :: default ( ) ;
10271054 let mut new_hide_attrs = FxHashMap :: default ( ) ;
10281055
@@ -1070,49 +1097,39 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
10701097 } ;
10711098 match & attr. kind {
10721099 MetaItemKind :: Word => {
1073- if let Some ( first_change) = changed_auto_active_status {
1074- if !cfg_info. auto_cfg_active {
1075- tcx. sess . dcx ( ) . struct_span_err (
1076- vec ! [ first_change, attr. span] ,
1077- "`auto_cfg` was disabled and enabled more than once on the same item" ,
1078- ) . emit ( ) ;
1079- return None ;
1080- }
1081- } else {
1082- changed_auto_active_status = Some ( attr. span ) ;
1100+ if check_changed_auto_active_status (
1101+ & mut changed_auto_active_status,
1102+ attr,
1103+ cfg_info,
1104+ tcx,
1105+ true ,
1106+ ) {
1107+ return None ;
10831108 }
1084- cfg_info. auto_cfg_active = true ;
10851109 }
10861110 MetaItemKind :: NameValue ( lit) => {
10871111 if let LitKind :: Bool ( value) = lit. kind {
1088- if let Some ( first_change) = changed_auto_active_status {
1089- if cfg_info. auto_cfg_active != value {
1090- tcx. sess . dcx ( ) . struct_span_err (
1091- vec ! [ first_change, attr. span] ,
1092- "`auto_cfg` was disabled and enabled more than once on the same item" ,
1093- ) . emit ( ) ;
1094- return None ;
1095- }
1096- } else {
1097- changed_auto_active_status = Some ( attr. span ) ;
1112+ if check_changed_auto_active_status (
1113+ & mut changed_auto_active_status,
1114+ attr,
1115+ cfg_info,
1116+ tcx,
1117+ value,
1118+ ) {
1119+ return None ;
10981120 }
1099- cfg_info. auto_cfg_active = value;
11001121 }
11011122 }
11021123 MetaItemKind :: List ( sub_attrs) => {
1103- if let Some ( first_change) = changed_auto_active_status {
1104- if !cfg_info. auto_cfg_active {
1105- tcx. sess . dcx ( ) . struct_span_err (
1106- vec ! [ first_change, attr. span] ,
1107- "`auto_cfg` was disabled and enabled more than once on the same item" ,
1108- ) . emit ( ) ;
1109- return None ;
1110- }
1111- } else {
1112- changed_auto_active_status = Some ( attr. span ) ;
1124+ if check_changed_auto_active_status (
1125+ & mut changed_auto_active_status,
1126+ attr,
1127+ cfg_info,
1128+ tcx,
1129+ true ,
1130+ ) {
1131+ return None ;
11131132 }
1114- // Whatever happens next, the feature is enabled again.
1115- cfg_info. auto_cfg_active = true ;
11161133 for sub_attr in sub_attrs. iter ( ) {
11171134 if let Some ( ident) = sub_attr. ident ( )
11181135 && ( ident. name == sym:: show || ident. name == sym:: hide)
0 commit comments