@@ -479,7 +479,7 @@ impl Item {
479479 name,
480480 kind,
481481 Attributes :: from_hir ( hir_attrs) ,
482- hir_attrs . cfg ( cx. tcx , & cx. cache . hidden_cfg ) ,
482+ extract_cfg_from_attrs ( hir_attrs , cx. tcx , & cx. cache . hidden_cfg ) ,
483483 )
484484 }
485485
@@ -990,95 +990,98 @@ pub(crate) trait AttributesExt {
990990 fn lists ( & self , name : Symbol ) -> Self :: AttributeIterator < ' _ > ;
991991
992992 fn iter ( & self ) -> Self :: Attributes < ' _ > ;
993+ }
993994
994- fn cfg ( & self , tcx : TyCtxt < ' _ > , hidden_cfg : & FxHashSet < Cfg > ) -> Option < Arc < Cfg > > {
995- let sess = tcx. sess ;
996- let doc_cfg_active = tcx. features ( ) . doc_cfg ( ) ;
997- let doc_auto_cfg_active = tcx. features ( ) . doc_auto_cfg ( ) ;
998-
999- fn single < T : IntoIterator > ( it : T ) -> Option < T :: Item > {
1000- let mut iter = it. into_iter ( ) ;
1001- let item = iter. next ( ) ?;
1002- if iter. next ( ) . is_some ( ) {
1003- return None ;
1004- }
1005- Some ( item)
995+ pub fn extract_cfg_from_attrs < A : AttributesExt + ?Sized > (
996+ attrs : & A ,
997+ tcx : TyCtxt < ' _ > ,
998+ hidden_cfg : & FxHashSet < Cfg > ,
999+ ) -> Option < Arc < Cfg > > {
1000+ let sess = tcx. sess ;
1001+ let doc_cfg_active = tcx. features ( ) . doc_cfg ( ) ;
1002+ let doc_auto_cfg_active = tcx. features ( ) . doc_auto_cfg ( ) ;
1003+
1004+ fn single < T : IntoIterator > ( it : T ) -> Option < T :: Item > {
1005+ let mut iter = it. into_iter ( ) ;
1006+ let item = iter. next ( ) ?;
1007+ if iter. next ( ) . is_some ( ) {
1008+ return None ;
10061009 }
1010+ Some ( item)
1011+ }
10071012
1008- let mut cfg = if doc_cfg_active || doc_auto_cfg_active {
1009- let mut doc_cfg = self
1013+ let mut cfg = if doc_cfg_active || doc_auto_cfg_active {
1014+ let mut doc_cfg = attrs
1015+ . iter ( )
1016+ . filter ( |attr| attr. has_name ( sym:: doc) )
1017+ . flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) )
1018+ . filter ( |attr| attr. has_name ( sym:: cfg) )
1019+ . peekable ( ) ;
1020+ if doc_cfg. peek ( ) . is_some ( ) && doc_cfg_active {
1021+ doc_cfg
1022+ . filter_map ( |attr| Cfg :: parse ( & attr) . ok ( ) )
1023+ . fold ( Cfg :: True , |cfg, new_cfg| cfg & new_cfg)
1024+ } else if doc_auto_cfg_active {
1025+ // If there is no `doc(cfg())`, then we retrieve the `cfg()` attributes (because
1026+ // `doc(cfg())` overrides `cfg()`).
1027+ attrs
10101028 . iter ( )
1011- . filter ( |attr| attr. has_name ( sym:: doc) )
1012- . flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) )
10131029 . filter ( |attr| attr. has_name ( sym:: cfg) )
1014- . peekable ( ) ;
1015- if doc_cfg. peek ( ) . is_some ( ) && doc_cfg_active {
1016- doc_cfg
1017- . filter_map ( |attr| Cfg :: parse ( & attr) . ok ( ) )
1018- . fold ( Cfg :: True , |cfg, new_cfg| cfg & new_cfg)
1019- } else if doc_auto_cfg_active {
1020- // If there is no `doc(cfg())`, then we retrieve the `cfg()` attributes (because
1021- // `doc(cfg())` overrides `cfg()`).
1022- self . iter ( )
1023- . filter ( |attr| attr. has_name ( sym:: cfg) )
1024- . filter_map ( |attr| single ( attr. meta_item_list ( ) ?) )
1025- . filter_map ( |attr| {
1026- Cfg :: parse_without ( attr. meta_item ( ) ?, hidden_cfg) . ok ( ) . flatten ( )
1027- } )
1028- . fold ( Cfg :: True , |cfg, new_cfg| cfg & new_cfg)
1029- } else {
1030- Cfg :: True
1031- }
1030+ . filter_map ( |attr| single ( attr. meta_item_list ( ) ?) )
1031+ . filter_map ( |attr| Cfg :: parse_without ( attr. meta_item ( ) ?, hidden_cfg) . ok ( ) . flatten ( ) )
1032+ . fold ( Cfg :: True , |cfg, new_cfg| cfg & new_cfg)
10321033 } else {
10331034 Cfg :: True
1034- } ;
1035-
1036- for attr in self . iter ( ) {
1037- // #[doc]
1038- if attr. doc_str ( ) . is_none ( ) && attr. has_name ( sym:: doc) {
1039- // #[doc(...)]
1040- if let Some ( list) = attr. meta_item_list ( ) {
1041- for item in list {
1042- // #[doc(hidden)]
1043- if !item. has_name ( sym:: cfg) {
1044- continue ;
1045- }
1046- // #[doc(cfg(...))]
1047- if let Some ( cfg_mi) = item
1048- . meta_item ( )
1049- . and_then ( |item| rustc_expand:: config:: parse_cfg ( item, sess) )
1050- {
1051- match Cfg :: parse ( cfg_mi) {
1052- Ok ( new_cfg) => cfg &= new_cfg,
1053- Err ( e) => {
1054- sess. dcx ( ) . span_err ( e. span , e. msg ) ;
1055- }
1035+ }
1036+ } else {
1037+ Cfg :: True
1038+ } ;
1039+
1040+ for attr in attrs. iter ( ) {
1041+ // #[doc]
1042+ if attr. doc_str ( ) . is_none ( ) && attr. has_name ( sym:: doc) {
1043+ // #[doc(...)]
1044+ if let Some ( list) = attr. meta_item_list ( ) {
1045+ for item in list {
1046+ // #[doc(hidden)]
1047+ if !item. has_name ( sym:: cfg) {
1048+ continue ;
1049+ }
1050+ // #[doc(cfg(...))]
1051+ if let Some ( cfg_mi) = item
1052+ . meta_item ( )
1053+ . and_then ( |item| rustc_expand:: config:: parse_cfg ( item, sess) )
1054+ {
1055+ match Cfg :: parse ( cfg_mi) {
1056+ Ok ( new_cfg) => cfg &= new_cfg,
1057+ Err ( e) => {
1058+ sess. dcx ( ) . span_err ( e. span , e. msg ) ;
10561059 }
10571060 }
10581061 }
10591062 }
10601063 }
10611064 }
1065+ }
10621066
1063- // treat #[target_feature(enable = "feat")] attributes as if they were
1064- // #[doc(cfg(target_feature = "feat"))] attributes as well
1065- for attr in self . lists ( sym:: target_feature) {
1066- if attr. has_name ( sym:: enable) {
1067- if attr. value_str ( ) . is_some ( ) {
1068- // Clone `enable = "feat"`, change to `target_feature = "feat"`.
1069- // Unwrap is safe because `value_str` succeeded above.
1070- let mut meta = attr. meta_item ( ) . unwrap ( ) . clone ( ) ;
1071- meta. path = ast:: Path :: from_ident ( Ident :: with_dummy_span ( sym:: target_feature) ) ;
1072-
1073- if let Ok ( feat_cfg) = Cfg :: parse ( & ast:: MetaItemInner :: MetaItem ( meta) ) {
1074- cfg &= feat_cfg;
1075- }
1067+ // treat #[target_feature(enable = "feat")] attributes as if they were
1068+ // #[doc(cfg(target_feature = "feat"))] attributes as well
1069+ for attr in attrs. lists ( sym:: target_feature) {
1070+ if attr. has_name ( sym:: enable) {
1071+ if attr. value_str ( ) . is_some ( ) {
1072+ // Clone `enable = "feat"`, change to `target_feature = "feat"`.
1073+ // Unwrap is safe because `value_str` succeeded above.
1074+ let mut meta = attr. meta_item ( ) . unwrap ( ) . clone ( ) ;
1075+ meta. path = ast:: Path :: from_ident ( Ident :: with_dummy_span ( sym:: target_feature) ) ;
1076+
1077+ if let Ok ( feat_cfg) = Cfg :: parse ( & ast:: MetaItemInner :: MetaItem ( meta) ) {
1078+ cfg &= feat_cfg;
10761079 }
10771080 }
10781081 }
1079-
1080- if cfg == Cfg :: True { None } else { Some ( Arc :: new ( cfg) ) }
10811082 }
1083+
1084+ if cfg == Cfg :: True { None } else { Some ( Arc :: new ( cfg) ) }
10821085}
10831086
10841087impl AttributesExt for [ hir:: Attribute ] {
0 commit comments