diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 92bd4a498ca37..d29bcc8a6bb9a 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -779,20 +779,25 @@ impl Item { self.attrs .other_attrs .iter() - .filter_map(|attr| match attr { - hir::Attribute::Parsed(AttributeKind::LinkSection { name, .. }) => { - Some(format!("#[unsafe(link_section = \"{name}\")]")) + .filter_map(|attr| { + if attr_has_doc_flag(attr, sym::hidden) { + return Some("#[doc(hidden)]".to_string()); } - hir::Attribute::Parsed(AttributeKind::NoMangle(..)) => { - Some("#[unsafe(no_mangle)]".to_string()) - } - hir::Attribute::Parsed(AttributeKind::ExportName { name, .. }) => { - Some(format!("#[unsafe(export_name = \"{name}\")]")) - } - hir::Attribute::Parsed(AttributeKind::NonExhaustive(..)) => { - Some("#[non_exhaustive]".to_string()) + match attr { + hir::Attribute::Parsed(AttributeKind::LinkSection { name, .. }) => { + Some(format!("#[unsafe(link_section = \"{name}\")]")) + } + hir::Attribute::Parsed(AttributeKind::NoMangle(..)) => { + Some("#[unsafe(no_mangle)]".to_string()) + } + hir::Attribute::Parsed(AttributeKind::ExportName { name, .. }) => { + Some(format!("#[unsafe(export_name = \"{name}\")]")) + } + hir::Attribute::Parsed(AttributeKind::NonExhaustive(..)) => { + Some("#[non_exhaustive]".to_string()) + } + _ => None, } - _ => None, }) .collect() } @@ -1159,6 +1164,19 @@ pub(crate) struct Attributes { pub(crate) other_attrs: ThinVec, } +/// Returns `true` if the attribute is a `#[doc(...)]` attribute with the given flag, e.g. +/// `#[doc(hidden)]` or `#[doc(inline)]`. +fn attr_has_doc_flag(attr: &hir::Attribute, flag: Symbol) -> bool { + if !attr.has_name(sym::doc) { + return false; + } + + if let Some(items) = attr.meta_item_list() { + return items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)); + } + false +} + impl Attributes { pub(crate) fn lists(&self, name: Symbol) -> impl Iterator { hir_attr_lists(&self.other_attrs[..], name) @@ -1166,13 +1184,7 @@ impl Attributes { pub(crate) fn has_doc_flag(&self, flag: Symbol) -> bool { for attr in &self.other_attrs { - if !attr.has_name(sym::doc) { - continue; - } - - if let Some(items) = attr.meta_item_list() - && items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) - { + if attr_has_doc_flag(attr, flag) { return true; } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 493fdc6fb1b33..6c772c01defec 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1407,10 +1407,6 @@ impl clean::FnDecl { pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { - if item.is_doc_hidden() { - f.write_str("#[doc(hidden)] ")?; - } - match item.visibility(cx.tcx()) { None => {} Some(ty::Visibility::Public) => f.write_str("pub ")?, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 2618ec272ca5a..b7460db93c60c 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1865,7 +1865,6 @@ fn item_variants( fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { - // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. render_attributes_in_code(w, it, "", cx); if !t.macro_rules { write!(w, "{}", visibility_print_with_space(it, cx))?; diff --git a/tests/rustdoc/display-hidden-items.rs b/tests/rustdoc/display-hidden-items.rs index 40cd636e2fe29..f3834ca9ef1f4 100644 --- a/tests/rustdoc/display-hidden-items.rs +++ b/tests/rustdoc/display-hidden-items.rs @@ -7,23 +7,27 @@ //@ has 'foo/index.html' //@ has - '//dt/span[@title="Hidden item"]' '👻' -//@ has - '//*[@id="reexport.hidden_reexport"]/code' '#[doc(hidden)] pub use hidden::inside_hidden as hidden_reexport;' +//@ has - '//*[@id="reexport.hidden_reexport"]/code/*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has - '//*[@id="reexport.hidden_reexport"]/code' 'pub use hidden::inside_hidden as hidden_reexport;' #[doc(hidden)] pub use hidden::inside_hidden as hidden_reexport; //@ has - '//dt/a[@class="trait"]' 'TraitHidden' //@ has 'foo/trait.TraitHidden.html' -//@ has - '//code' '#[doc(hidden)] pub trait TraitHidden' +//@ has - '//*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has - '//code' 'pub trait TraitHidden' #[doc(hidden)] pub trait TraitHidden {} //@ has 'foo/index.html' '//dt/a[@class="trait"]' 'Trait' pub trait Trait { //@ has 'foo/trait.Trait.html' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' #[doc(hidden)] const BAR: u32 = 0; + //@ has - '//*[@class="code-attribute"]' '#[doc(hidden)]' //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' #[doc(hidden)] fn foo() {} @@ -33,26 +37,31 @@ pub trait Trait { //@ has 'foo/struct.Struct.html' pub struct Struct { //@ has - '//*[@id="structfield.a"]/code' 'a: u32' + //@ has - '//*[@class="code-attribute"]' '#[doc(hidden)]' #[doc(hidden)] pub a: u32, } impl Struct { + //@ has - '//*[@class="code-attribute"]' '#[doc(hidden)]' //@ has - '//*[@id="method.new"]/*[@class="code-header"]' 'pub fn new() -> Self' #[doc(hidden)] pub fn new() -> Self { Self { a: 0 } } } impl Trait for Struct { - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0u32' - //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' '#[doc(hidden)] fn foo()' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' 'const BAR: u32 = 0u32' + //@ has - '//*[@id="method.foo"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' + //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' } //@ has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' impl TraitHidden for Struct {} //@ has 'foo/index.html' '//dt/a[@class="enum"]' 'HiddenEnum' //@ has 'foo/enum.HiddenEnum.html' -//@ has - '//code' '#[doc(hidden)] pub enum HiddenEnum' +//@ has - '//*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has - '//code' 'pub enum HiddenEnum' #[doc(hidden)] pub enum HiddenEnum { A, @@ -60,6 +69,7 @@ pub enum HiddenEnum { //@ has 'foo/index.html' '//dt/a[@class="enum"]' 'Enum' pub enum Enum { + //@ has - '//*[@class="code-attribute"]' '#[doc(hidden)]' //@ has 'foo/enum.Enum.html' '//*[@id="variant.A"]/*[@class="code-header"]' 'A' #[doc(hidden)] A, @@ -73,3 +83,12 @@ pub mod hidden { //@ has 'foo/hidden/fn.inside_hidden.html' pub fn inside_hidden() {} } + +//@ has 'foo/index.html' +//@ has - '//*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has - '//a[@class="macro"]' 'macro_rule' +#[doc(hidden)] +#[macro_export] +macro_rules! macro_rule { + () => {}; +}