11//! Strip all doc(hidden) items from the output.
2+
3+ use rustc_middle:: ty:: TyCtxt ;
24use rustc_span:: symbol:: sym;
35use std:: mem;
46
@@ -7,6 +9,7 @@ use crate::clean::{Item, ItemIdSet, NestedAttributesExt};
79use crate :: core:: DocContext ;
810use crate :: fold:: { strip_item, DocFolder } ;
911use crate :: passes:: { ImplStripper , Pass } ;
12+ use crate :: visit_ast:: inherits_doc_hidden;
1013
1114pub ( crate ) const STRIP_HIDDEN : Pass = Pass {
1215 name : "strip-hidden" ,
@@ -21,7 +24,12 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
2124
2225 // strip all #[doc(hidden)] items
2326 let krate = {
24- let mut stripper = Stripper { retained : & mut retained, update_retained : true } ;
27+ let mut stripper = Stripper {
28+ retained : & mut retained,
29+ update_retained : true ,
30+ tcx : cx. tcx ,
31+ is_in_hidden_item : false ,
32+ } ;
2533 stripper. fold_crate ( krate)
2634 } ;
2735
@@ -36,14 +44,38 @@ pub(crate) fn strip_hidden(krate: clean::Crate, cx: &mut DocContext<'_>) -> clea
3644 stripper. fold_crate ( krate)
3745}
3846
39- struct Stripper < ' a > {
47+ struct Stripper < ' a , ' tcx > {
4048 retained : & ' a mut ItemIdSet ,
4149 update_retained : bool ,
50+ tcx : TyCtxt < ' tcx > ,
51+ is_in_hidden_item : bool ,
52+ }
53+
54+ impl < ' a , ' tcx > Stripper < ' a , ' tcx > {
55+ fn set_is_in_hidden_item_and_fold ( & mut self , is_in_hidden_item : bool , i : Item ) -> Item {
56+ let prev = self . is_in_hidden_item ;
57+ self . is_in_hidden_item |= is_in_hidden_item;
58+ let ret = self . fold_item_recur ( i) ;
59+ self . is_in_hidden_item = prev;
60+ ret
61+ }
4262}
4363
44- impl < ' a > DocFolder for Stripper < ' a > {
64+ impl < ' a , ' tcx > DocFolder for Stripper < ' a , ' tcx > {
4565 fn fold_item ( & mut self , i : Item ) -> Option < Item > {
46- if i. attrs . lists ( sym:: doc) . has_word ( sym:: hidden) {
66+ let has_doc_hidden = i. attrs . lists ( sym:: doc) . has_word ( sym:: hidden) ;
67+ let mut is_hidden = self . is_in_hidden_item || has_doc_hidden;
68+ if !is_hidden && i. inline_stmt_id . is_none ( ) {
69+ // We don't need to check if it's coming from a reexport since the reexport itself was
70+ // already checked.
71+ is_hidden = i
72+ . item_id
73+ . as_def_id ( )
74+ . and_then ( |def_id| def_id. as_local ( ) )
75+ . map ( |def_id| inherits_doc_hidden ( self . tcx , def_id) )
76+ . unwrap_or ( false ) ;
77+ }
78+ if is_hidden {
4779 debug ! ( "strip_hidden: stripping {:?} {:?}" , i. type_( ) , i. name) ;
4880 // Use a dedicated hidden item for fields, variants, and modules.
4981 // We need to keep private fields and variants, so that the docs
@@ -53,23 +85,31 @@ impl<'a> DocFolder for Stripper<'a> {
5385 // module it's defined in. Both of these are marked "stripped," and
5486 // not included in the final docs, but since they still have an effect
5587 // on the final doc, cannot be completely removed from the Clean IR.
56- match * i. kind {
88+ return match * i. kind {
5789 clean:: StructFieldItem ( ..) | clean:: ModuleItem ( ..) | clean:: VariantItem ( ..) => {
5890 // We need to recurse into stripped modules to
5991 // strip things like impl methods but when doing so
6092 // we must not add any items to the `retained` set.
6193 let old = mem:: replace ( & mut self . update_retained , false ) ;
62- let ret = strip_item ( self . fold_item_recur ( i) ) ;
94+ let ret = strip_item ( self . set_is_in_hidden_item_and_fold ( true , i) ) ;
6395 self . update_retained = old;
64- return Some ( ret) ;
96+ Some ( ret)
97+ }
98+ _ => {
99+ let ret = self . set_is_in_hidden_item_and_fold ( true , i) ;
100+ if has_doc_hidden {
101+ // If the item itself has `#[doc(hidden)]`, then we simply remove it.
102+ None
103+ } else {
104+ // However if it's a "descendant" of a `#[doc(hidden)]` item, then we strip it.
105+ Some ( strip_item ( ret) )
106+ }
65107 }
66- _ => return None ,
67- }
68- } else {
69- if self . update_retained {
70- self . retained . insert ( i. item_id ) ;
71- }
108+ } ;
109+ }
110+ if self . update_retained {
111+ self . retained . insert ( i. item_id ) ;
72112 }
73- Some ( self . fold_item_recur ( i) )
113+ Some ( self . set_is_in_hidden_item_and_fold ( is_hidden , i) )
74114 }
75115}
0 commit comments