@@ -811,29 +811,6 @@ pub struct RenderedLink {
811811}
812812
813813impl Attributes {
814- /// Extracts the content from an attribute `#[doc(cfg(content))]`.
815- crate fn extract_cfg ( mi : & ast:: MetaItem ) -> Option < & ast:: MetaItem > {
816- use rustc_ast:: NestedMetaItem :: MetaItem ;
817-
818- if let ast:: MetaItemKind :: List ( ref nmis) = mi. kind {
819- if nmis. len ( ) == 1 {
820- if let MetaItem ( ref cfg_mi) = nmis[ 0 ] {
821- if cfg_mi. has_name ( sym:: cfg) {
822- if let ast:: MetaItemKind :: List ( ref cfg_nmis) = cfg_mi. kind {
823- if cfg_nmis. len ( ) == 1 {
824- if let MetaItem ( ref content_mi) = cfg_nmis[ 0 ] {
825- return Some ( content_mi) ;
826- }
827- }
828- }
829- }
830- }
831- }
832- }
833-
834- None
835- }
836-
837814 /// Reads a `MetaItem` from within an attribute, looks for whether it is a
838815 /// `#[doc(include="file")]`, and returns the filename and contents of the file as loaded from
839816 /// its expansion.
@@ -893,10 +870,10 @@ impl Attributes {
893870 diagnostic : & :: rustc_errors:: Handler ,
894871 attrs : & [ ast:: Attribute ] ,
895872 additional_attrs : Option < ( & [ ast:: Attribute ] , DefId ) > ,
873+ doc_cfg_active : bool ,
896874 ) -> Attributes {
897875 let mut doc_strings: Vec < DocFragment > = vec ! [ ] ;
898876 let mut sp = None ;
899- let mut cfg = Cfg :: True ;
900877 let mut doc_line = 0 ;
901878
902879 fn update_need_backline ( doc_strings : & mut Vec < DocFragment > , frag : & DocFragment ) {
@@ -943,36 +920,27 @@ impl Attributes {
943920 if sp. is_none ( ) {
944921 sp = Some ( attr. span ) ;
945922 }
946- None
947- } else {
948- if attr. has_name ( sym:: doc) {
949- if let Some ( mi) = attr. meta ( ) {
950- if let Some ( cfg_mi) = Attributes :: extract_cfg ( & mi) {
951- // Extracted #[doc(cfg(...))]
952- match Cfg :: parse ( cfg_mi) {
953- Ok ( new_cfg) => cfg &= new_cfg,
954- Err ( e) => diagnostic. span_err ( e. span , e. msg ) ,
955- }
956- } else if let Some ( ( filename, contents) ) = Attributes :: extract_include ( & mi)
957- {
958- let line = doc_line;
959- doc_line += contents. as_str ( ) . lines ( ) . count ( ) ;
960- let frag = DocFragment {
961- line,
962- span : attr. span ,
963- doc : contents,
964- kind : DocFragmentKind :: Include { filename } ,
965- parent_module,
966- need_backline : false ,
967- indent : 0 ,
968- } ;
969- update_need_backline ( & mut doc_strings, & frag) ;
970- doc_strings. push ( frag) ;
971- }
923+ return None ;
924+ } else if attr. has_name ( sym:: doc) {
925+ if let Some ( mi) = attr. meta ( ) {
926+ if let Some ( ( filename, contents) ) = Attributes :: extract_include ( & mi) {
927+ let line = doc_line;
928+ doc_line += contents. as_str ( ) . lines ( ) . count ( ) ;
929+ let frag = DocFragment {
930+ line,
931+ span : attr. span ,
932+ doc : contents,
933+ kind : DocFragmentKind :: Include { filename } ,
934+ parent_module,
935+ need_backline : false ,
936+ indent : 0 ,
937+ } ;
938+ update_need_backline ( & mut doc_strings, & frag) ;
939+ doc_strings. push ( frag) ;
972940 }
973941 }
974- Some ( attr. clone ( ) )
975942 }
943+ Some ( attr. clone ( ) )
976944 } ;
977945
978946 // Additional documentation should be shown before the original documentation
@@ -984,6 +952,49 @@ impl Attributes {
984952 . filter_map ( clean_attr)
985953 . collect ( ) ;
986954
955+ trait SingleExt {
956+ type Item ;
957+ fn single ( self ) -> Option < Self :: Item > ;
958+ }
959+
960+ impl < T : IntoIterator > SingleExt for T {
961+ type Item = T :: Item ;
962+ fn single ( self ) -> Option < Self :: Item > {
963+ let mut iter = self . into_iter ( ) ;
964+ let item = iter. next ( ) ?;
965+ iter. next ( ) . is_none ( ) . then_some ( ( ) ) ?;
966+ Some ( item)
967+ }
968+ }
969+
970+ let mut cfg = if doc_cfg_active {
971+ let mut doc_cfg = attrs
972+ . iter ( )
973+ . filter ( |attr| attr. has_name ( sym:: doc) )
974+ . filter_map ( |attr| Some ( attr. meta_item_list ( ) ?. single ( ) ?) )
975+ . filter ( |attr| attr. has_name ( sym:: cfg) )
976+ . filter_map ( |attr| Some ( attr. meta_item_list ( ) ?. single ( ) ?. meta_item ( ) ?. clone ( ) ) )
977+ . peekable ( ) ;
978+ if doc_cfg. peek ( ) . is_some ( ) {
979+ doc_cfg
980+ . filter_map ( |attr| {
981+ Cfg :: parse ( & attr) . map_err ( |e| diagnostic. span_err ( e. span , e. msg ) ) . ok ( )
982+ } )
983+ . fold ( Cfg :: True , |cfg, new_cfg| cfg & new_cfg)
984+ } else {
985+ attrs
986+ . iter ( )
987+ . filter ( |attr| attr. has_name ( sym:: cfg) )
988+ . filter_map ( |attr| Some ( attr. meta_item_list ( ) ?. single ( ) ?. meta_item ( ) ?. clone ( ) ) )
989+ . filter_map ( |attr| {
990+ Cfg :: parse ( & attr) . map_err ( |e| diagnostic. span_err ( e. span , e. msg ) ) . ok ( )
991+ } )
992+ . fold ( Cfg :: True , |cfg, new_cfg| cfg & new_cfg)
993+ }
994+ } else {
995+ Cfg :: True
996+ } ;
997+
987998 // treat #[target_feature(enable = "feat")] attributes as if they were
988999 // #[doc(cfg(target_feature = "feat"))] attributes as well
9891000 for attr in attrs. lists ( sym:: target_feature) {
0 commit comments