@@ -283,6 +283,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
283283 | AttributeKind :: ObjcSelector { .. }
284284 | AttributeKind :: RustcCoherenceIsCore ( ..)
285285 | AttributeKind :: DebuggerVisualizer ( ..)
286+ | AttributeKind :: Feature ( ..)
286287 ) => { /* do nothing */ }
287288 Attribute :: Unparsed ( attr_item) => {
288289 style = Some ( attr_item. style ) ;
@@ -1861,75 +1862,82 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
18611862 fn check_unused_attribute ( & self , hir_id : HirId , attr : & Attribute , style : Option < AttrStyle > ) {
18621863 // Warn on useless empty attributes.
18631864 // FIXME(jdonszelmann): this lint should be moved to attribute parsing, see `AcceptContext::warn_empty_attribute`
1864- let note = if attr. has_any_name ( & [
1865- sym:: allow,
1866- sym:: expect,
1867- sym:: warn,
1868- sym:: deny,
1869- sym:: forbid,
1870- sym:: feature,
1871- ] ) && attr. meta_item_list ( ) . is_some_and ( |list| list. is_empty ( ) )
1872- {
1873- errors:: UnusedNote :: EmptyList { name : attr. name ( ) . unwrap ( ) }
1874- } else if attr. has_any_name ( & [ sym:: allow, sym:: warn, sym:: deny, sym:: forbid, sym:: expect] )
1875- && let Some ( meta) = attr. meta_item_list ( )
1876- && let [ meta] = meta. as_slice ( )
1877- && let Some ( item) = meta. meta_item ( )
1878- && let MetaItemKind :: NameValue ( _) = & item. kind
1879- && item. path == sym:: reason
1880- {
1881- errors:: UnusedNote :: NoLints { name : attr. name ( ) . unwrap ( ) }
1882- } else if attr. has_any_name ( & [ sym:: allow, sym:: warn, sym:: deny, sym:: forbid, sym:: expect] )
1883- && let Some ( meta) = attr. meta_item_list ( )
1884- && meta. iter ( ) . any ( |meta| {
1885- meta. meta_item ( ) . map_or ( false , |item| item. path == sym:: linker_messages)
1886- } )
1887- {
1888- if hir_id != CRATE_HIR_ID {
1889- match style {
1890- Some ( ast:: AttrStyle :: Outer ) => {
1891- let attr_span = attr. span ( ) ;
1892- let bang_position = self
1893- . tcx
1894- . sess
1895- . source_map ( )
1896- . span_until_char ( attr_span, '[' )
1897- . shrink_to_hi ( ) ;
1898-
1899- self . tcx . emit_node_span_lint (
1865+ let note =
1866+ if attr. has_any_name ( & [ sym:: allow, sym:: expect, sym:: warn, sym:: deny, sym:: forbid] )
1867+ && attr. meta_item_list ( ) . is_some_and ( |list| list. is_empty ( ) )
1868+ {
1869+ errors:: UnusedNote :: EmptyList { name : attr. name ( ) . unwrap ( ) }
1870+ } else if attr. has_any_name ( & [
1871+ sym:: allow,
1872+ sym:: warn,
1873+ sym:: deny,
1874+ sym:: forbid,
1875+ sym:: expect,
1876+ ] ) && let Some ( meta) = attr. meta_item_list ( )
1877+ && let [ meta] = meta. as_slice ( )
1878+ && let Some ( item) = meta. meta_item ( )
1879+ && let MetaItemKind :: NameValue ( _) = & item. kind
1880+ && item. path == sym:: reason
1881+ {
1882+ errors:: UnusedNote :: NoLints { 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+ && meta. iter ( ) . any ( |meta| {
1891+ meta. meta_item ( ) . map_or ( false , |item| item. path == sym:: linker_messages)
1892+ } )
1893+ {
1894+ if hir_id != CRATE_HIR_ID {
1895+ match style {
1896+ Some ( ast:: AttrStyle :: Outer ) => {
1897+ let attr_span = attr. span ( ) ;
1898+ let bang_position = self
1899+ . tcx
1900+ . sess
1901+ . source_map ( )
1902+ . span_until_char ( attr_span, '[' )
1903+ . shrink_to_hi ( ) ;
1904+
1905+ self . tcx . emit_node_span_lint (
1906+ UNUSED_ATTRIBUTES ,
1907+ hir_id,
1908+ attr_span,
1909+ errors:: OuterCrateLevelAttr {
1910+ suggestion : errors:: OuterCrateLevelAttrSuggestion {
1911+ bang_position,
1912+ } ,
1913+ } ,
1914+ )
1915+ }
1916+ Some ( ast:: AttrStyle :: Inner ) | None => self . tcx . emit_node_span_lint (
19001917 UNUSED_ATTRIBUTES ,
19011918 hir_id,
1902- attr_span,
1903- errors:: OuterCrateLevelAttr {
1904- suggestion : errors:: OuterCrateLevelAttrSuggestion { bang_position } ,
1905- } ,
1906- )
1907- }
1908- Some ( ast:: AttrStyle :: Inner ) | None => self . tcx . emit_node_span_lint (
1909- UNUSED_ATTRIBUTES ,
1910- hir_id,
1911- attr. span ( ) ,
1912- errors:: InnerCrateLevelAttr ,
1913- ) ,
1914- } ;
1915- return ;
1916- } else {
1917- let never_needs_link = self
1918- . tcx
1919- . crate_types ( )
1920- . iter ( )
1921- . all ( |kind| matches ! ( kind, CrateType :: Rlib | CrateType :: Staticlib ) ) ;
1922- if never_needs_link {
1923- errors:: UnusedNote :: LinkerMessagesBinaryCrateOnly
1924- } else {
1919+ attr. span ( ) ,
1920+ errors:: InnerCrateLevelAttr ,
1921+ ) ,
1922+ } ;
19251923 return ;
1924+ } else {
1925+ let never_needs_link = self
1926+ . tcx
1927+ . crate_types ( )
1928+ . iter ( )
1929+ . all ( |kind| matches ! ( kind, CrateType :: Rlib | CrateType :: Staticlib ) ) ;
1930+ if never_needs_link {
1931+ errors:: UnusedNote :: LinkerMessagesBinaryCrateOnly
1932+ } else {
1933+ return ;
1934+ }
19261935 }
1927- }
1928- } else if attr. has_name ( sym:: default_method_body_is_const) {
1929- errors:: UnusedNote :: DefaultMethodBodyConst
1930- } else {
1931- return ;
1932- } ;
1936+ } else if attr. has_name ( sym:: default_method_body_is_const) {
1937+ errors:: UnusedNote :: DefaultMethodBodyConst
1938+ } else {
1939+ return ;
1940+ } ;
19331941
19341942 self . tcx . emit_node_span_lint (
19351943 UNUSED_ATTRIBUTES ,
0 commit comments