diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index eee13ff2b0dc0..f38a21bd1ff36 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1390,10 +1390,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)] ")?; - } - let Some(vis) = item.visibility(cx.tcx()) else { return Ok(()); }; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 0637f1cb6c82a..86e8167dc3cda 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1075,6 +1075,7 @@ fn assoc_type( cx: &Context<'_>, ) -> impl fmt::Display { fmt::from_fn(move |w| { + render_attributes_in_code(w, it, &" ".repeat(indent), cx)?; write!( w, "{indent}{vis}type {name}{generics}", @@ -2931,6 +2932,21 @@ fn render_attributes_in_code( prefix: &str, cx: &Context<'_>, ) -> fmt::Result { + render_attributes_in_code_with_options(w, item, prefix, cx, true, "") +} + +pub(super) fn render_attributes_in_code_with_options( + w: &mut impl fmt::Write, + item: &clean::Item, + prefix: &str, + cx: &Context<'_>, + render_doc_hidden: bool, + open_tag: &str, +) -> fmt::Result { + w.write_str(open_tag)?; + if render_doc_hidden && item.is_doc_hidden() { + render_code_attribute(prefix, "#[doc(hidden)]", w)?; + } for attr in &item.attrs.other_attrs { let hir::Attribute::Parsed(kind) = attr else { continue }; let attr = match kind { diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 55e36c462f967..5363755a0da7a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -344,15 +344,38 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i } for (_, myitem) in ¬_stripped_items[&type_] { + let visibility_and_hidden = |item: &clean::Item| match item.visibility(tcx) { + Some(ty::Visibility::Restricted(_)) => { + if item.is_doc_hidden() { + // Don't separate with a space when there are two of them + " ðŸ”’👻 " + } else { + " ðŸ”’ " + } + } + _ if item.is_doc_hidden() => " ðŸ‘» ", + _ => "", + }; + match myitem.kind { clean::ExternCrateItem { ref src } => { use crate::html::format::print_anchor; + let visibility_and_hidden = visibility_and_hidden(myitem); + // Module listings use the hidden marker, so skip doc(hidden) here. + super::render_attributes_in_code_with_options( + w, + myitem, + "", + cx, + false, + "
", + )?; match *src { Some(src) => { write!( w, - "
{}extern crate {} as {};", + "{}extern crate {} as {};", visibility_print_with_space(myitem, cx), print_anchor(myitem.item_id.expect_def_id(), src, cx), EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()) @@ -361,7 +384,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i None => { write!( w, - "
{}extern crate {};", + "{}extern crate {};", visibility_print_with_space(myitem, cx), print_anchor( myitem.item_id.expect_def_id(), @@ -371,7 +394,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i )?; } } - write!(w, "
")? + write!(w, "{visibility_and_hidden}")? } clean::ImportItem(ref import) => { let (stab_tags, deprecation) = match import.source.did { @@ -386,6 +409,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i } None => (String::new(), item.is_deprecated(tcx)), }; + let visibility_and_hidden = visibility_and_hidden(myitem); let id = match import.kind { clean::ImportKind::Simple(s) => { format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}"))) @@ -397,13 +421,13 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i "", deprecation_attr = deprecation_class_attr(deprecation) )?; - render_attributes_in_code(w, myitem, "", cx)?; write!( w, - "{vis}{imp}{stab_tags}\ + "{vis}{imp}{visibility_and_hidden}{stab_tags}\ ", vis = visibility_print_with_space(myitem, cx), imp = print_import(import, cx), + visibility_and_hidden = visibility_and_hidden, )?; } _ => { @@ -421,20 +445,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i } _ => "", }; - let visibility_and_hidden = match myitem.visibility(tcx) { - Some(ty::Visibility::Restricted(_)) => { - if myitem.is_doc_hidden() { - // Don't separate with a space when there are two of them - " ðŸ”’👻 " - } else { - " ðŸ”’ " - } - } - _ if myitem.is_doc_hidden() => { - " ðŸ‘» " - } - _ => "", - }; + let visibility_and_hidden = visibility_and_hidden(myitem); let docs = MarkdownSummaryLine(&myitem.doc_value(), &myitem.links(cx)) .into_string(); @@ -1868,7 +1879,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-html/display-hidden-items.rs b/tests/rustdoc-html/display-hidden-items.rs index 8b0854d1ade81..6b548e3945600 100644 --- a/tests/rustdoc-html/display-hidden-items.rs +++ b/tests/rustdoc-html/display-hidden-items.rs @@ -5,25 +5,32 @@ #![crate_name = "foo"] //@ 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;' +//@ matches - '//dt[code]' 'pub extern crate .*hidden_core;.*👻' +//@ has - '//dt/code' 'pub extern crate core as hidden_core;' +#[doc(hidden)] +pub extern crate core as hidden_core; + +//@ has - '//*[@id="reexport.hidden_reexport"]/span[@title="Hidden item"]' '👻' +//@ 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 'foo/trait.TraitHidden.html' '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has 'foo/trait.TraitHidden.html' '//*[@class="rust item-decl"]/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 = 0' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' #[doc(hidden)] const BAR: u32 = 0; + //@ has - '//*[@id="method.foo"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' #[doc(hidden)] fn foo() {} @@ -44,15 +51,16 @@ impl Struct { } impl Trait for Struct { - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' - //@ 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="method.foo"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' } //@ 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 'foo/enum.HiddenEnum.html' '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has 'foo/enum.HiddenEnum.html' '//*[@class="rust item-decl"]/code' 'pub enum HiddenEnum' #[doc(hidden)] pub enum HiddenEnum { A, @@ -60,6 +68,7 @@ pub enum HiddenEnum { //@ has 'foo/index.html' '//dt/a[@class="enum"]' 'Enum' pub enum Enum { + //@ has 'foo/enum.Enum.html' '//*[@id="variant.A"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' //@ has 'foo/enum.Enum.html' '//*[@id="variant.A"]/*[@class="code-header"]' 'A' #[doc(hidden)] A,