@@ -479,7 +479,7 @@ impl Item {
479
479
name,
480
480
kind,
481
481
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 ) ,
483
483
)
484
484
}
485
485
@@ -990,95 +990,98 @@ pub(crate) trait AttributesExt {
990
990
fn lists ( & self , name : Symbol ) -> Self :: AttributeIterator < ' _ > ;
991
991
992
992
fn iter ( & self ) -> Self :: Attributes < ' _ > ;
993
+ }
993
994
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 ;
1006
1009
}
1010
+ Some ( item)
1011
+ }
1007
1012
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
1010
1028
. iter ( )
1011
- . filter ( |attr| attr. has_name ( sym:: doc) )
1012
- . flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) )
1013
1029
. 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)
1032
1033
} else {
1033
1034
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 ) ;
1056
1059
}
1057
1060
}
1058
1061
}
1059
1062
}
1060
1063
}
1061
1064
}
1065
+ }
1062
1066
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;
1076
1079
}
1077
1080
}
1078
1081
}
1079
-
1080
- if cfg == Cfg :: True { None } else { Some ( Arc :: new ( cfg) ) }
1081
1082
}
1083
+
1084
+ if cfg == Cfg :: True { None } else { Some ( Arc :: new ( cfg) ) }
1082
1085
}
1083
1086
1084
1087
impl AttributesExt for [ hir:: Attribute ] {
0 commit comments