@@ -745,31 +745,30 @@ impl Item {
745745 find_attr ! ( & self . attrs. other_attrs, NonExhaustive ( ..) )
746746 }
747747
748- /// Returns a documentation-level item type from the item.
748+ /// Returns a documentation-level item type from the item. In case of a `macro_rules!` which
749+ /// contains an attr/derive kind, it will always return `ItemType::Macro`. If you want all
750+ /// kinds, you need to use [`Item::types`].
749751 pub ( crate ) fn type_ ( & self ) -> ItemType {
750752 ItemType :: from ( self )
751753 }
752754
753- // FIXME: Return an iterator instead of a `ThinVec`.
754- pub ( crate ) fn types ( & self ) -> ThinVec < ItemType > {
755+ /// Returns an item types. There is only one case where it can return more than one kind:
756+ /// for `macro_rules!` items which contain an attr/derive kind.
757+ pub ( crate ) fn types ( & self ) -> impl Iterator < Item = ItemType > {
755758 if let ItemKind :: MacroItem ( _, macro_kinds) = self . kind {
756- let mut types = ThinVec :: with_capacity ( 3 ) ;
757- for kind in macro_kinds. iter ( ) {
758- match kind {
759- MacroKinds :: ATTR => types. push ( ItemType :: BangMacroAttribute ) ,
760- MacroKinds :: DERIVE => types. push ( ItemType :: BangMacroDerive ) ,
761- MacroKinds :: BANG => types. push ( ItemType :: Macro ) ,
762- _ => panic ! ( "unsupported macro kind {kind:?}" ) ,
763- }
764- }
765- return types;
759+ Either :: Right ( macro_kinds. iter ( ) . map ( |kind| match kind {
760+ MacroKinds :: ATTR => ItemType :: BangMacroAttribute ,
761+ MacroKinds :: DERIVE => ItemType :: BangMacroDerive ,
762+ MacroKinds :: BANG => ItemType :: Macro ,
763+ _ => panic ! ( "unsupported macro kind {kind:?}" ) ,
764+ } ) )
765+ } else {
766+ Either :: Left ( std:: iter:: once ( self . type_ ( ) ) )
766767 }
767- let mut types = ThinVec :: with_capacity ( 1 ) ;
768- types. push ( self . type_ ( ) ) ;
769- types
770768 }
771769
772- pub ( crate ) fn is_macro_rules ( & self ) -> bool {
770+ /// Returns true if this a macro declared with the `macro` keyword or with `macro_rules!.
771+ pub ( crate ) fn is_bang_macro_or_macro_rules ( & self ) -> bool {
773772 matches ! ( self . kind, ItemKind :: MacroItem ( ..) )
774773 }
775774
@@ -946,8 +945,12 @@ pub(crate) enum ItemKind {
946945 ForeignStaticItem ( Static , hir:: Safety ) ,
947946 /// `type`s from an extern block
948947 ForeignTypeItem ,
949- /// A bang macro. it can be multiple things (macro, derive and attribute, potentially multiple
950- /// at once). Don't forget to look into the `MacroKinds` values.
948+ /// A macro defined with `macro_rules` or the `macro` keyword. It can be multiple things (macro,
949+ /// derive and attribute, potentially multiple at once). Don't forget to look into the
950+ ///`MacroKinds` values.
951+ ///
952+ /// If a `macro_rules!` only contains a `attr`/`derive` branch, then it's not stored in this
953+ /// variant but in the `ProcMacroItem` variant.
951954 MacroItem ( Macro , MacroKinds ) ,
952955 ProcMacroItem ( ProcMacro ) ,
953956 PrimitiveItem ( PrimitiveType ) ,
0 commit comments