@@ -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