diff options
| author | Jonathan Brouwer <jonathantbrouwer@gmail.com> | 2025-06-22 12:14:38 +0200 |
|---|---|---|
| committer | Jonathan Brouwer <jonathantbrouwer@gmail.com> | 2025-06-22 22:17:04 +0200 |
| commit | 2084831cd54eb603fec6cd85ebd9d1426b09f628 (patch) | |
| tree | 54d0aff88295539e999e2d99e612761f137a973a /src | |
| parent | 111e9bc64bbdce14122e3676978f2ceefa5bff1a (diff) | |
Port `#[no_mangle]` to new attribute parsing infrastructure
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/clean/types.rs | 22 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/render/print_item.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/json/conversions.rs | 2 | ||||
| -rw-r--r-- | src/rustdoc-json-types/lib.rs | 4 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/functions/must_use.rs | 5 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs | 7 |
7 files changed, 22 insertions, 24 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c0a9d8c84f6..0aedc7f5219 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -746,15 +746,17 @@ impl Item { Some(tcx.visibility(def_id)) } - pub(crate) fn attributes_without_repr(&self, tcx: TyCtxt<'_>, is_json: bool) -> Vec<String> { + fn attributes_without_repr(&self, tcx: TyCtxt<'_>, is_json: bool) -> Vec<String> { const ALLOWED_ATTRIBUTES: &[Symbol] = &[sym::export_name, sym::link_section, sym::no_mangle, sym::non_exhaustive]; - self.attrs .other_attrs .iter() .filter_map(|attr| { - if is_json { + // NoMangle is special-cased because cargo-semver-checks uses it + if matches!(attr, hir::Attribute::Parsed(AttributeKind::NoMangle(..))) { + Some("#[no_mangle]".to_string()) + } else if is_json { match attr { // rustdoc-json stores this in `Item::deprecation`, so we // don't want it it `Item::attrs`. @@ -767,26 +769,22 @@ impl Item { s }), } - } else if attr.has_any_name(ALLOWED_ATTRIBUTES) { + } else { + if !attr.has_any_name(ALLOWED_ATTRIBUTES) { + return None; + } Some( rustc_hir_pretty::attribute_to_string(&tcx, attr) .replace("\\\n", "") .replace('\n', "") .replace(" ", " "), ) - } else { - None } }) .collect() } - pub(crate) fn attributes_and_repr( - &self, - tcx: TyCtxt<'_>, - cache: &Cache, - is_json: bool, - ) -> Vec<String> { + pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, cache: &Cache, is_json: bool) -> Vec<String> { let mut attrs = self.attributes_without_repr(tcx, is_json); if let Some(repr_attr) = self.repr(tcx, cache, is_json) { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 66d5aafa3c1..ed58bae70bd 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1194,7 +1194,7 @@ fn render_assoc_item( // a whitespace prefix and newline. fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display { fmt::from_fn(move |f| { - for a in it.attributes_and_repr(cx.tcx(), cx.cache(), false) { + for a in it.attributes(cx.tcx(), cx.cache(), false) { writeln!(f, "{prefix}{a}")?; } Ok(()) @@ -1210,7 +1210,7 @@ fn render_code_attribute(code_attr: CodeAttribute, w: &mut impl fmt::Write) { // When an attribute is rendered inside a <code> tag, it is formatted using // a div to produce a newline after it. fn render_attributes_in_code(w: &mut impl fmt::Write, it: &clean::Item, cx: &Context<'_>) { - for attr in it.attributes_and_repr(cx.tcx(), cx.cache(), false) { + for attr in it.attributes(cx.tcx(), cx.cache(), false) { render_code_attribute(CodeAttribute(attr), w); } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index a75088d27cc..515424cbef1 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1491,7 +1491,7 @@ impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { writeln!(f, "{repr}")?; }; } else { - for a in self.it.attributes_and_repr(self.cx.tcx(), self.cx.cache(), false) { + for a in self.it.attributes(self.cx.tcx(), self.cx.cache(), false) { writeln!(f, "{a}")?; } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index abad6e48029..0778b5b56f5 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -40,7 +40,7 @@ impl JsonRenderer<'_> { }) .collect(); let docs = item.opt_doc_value(); - let attrs = item.attributes_and_repr(self.tcx, &self.cache, true); + let attrs = item.attributes(self.tcx, &self.cache, true); let span = item.span(self.tcx); let visibility = item.visibility(self.tcx); let clean::ItemInner { name, item_id, .. } = *item.inner; diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index e5c246cb69c..0e72ddd9db1 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -37,8 +37,8 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc // will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line // are deliberately not in a doc comment, because they need not be in public docs.) // -// Latest feature: Pretty printing of must_use attributes changed -pub const FORMAT_VERSION: u32 = 52; +// Latest feature: Pretty printing of no_mangle attributes changed +pub const FORMAT_VERSION: u32 = 53; /// The root of the emitted JSON blob. /// diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index ea9ed4ddade..c0c23e217fd 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -15,9 +15,8 @@ use clippy_utils::ty::is_must_use_ty; use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::{return_ty, trait_ref_of_method}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; -use rustc_attr_data_structures::AttributeKind; use rustc_span::Symbol; -use rustc_attr_data_structures::find_attr; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use core::ops::ControlFlow; @@ -36,7 +35,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_> let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); if let Some((attr_span, reason)) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, *attr_span, *reason, attrs, sig); - } else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) { + } else if is_public && !is_proc_macro(attrs) && !find_attr!(attrs, AttributeKind::NoMangle(..)) { check_must_use_candidate( cx, sig.decl, diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs index b71dde90691..0159c5d2ac1 100644 --- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -6,6 +6,8 @@ use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; use rustc_span::{BytePos, Pos}; +use rustc_attr_data_structures::AttributeKind; +use rustc_hir::Attribute; declare_clippy_lint! { /// ### What it does @@ -44,8 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { let mut app = Applicability::MaybeIncorrect; let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(ident.span.lo()), "..", &mut app); for attr in attrs { - if let Some(ident) = attr.ident() - && ident.name == rustc_span::sym::no_mangle + if let Attribute::Parsed(AttributeKind::NoMangle(attr_span)) = attr && fn_sig.header.abi == ExternAbi::Rust && let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn") && !fn_attrs.contains("extern") @@ -54,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { .span .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) .shrink_to_lo(); - let attr_snippet = snippet(cx, attr.span(), ".."); + let attr_snippet = snippet(cx, *attr_span, ".."); span_lint_and_then( cx, |
