@@ -281,6 +281,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
281281 | AttributeKind :: ObjcClass { .. }
282282 | AttributeKind :: ObjcSelector { .. }
283283 | AttributeKind :: RustcCoherenceIsCore ( ..)
284+ | AttributeKind :: Feature ( ..)
284285 ) => { /* do nothing */ }
285286 Attribute :: Unparsed ( attr_item) => {
286287 style = Some ( attr_item. style ) ;
@@ -1874,75 +1875,82 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18741875 fn check_unused_attribute ( & self , hir_id : HirId , attr : & Attribute , style : Option < AttrStyle > ) {
18751876 // Warn on useless empty attributes.
18761877 // FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute`
1877- let note = if attr. has_any_name ( & [
1878- sym:: allow,
1879- sym:: expect,
1880- sym:: warn,
1881- sym:: deny,
1882- sym:: forbid,
1883- sym:: feature,
1884- ] ) && attr. meta_item_list ( ) . is_some_and ( |list| list. is_empty ( ) )
1885- {
1886- errors:: UnusedNote :: EmptyList { name : attr. name ( ) . unwrap ( ) }
1887- } else if attr. has_any_name ( & [ sym:: allow, sym:: warn, sym:: deny, sym:: forbid, sym:: expect] )
1888- && let Some ( meta) = attr. meta_item_list ( )
1889- && let [ meta] = meta. as_slice ( )
1890- && let Some ( item) = meta. meta_item ( )
1891- && let MetaItemKind :: NameValue ( _) = & item. kind
1892- && item. path == sym:: reason
1893- {
1894- errors:: UnusedNote :: NoLints { name : attr. name ( ) . unwrap ( ) }
1895- } else if attr. has_any_name ( & [ sym:: allow, sym:: warn, sym:: deny, sym:: forbid, sym:: expect] )
1896- && let Some ( meta) = attr. meta_item_list ( )
1897- && meta. iter ( ) . any ( |meta| {
1898- meta. meta_item ( ) . map_or ( false , |item| item. path == sym:: linker_messages)
1899- } )
1900- {
1901- if hir_id != CRATE_HIR_ID {
1902- match style {
1903- Some ( ast:: AttrStyle :: Outer ) => {
1904- let attr_span = attr. span ( ) ;
1905- let bang_position = self
1906- . tcx
1907- . sess
1908- . source_map ( )
1909- . span_until_char ( attr_span, '[' )
1910- . shrink_to_hi ( ) ;
1911-
1912- self . tcx . emit_node_span_lint (
1878+ let note =
1879+ if attr. has_any_name ( & [ sym:: allow, sym:: expect, sym:: warn, sym:: deny, sym:: forbid] )
1880+ && attr. meta_item_list ( ) . is_some_and ( |list| list. is_empty ( ) )
1881+ {
1882+ errors:: UnusedNote :: EmptyList { name : attr. name ( ) . unwrap ( ) }
1883+ } else if attr. has_any_name ( & [
1884+ sym:: allow,
1885+ sym:: warn,
1886+ sym:: deny,
1887+ sym:: forbid,
1888+ sym:: expect,
1889+ ] ) && let Some ( meta) = attr. meta_item_list ( )
1890+ && let [ meta] = meta. as_slice ( )
1891+ && let Some ( item) = meta. meta_item ( )
1892+ && let MetaItemKind :: NameValue ( _) = & item. kind
1893+ && item. path == sym:: reason
1894+ {
1895+ errors:: UnusedNote :: NoLints { name : attr. name ( ) . unwrap ( ) }
1896+ } else if attr. has_any_name ( & [
1897+ sym:: allow,
1898+ sym:: warn,
1899+ sym:: deny,
1900+ sym:: forbid,
1901+ sym:: expect,
1902+ ] ) && let Some ( meta) = attr. meta_item_list ( )
1903+ && meta. iter ( ) . any ( |meta| {
1904+ meta. meta_item ( ) . map_or ( false , |item| item. path == sym:: linker_messages)
1905+ } )
1906+ {
1907+ if hir_id != CRATE_HIR_ID {
1908+ match style {
1909+ Some ( ast:: AttrStyle :: Outer ) => {
1910+ let attr_span = attr. span ( ) ;
1911+ let bang_position = self
1912+ . tcx
1913+ . sess
1914+ . source_map ( )
1915+ . span_until_char ( attr_span, '[' )
1916+ . shrink_to_hi ( ) ;
1917+
1918+ self . tcx . emit_node_span_lint (
1919+ UNUSED_ATTRIBUTES ,
1920+ hir_id,
1921+ attr_span,
1922+ errors:: OuterCrateLevelAttr {
1923+ suggestion : errors:: OuterCrateLevelAttrSuggestion {
1924+ bang_position,
1925+ } ,
1926+ } ,
1927+ )
1928+ }
1929+ Some ( ast:: AttrStyle :: Inner ) | None => self . tcx . emit_node_span_lint (
19131930 UNUSED_ATTRIBUTES ,
19141931 hir_id,
1915- attr_span,
1916- errors:: OuterCrateLevelAttr {
1917- suggestion : errors:: OuterCrateLevelAttrSuggestion { bang_position } ,
1918- } ,
1919- )
1920- }
1921- Some ( ast:: AttrStyle :: Inner ) | None => self . tcx . emit_node_span_lint (
1922- UNUSED_ATTRIBUTES ,
1923- hir_id,
1924- attr. span ( ) ,
1925- errors:: InnerCrateLevelAttr ,
1926- ) ,
1927- } ;
1928- return ;
1929- } else {
1930- let never_needs_link = self
1931- . tcx
1932- . crate_types ( )
1933- . iter ( )
1934- . all ( |kind| matches ! ( kind, CrateType :: Rlib | CrateType :: Staticlib ) ) ;
1935- if never_needs_link {
1936- errors:: UnusedNote :: LinkerMessagesBinaryCrateOnly
1937- } else {
1932+ attr. span ( ) ,
1933+ errors:: InnerCrateLevelAttr ,
1934+ ) ,
1935+ } ;
19381936 return ;
1937+ } else {
1938+ let never_needs_link = self
1939+ . tcx
1940+ . crate_types ( )
1941+ . iter ( )
1942+ . all ( |kind| matches ! ( kind, CrateType :: Rlib | CrateType :: Staticlib ) ) ;
1943+ if never_needs_link {
1944+ errors:: UnusedNote :: LinkerMessagesBinaryCrateOnly
1945+ } else {
1946+ return ;
1947+ }
19391948 }
1940- }
1941- } else if attr. has_name ( sym:: default_method_body_is_const) {
1942- errors:: UnusedNote :: DefaultMethodBodyConst
1943- } else {
1944- return ;
1945- } ;
1949+ } else if attr. has_name ( sym:: default_method_body_is_const) {
1950+ errors:: UnusedNote :: DefaultMethodBodyConst
1951+ } else {
1952+ return ;
1953+ } ;
19461954
19471955 self . tcx . emit_node_span_lint (
19481956 UNUSED_ATTRIBUTES ,
0 commit comments