Fix handling of items inside a doc(hidden) block

This commit is contained in:
Guillaume Gomez 2023-01-17 20:40:25 +01:00
parent 34685485c7
commit 5b654a7e5e
3 changed files with 66 additions and 34 deletions

View File

@ -2225,21 +2225,17 @@ fn clean_maybe_renamed_item<'tcx>(
get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs);
}
if !extra_attrs.is_empty() {
let mut item = if !extra_attrs.is_empty() {
extra_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
let attrs = Attributes::from_ast(&extra_attrs);
let cfg = extra_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg);
vec![Item::from_def_id_and_attrs_and_parts(
def_id,
Some(name),
kind,
Box::new(attrs),
cfg,
)]
Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg)
} else {
vec![Item::from_def_id_and_parts(def_id, Some(name), kind, cx)]
}
Item::from_def_id_and_parts(def_id, Some(name), kind, cx)
};
item.inline_stmt_id = import_id.map(|def_id| def_id.to_def_id());
vec![item]
})
}

View File

@ -1,4 +1,6 @@
//! Strip all doc(hidden) items from the output.
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym;
use std::mem;
@ -7,6 +9,7 @@ use crate::clean::{Item, ItemIdSet, NestedAttributesExt};
use crate::core::DocContext;
use crate::fold::{strip_item, DocFolder};
use crate::passes::{ImplStripper, Pass};
use crate::visit_ast::inherits_doc_hidden;
pub(crate) const STRIP_HIDDEN: Pass = Pass {
name: "strip-hidden",
@ -21,7 +24,12 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
// strip all #[doc(hidden)] items
let krate = {
let mut stripper = Stripper { retained: &mut retained, update_retained: true };
let mut stripper = Stripper {
retained: &mut retained,
update_retained: true,
tcx: cx.tcx,
is_in_hidden_item: false,
};
stripper.fold_crate(krate)
};
@ -36,14 +44,38 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
stripper.fold_crate(krate)
}
struct Stripper<'a> {
struct Stripper<'a, 'tcx> {
retained: &'a mut ItemIdSet,
update_retained: bool,
tcx: TyCtxt<'tcx>,
is_in_hidden_item: bool,
}
impl<'a> DocFolder for Stripper<'a> {
impl<'a, 'tcx> Stripper<'a, 'tcx> {
fn set_is_in_hidden_item_and_fold(&mut self, is_in_hidden_item: bool, i: Item) -> Item {
let prev = self.is_in_hidden_item;
self.is_in_hidden_item |= is_in_hidden_item;
let ret = self.fold_item_recur(i);
self.is_in_hidden_item = prev;
ret
}
}
impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
fn fold_item(&mut self, i: Item) -> Option<Item> {
if i.attrs.lists(sym::doc).has_word(sym::hidden) {
let has_doc_hidden = i.attrs.lists(sym::doc).has_word(sym::hidden);
let mut is_hidden = self.is_in_hidden_item || has_doc_hidden;
if !is_hidden && i.inline_stmt_id.is_none() {
// We don't need to check if it's coming from a reexport since the reexport itself was
// already checked.
is_hidden = i
.item_id
.as_def_id()
.and_then(|def_id| def_id.as_local())
.map(|def_id| inherits_doc_hidden(self.tcx, def_id))
.unwrap_or(false);
}
if is_hidden {
debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name);
// Use a dedicated hidden item for fields, variants, and modules.
// We need to keep private fields and variants, so that the docs
@ -53,23 +85,31 @@ impl<'a> DocFolder for Stripper<'a> {
// module it's defined in. Both of these are marked "stripped," and
// not included in the final docs, but since they still have an effect
// on the final doc, cannot be completely removed from the Clean IR.
match *i.kind {
return match *i.kind {
clean::StructFieldItem(..) | clean::ModuleItem(..) | clean::VariantItem(..) => {
// We need to recurse into stripped modules to
// strip things like impl methods but when doing so
// we must not add any items to the `retained` set.
let old = mem::replace(&mut self.update_retained, false);
let ret = strip_item(self.fold_item_recur(i));
let ret = strip_item(self.set_is_in_hidden_item_and_fold(true, i));
self.update_retained = old;
return Some(ret);
Some(ret)
}
_ => return None,
}
} else {
if self.update_retained {
self.retained.insert(i.item_id);
}
_ => {
let ret = self.set_is_in_hidden_item_and_fold(true, i);
if has_doc_hidden {
// If the item itself has `#[doc(hidden)]`, then we simply remove it.
None
} else {
// However if it's a "descendant" of a `#[doc(hidden)]` item, then we strip it.
Some(strip_item(ret))
}
}
};
}
Some(self.fold_item_recur(i))
if self.update_retained {
self.retained.insert(i.item_id);
}
Some(self.set_is_in_hidden_item_and_fold(is_hidden, i))
}
}

View File

@ -187,6 +187,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}
self.inside_public_path = orig_inside_public_path;
debug!("Leaving module {:?}", m);
}
/// Tries to resolve the target of a `pub use` statement and inlines the
@ -290,7 +291,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
&mut self,
item: &'tcx hir::Item<'_>,
renamed: Option<Symbol>,
parent_id: Option<LocalDefId>,
import_id: Option<LocalDefId>,
) -> bool {
debug!("visiting item {:?}", item);
let name = renamed.unwrap_or(item.ident.name);
@ -347,7 +348,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}
self.add_to_current_mod(item, renamed, parent_id);
self.add_to_current_mod(item, renamed, import_id);
}
}
hir::ItemKind::Macro(ref macro_def, _) => {
@ -383,13 +384,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
| hir::ItemKind::Static(..)
| hir::ItemKind::Trait(..)
| hir::ItemKind::TraitAlias(..) => {
self.add_to_current_mod(item, renamed, parent_id);
self.add_to_current_mod(item, renamed, import_id);
}
hir::ItemKind::Const(..) => {
// Underscore constants do not correspond to a nameable item and
// so are never useful in documentation.
if name != kw::Underscore {
self.add_to_current_mod(item, renamed, parent_id);
self.add_to_current_mod(item, renamed, import_id);
}
}
hir::ItemKind::Impl(impl_) => {
@ -437,12 +438,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
}
fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
let parent_id = if self.modules.len() > 1 {
Some(self.modules[self.modules.len() - 2].def_id)
} else {
None
};
if self.visit_item_inner(i, None, parent_id) {
if self.visit_item_inner(i, None, None) {
walk_item(self, i);
}
}