1 //! A collection of utility functions for the `strip_*` passes.
2 use rustc_hir::def_id::DefId;
3 use rustc_middle::middle::privacy::AccessLevels;
6 use crate::clean::{self, Item, ItemIdSet};
7 use crate::fold::{strip_item, DocFolder};
8 use crate::formats::cache::Cache;
10 crate struct Stripper<'a> {
11 crate retained: &'a mut ItemIdSet,
12 crate access_levels: &'a AccessLevels<DefId>,
13 crate update_retained: bool,
16 impl<'a> DocFolder for Stripper<'a> {
17 fn fold_item(&mut self, i: Item) -> Option<Item> {
19 clean::StrippedItem(..) => {
20 // We need to recurse into stripped modules to strip things
21 // like impl methods but when doing so we must not add any
22 // items to the `retained` set.
23 debug!("Stripper: recursing into stripped {:?} {:?}", i.type_(), i.name);
24 let old = mem::replace(&mut self.update_retained, false);
25 let ret = self.fold_item_recur(i);
26 self.update_retained = old;
29 // These items can all get re-exported
30 clean::OpaqueTyItem(..)
31 | clean::TypedefItem(..)
32 | clean::StaticItem(..)
33 | clean::StructItem(..)
35 | clean::TraitItem(..)
36 | clean::FunctionItem(..)
37 | clean::VariantItem(..)
38 | clean::MethodItem(..)
39 | clean::ForeignFunctionItem(..)
40 | clean::ForeignStaticItem(..)
41 | clean::ConstantItem(..)
42 | clean::UnionItem(..)
43 | clean::AssocConstItem(..)
44 | clean::AssocTypeItem(..)
45 | clean::TraitAliasItem(..)
46 | clean::MacroItem(..)
47 | clean::ForeignTypeItem => {
48 if i.item_id.is_local()
49 && !self.access_levels.is_exported(i.item_id.expect_def_id())
51 debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
56 clean::StructFieldItem(..) => {
57 if !i.visibility.is_public() {
58 return Some(strip_item(i));
62 clean::ModuleItem(..) => {
63 if i.item_id.is_local() && !i.visibility.is_public() {
64 debug!("Stripper: stripping module {:?}", i.name);
65 let old = mem::replace(&mut self.update_retained, false);
66 let ret = strip_item(self.fold_item_recur(i));
67 self.update_retained = old;
72 // handled in the `strip-priv-imports` pass
73 clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
75 clean::ImplItem(..) => {}
77 // tymethods etc. have no control over privacy
78 clean::TyMethodItem(..) | clean::TyAssocConstItem(..) | clean::TyAssocTypeItem(..) => {}
80 // Proc-macros are always public
81 clean::ProcMacroItem(..) => {}
83 // Primitives are never stripped
84 clean::PrimitiveItem(..) => {}
86 // Keywords are never stripped
87 clean::KeywordItem(..) => {}
90 let fastreturn = match *i.kind {
91 // nothing left to do for traits (don't want to filter their
92 // methods out, visibility controlled by the trait)
93 clean::TraitItem(..) => true,
95 // implementations of traits are always public.
96 clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
97 // Variant fields have inherited visibility
98 clean::VariantItem(clean::Variant::Struct(..) | clean::Variant::Tuple(..)) => true,
102 let i = if fastreturn {
103 if self.update_retained {
104 self.retained.insert(i.item_id);
108 self.fold_item_recur(i)
111 if self.update_retained {
112 self.retained.insert(i.item_id);
118 /// This stripper discards all impls which reference stripped items
119 crate struct ImplStripper<'a> {
120 crate retained: &'a ItemIdSet,
121 crate cache: &'a Cache,
124 impl<'a> DocFolder for ImplStripper<'a> {
125 fn fold_item(&mut self, i: Item) -> Option<Item> {
126 if let clean::ImplItem(ref imp) = *i.kind {
127 // emptied none trait impls can be stripped
128 if imp.trait_.is_none() && imp.items.is_empty() {
131 if let Some(did) = imp.for_.def_id(self.cache) {
132 if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
134 debug!("ImplStripper: impl item for stripped type; removing");
138 if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) {
139 if did.is_local() && !self.retained.contains(&did.into()) {
140 debug!("ImplStripper: impl item for stripped trait; removing");
144 if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
145 for typaram in generics {
146 if let Some(did) = typaram.def_id(self.cache) {
147 if did.is_local() && !self.retained.contains(&did.into()) {
149 "ImplStripper: stripped item in trait's generics; removing impl"
157 Some(self.fold_item_recur(i))
161 /// This stripper discards all private import statements (`use`, `extern crate`)
162 crate struct ImportStripper;
164 impl DocFolder for ImportStripper {
165 fn fold_item(&mut self, i: Item) -> Option<Item> {
167 clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => {
170 _ => Some(self.fold_item_recur(i)),