diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 94e7462d26df..a5e630a09afe 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -233,6 +233,19 @@ fn is_doc_hidden(&self) -> bool { self.has_name(sym::doc) && self.meta_item_list().is_some_and(|l| list_contains_name(&l, sym::hidden)) } + + fn is_doc_keyword_or_attribute(&self) -> bool { + if self.has_name(sym::doc) + && let Some(items) = self.meta_item_list() + { + for item in items { + if item.has_name(sym::keyword) || item.has_name(sym::attribute) { + return true; + } + } + } + false + } } impl Attribute { @@ -865,6 +878,9 @@ fn is_proc_macro_attr(&self) -> bool { /// Returns `true` if this attribute contains `doc(hidden)`. fn is_doc_hidden(&self) -> bool; + + /// Returns `true` is this attribute contains `doc(keyword)` or `doc(attribute)`. + fn is_doc_keyword_or_attribute(&self) -> bool; } // FIXME(fn_delegation): use function delegation instead of manually forwarding diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index afa1a33fe769..f5470adb87e0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1418,6 +1418,10 @@ fn is_proc_macro_attr(&self) -> bool { fn is_doc_hidden(&self) -> bool { matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some()) } + + fn is_doc_keyword_or_attribute(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some()) + } } // FIXME(fn_delegation): use function delegation instead of manually forwarding diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 0ac8e68ad968..7f7c423acb40 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -367,16 +367,8 @@ pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool { /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]` or `#[doc(attribute)]`. pub fn has_primitive_or_keyword_or_attribute_docs(attrs: &[impl AttributeExt]) -> bool { for attr in attrs { - if attr.has_name(sym::rustc_doc_primitive) { + if attr.has_name(sym::rustc_doc_primitive) || attr.is_doc_keyword_or_attribute() { return true; - } else if attr.has_name(sym::doc) - && let Some(items) = attr.meta_item_list() - { - for item in items { - if item.has_name(sym::keyword) || item.has_name(sym::attribute) { - return true; - } - } } } false diff --git a/tests/rustdoc/doc-on-keyword.rs b/tests/rustdoc/doc-on-keyword.rs new file mode 100644 index 000000000000..0c62eda60a6b --- /dev/null +++ b/tests/rustdoc/doc-on-keyword.rs @@ -0,0 +1,13 @@ +// While working on , the +// intra doc links on keyword/attribute items were not processed. + +#![feature(rustdoc_internals)] +#![crate_name = "foo"] + +//@ has 'foo/keyword.trait.html' +//@ has - '//a[@href="{{channel}}/core/marker/trait.Send.html"]' 'Send' +//@ has - '//a[@href="{{channel}}/core/marker/trait.Sync.html"]' 'Sync' +#[doc(keyword = "trait")] +// +/// [`Send`] and [Sync] +mod bar {}