@@ -10,13 +10,13 @@ use itertools::Either;
1010use rustc_ast:: { LitKind , MetaItem , MetaItemInner , MetaItemKind , MetaItemLit } ;
1111use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1212use rustc_data_structures:: thin_vec:: { ThinVec , thin_vec} ;
13+ use rustc_hir as hir;
1314use rustc_hir:: Attribute ;
14- use rustc_hir:: attrs:: { AttributeKind , CfgEntry } ;
15+ use rustc_hir:: attrs:: { self , AttributeKind , CfgEntry , CfgHideShow , HideOrShow } ;
1516use rustc_middle:: ty:: TyCtxt ;
1617use rustc_session:: parse:: ParseSess ;
1718use rustc_span:: symbol:: { Symbol , sym} ;
1819use rustc_span:: { DUMMY_SP , Span } ;
19- use { rustc_ast as ast, rustc_hir as hir} ;
2020
2121use crate :: display:: { Joined as _, MaybeDisplay , Wrapped } ;
2222use crate :: html:: escape:: Escape ;
@@ -689,6 +689,12 @@ impl<'a> From<&'a CfgEntry> for SimpleCfg {
689689 }
690690}
691691
692+ impl < ' a > From < & ' a attrs:: CfgInfo > for SimpleCfg {
693+ fn from ( cfg : & ' a attrs:: CfgInfo ) -> Self {
694+ Self { name : cfg. name , value : cfg. value . map ( |( value, _) | value) }
695+ }
696+ }
697+
692698/// This type keeps track of (doc) cfg information as we go down the item tree.
693699#[ derive( Clone , Debug ) ]
694700pub ( crate ) struct CfgInfo {
@@ -746,37 +752,27 @@ fn show_hide_show_conflict_error(
746752fn handle_auto_cfg_hide_show (
747753 tcx : TyCtxt < ' _ > ,
748754 cfg_info : & mut CfgInfo ,
749- sub_attr : & MetaItemInner ,
750- is_show : bool ,
755+ attr : & CfgHideShow ,
756+ attr_span : Span ,
751757 new_show_attrs : & mut FxHashMap < ( Symbol , Option < Symbol > ) , rustc_span:: Span > ,
752758 new_hide_attrs : & mut FxHashMap < ( Symbol , Option < Symbol > ) , rustc_span:: Span > ,
753759) {
754- if let MetaItemInner :: MetaItem ( item) = sub_attr
755- && let MetaItemKind :: List ( items) = & item. kind
756- {
757- for item in items {
758- // FIXME: Report in case `Cfg::parse` reports an error?
759-
760- let Ok ( cfg) = Cfg :: parse ( item) else { continue } ;
761- if let CfgEntry :: NameValue { name, value, .. } = cfg. 0 {
762- let value = value. map ( |( v, _) | v) ;
763- let simple = SimpleCfg :: from ( & cfg. 0 ) ;
764- if is_show {
765- if let Some ( span) = new_hide_attrs. get ( & ( name, value) ) {
766- show_hide_show_conflict_error ( tcx, item. span ( ) , * span) ;
767- } else {
768- new_show_attrs. insert ( ( name, value) , item. span ( ) ) ;
769- }
770- cfg_info. hidden_cfg . remove ( & simple) ;
771- } else {
772- if let Some ( span) = new_show_attrs. get ( & ( name, value) ) {
773- show_hide_show_conflict_error ( tcx, item. span ( ) , * span) ;
774- } else {
775- new_hide_attrs. insert ( ( name, value) , item. span ( ) ) ;
776- }
777- cfg_info. hidden_cfg . insert ( simple) ;
778- }
760+ for value in & attr. values {
761+ let simple = SimpleCfg :: from ( value) ;
762+ if attr. kind == HideOrShow :: Show {
763+ if let Some ( span) = new_hide_attrs. get ( & ( simple. name , simple. value ) ) {
764+ show_hide_show_conflict_error ( tcx, attr_span, * span) ;
765+ } else {
766+ new_show_attrs. insert ( ( simple. name , simple. value ) , attr_span) ;
779767 }
768+ cfg_info. hidden_cfg . remove ( & simple) ;
769+ } else {
770+ if let Some ( span) = new_show_attrs. get ( & ( simple. name , simple. value ) ) {
771+ show_hide_show_conflict_error ( tcx, attr_span, * span) ;
772+ } else {
773+ new_hide_attrs. insert ( ( simple. name , simple. value ) , attr_span) ;
774+ }
775+ cfg_info. hidden_cfg . insert ( simple) ;
780776 }
781777 }
782778}
@@ -797,7 +793,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
797793
798794 fn check_changed_auto_active_status (
799795 changed_auto_active_status : & mut Option < rustc_span:: Span > ,
800- attr : & ast :: MetaItem ,
796+ attr_span : Span ,
801797 cfg_info : & mut CfgInfo ,
802798 tcx : TyCtxt < ' _ > ,
803799 new_value : bool ,
@@ -807,14 +803,14 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
807803 tcx. sess
808804 . dcx ( )
809805 . struct_span_err (
810- vec ! [ * first_change, attr . span ] ,
806+ vec ! [ * first_change, attr_span ] ,
811807 "`auto_cfg` was disabled and enabled more than once on the same item" ,
812808 )
813809 . emit ( ) ;
814810 return true ;
815811 }
816812 } else {
817- * changed_auto_active_status = Some ( attr . span ) ;
813+ * changed_auto_active_status = Some ( attr_span ) ;
818814 }
819815 cfg_info. auto_cfg_active = new_value;
820816 false
@@ -826,7 +822,7 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
826822 let mut doc_cfg = attrs
827823 . clone ( )
828824 . filter_map ( |attr| match attr {
829- Attribute :: Parsed ( AttributeKind :: Doc ( d) ) => Some ( d) ,
825+ Attribute :: Parsed ( AttributeKind :: Doc ( d) ) if !d . cfg . is_empty ( ) => Some ( d) ,
830826 _ => None ,
831827 } )
832828 . peekable ( ) ;
@@ -850,64 +846,37 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
850846
851847 // We get all `doc(auto_cfg)`, `cfg` and `target_feature` attributes.
852848 for attr in attrs {
853- if let Some ( ident) = attr. ident ( )
854- && ident. name == sym:: doc
855- && let Some ( attrs) = attr. meta_item_list ( )
856- {
857- for attr in attrs. iter ( ) . filter ( |attr| attr. has_name ( sym:: auto_cfg) ) {
858- let MetaItemInner :: MetaItem ( attr) = attr else {
859- continue ;
860- } ;
861- match & attr. kind {
862- MetaItemKind :: Word => {
863- if check_changed_auto_active_status (
864- & mut changed_auto_active_status,
865- attr,
866- cfg_info,
867- tcx,
868- true ,
869- ) {
870- return None ;
871- }
872- }
873- MetaItemKind :: NameValue ( lit) => {
874- if let LitKind :: Bool ( value) = lit. kind {
875- if check_changed_auto_active_status (
876- & mut changed_auto_active_status,
877- attr,
878- cfg_info,
879- tcx,
880- value,
881- ) {
882- return None ;
883- }
884- }
885- }
886- MetaItemKind :: List ( sub_attrs) => {
887- if check_changed_auto_active_status (
888- & mut changed_auto_active_status,
889- attr,
890- cfg_info,
891- tcx,
892- true ,
893- ) {
894- return None ;
895- }
896- for sub_attr in sub_attrs. iter ( ) {
897- if let Some ( ident) = sub_attr. ident ( )
898- && ( ident. name == sym:: show || ident. name == sym:: hide)
899- {
900- handle_auto_cfg_hide_show (
901- tcx,
902- cfg_info,
903- & sub_attr,
904- ident. name == sym:: show,
905- & mut new_show_attrs,
906- & mut new_hide_attrs,
907- ) ;
908- }
909- }
910- }
849+ if let Attribute :: Parsed ( AttributeKind :: Doc ( d) ) = attr {
850+ for ( new_value, span) in & d. auto_cfg_change {
851+ if check_changed_auto_active_status (
852+ & mut changed_auto_active_status,
853+ * span,
854+ cfg_info,
855+ tcx,
856+ * new_value,
857+ ) {
858+ return None ;
859+ }
860+ }
861+ if let Some ( ( _, span) ) = d. auto_cfg . first ( ) {
862+ if check_changed_auto_active_status (
863+ & mut changed_auto_active_status,
864+ * span,
865+ cfg_info,
866+ tcx,
867+ true ,
868+ ) {
869+ return None ;
870+ }
871+ for ( value, span) in & d. auto_cfg {
872+ handle_auto_cfg_hide_show (
873+ tcx,
874+ cfg_info,
875+ value,
876+ * span,
877+ & mut new_show_attrs,
878+ & mut new_hide_attrs,
879+ ) ;
911880 }
912881 }
913882 } else if let hir:: Attribute :: Parsed ( AttributeKind :: TargetFeature { features, .. } ) = attr {
0 commit comments