@@ -276,6 +276,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
276276 | AttributeKind :: NoCore { .. }
277277 | AttributeKind :: NoStd { .. }
278278 | AttributeKind :: RustcCoherenceIsCore ( ..)
279+ | AttributeKind :: Feature ( ..)
279280 ) => { /* do nothing */ }
280281 Attribute :: Unparsed ( attr_item) => {
281282 style = Some ( attr_item. style ) ;
@@ -1893,75 +1894,82 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18931894 fn check_unused_attribute ( & self , hir_id : HirId , attr : & Attribute , style : Option < AttrStyle > ) {
18941895 // Warn on useless empty attributes.
18951896 // FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute`
1896- let note = if attr. has_any_name ( & [
1897- sym:: allow,
1898- sym:: expect,
1899- sym:: warn,
1900- sym:: deny,
1901- sym:: forbid,
1902- sym:: feature,
1903- ] ) && attr. meta_item_list ( ) . is_some_and ( |list| list. is_empty ( ) )
1904- {
1905- errors:: UnusedNote :: EmptyList { name : attr. name ( ) . unwrap ( ) }
1906- } else if attr. has_any_name ( & [ sym:: allow, sym:: warn, sym:: deny, sym:: forbid, sym:: expect] )
1907- && let Some ( meta) = attr. meta_item_list ( )
1908- && let [ meta] = meta. as_slice ( )
1909- && let Some ( item) = meta. meta_item ( )
1910- && let MetaItemKind :: NameValue ( _) = & item. kind
1911- && item. path == sym:: reason
1912- {
1913- errors:: UnusedNote :: NoLints { name : attr. name ( ) . unwrap ( ) }
1914- } else if attr. has_any_name ( & [ sym:: allow, sym:: warn, sym:: deny, sym:: forbid, sym:: expect] )
1915- && let Some ( meta) = attr. meta_item_list ( )
1916- && meta. iter ( ) . any ( |meta| {
1917- meta. meta_item ( ) . map_or ( false , |item| item. path == sym:: linker_messages)
1918- } )
1919- {
1920- if hir_id != CRATE_HIR_ID {
1921- match style {
1922- Some ( ast:: AttrStyle :: Outer ) => {
1923- let attr_span = attr. span ( ) ;
1924- let bang_position = self
1925- . tcx
1926- . sess
1927- . source_map ( )
1928- . span_until_char ( attr_span, '[' )
1929- . shrink_to_hi ( ) ;
1930-
1931- self . tcx . emit_node_span_lint (
1897+ let note =
1898+ if attr. has_any_name ( & [ sym:: allow, sym:: expect, sym:: warn, sym:: deny, sym:: forbid] )
1899+ && attr. meta_item_list ( ) . is_some_and ( |list| list. is_empty ( ) )
1900+ {
1901+ errors:: UnusedNote :: EmptyList { name : attr. name ( ) . unwrap ( ) }
1902+ } else if attr. has_any_name ( & [
1903+ sym:: allow,
1904+ sym:: warn,
1905+ sym:: deny,
1906+ sym:: forbid,
1907+ sym:: expect,
1908+ ] ) && let Some ( meta) = attr. meta_item_list ( )
1909+ && let [ meta] = meta. as_slice ( )
1910+ && let Some ( item) = meta. meta_item ( )
1911+ && let MetaItemKind :: NameValue ( _) = & item. kind
1912+ && item. path == sym:: reason
1913+ {
1914+ errors:: UnusedNote :: NoLints { name : attr. name ( ) . unwrap ( ) }
1915+ } else if attr. has_any_name ( & [
1916+ sym:: allow,
1917+ sym:: warn,
1918+ sym:: deny,
1919+ sym:: forbid,
1920+ sym:: expect,
1921+ ] ) && let Some ( meta) = attr. meta_item_list ( )
1922+ && meta. iter ( ) . any ( |meta| {
1923+ meta. meta_item ( ) . map_or ( false , |item| item. path == sym:: linker_messages)
1924+ } )
1925+ {
1926+ if hir_id != CRATE_HIR_ID {
1927+ match style {
1928+ Some ( ast:: AttrStyle :: Outer ) => {
1929+ let attr_span = attr. span ( ) ;
1930+ let bang_position = self
1931+ . tcx
1932+ . sess
1933+ . source_map ( )
1934+ . span_until_char ( attr_span, '[' )
1935+ . shrink_to_hi ( ) ;
1936+
1937+ self . tcx . emit_node_span_lint (
1938+ UNUSED_ATTRIBUTES ,
1939+ hir_id,
1940+ attr_span,
1941+ errors:: OuterCrateLevelAttr {
1942+ suggestion : errors:: OuterCrateLevelAttrSuggestion {
1943+ bang_position,
1944+ } ,
1945+ } ,
1946+ )
1947+ }
1948+ Some ( ast:: AttrStyle :: Inner ) | None => self . tcx . emit_node_span_lint (
19321949 UNUSED_ATTRIBUTES ,
19331950 hir_id,
1934- attr_span,
1935- errors:: OuterCrateLevelAttr {
1936- suggestion : errors:: OuterCrateLevelAttrSuggestion { bang_position } ,
1937- } ,
1938- )
1939- }
1940- Some ( ast:: AttrStyle :: Inner ) | None => self . tcx . emit_node_span_lint (
1941- UNUSED_ATTRIBUTES ,
1942- hir_id,
1943- attr. span ( ) ,
1944- errors:: InnerCrateLevelAttr ,
1945- ) ,
1946- } ;
1947- return ;
1948- } else {
1949- let never_needs_link = self
1950- . tcx
1951- . crate_types ( )
1952- . iter ( )
1953- . all ( |kind| matches ! ( kind, CrateType :: Rlib | CrateType :: Staticlib ) ) ;
1954- if never_needs_link {
1955- errors:: UnusedNote :: LinkerMessagesBinaryCrateOnly
1956- } else {
1951+ attr. span ( ) ,
1952+ errors:: InnerCrateLevelAttr ,
1953+ ) ,
1954+ } ;
19571955 return ;
1956+ } else {
1957+ let never_needs_link = self
1958+ . tcx
1959+ . crate_types ( )
1960+ . iter ( )
1961+ . all ( |kind| matches ! ( kind, CrateType :: Rlib | CrateType :: Staticlib ) ) ;
1962+ if never_needs_link {
1963+ errors:: UnusedNote :: LinkerMessagesBinaryCrateOnly
1964+ } else {
1965+ return ;
1966+ }
19581967 }
1959- }
1960- } else if attr. has_name ( sym:: default_method_body_is_const) {
1961- errors:: UnusedNote :: DefaultMethodBodyConst
1962- } else {
1963- return ;
1964- } ;
1968+ } else if attr. has_name ( sym:: default_method_body_is_const) {
1969+ errors:: UnusedNote :: DefaultMethodBodyConst
1970+ } else {
1971+ return ;
1972+ } ;
19651973
19661974 self . tcx . emit_node_span_lint (
19671975 UNUSED_ATTRIBUTES ,
0 commit comments