]> git.proxmox.com Git - rustc.git/blame - src/librustdoc/passes/stripper.rs
New upstream version 1.62.1+dfsg1
[rustc.git] / src / librustdoc / passes / stripper.rs
CommitLineData
a2a8927a 1//! A collection of utility functions for the `strip_*` passes.
17df50a5 2use rustc_hir::def_id::DefId;
29967ef6
XL
3use rustc_middle::middle::privacy::AccessLevels;
4use std::mem;
5
3c0e092e 6use crate::clean::{self, Item, ItemIdSet};
17df50a5 7use crate::fold::{strip_item, DocFolder};
5099ac24 8use crate::formats::cache::Cache;
29967ef6 9
fc512014 10crate struct Stripper<'a> {
136023e0 11 crate retained: &'a mut ItemIdSet,
fc512014
XL
12 crate access_levels: &'a AccessLevels<DefId>,
13 crate update_retained: bool,
29967ef6
XL
14}
15
16impl<'a> DocFolder for Stripper<'a> {
17 fn fold_item(&mut self, i: Item) -> Option<Item> {
5869c6ff 18 match *i.kind {
29967ef6
XL
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;
fc512014 27 return Some(ret);
29967ef6
XL
28 }
29 // These items can all get re-exported
30 clean::OpaqueTyItem(..)
31 | clean::TypedefItem(..)
32 | clean::StaticItem(..)
33 | clean::StructItem(..)
34 | clean::EnumItem(..)
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(..)
04454e1e 44 | clean::AssocTypeItem(..)
29967ef6 45 | clean::TraitAliasItem(..)
94222f64 46 | clean::MacroItem(..)
29967ef6 47 | clean::ForeignTypeItem => {
04454e1e
FG
48 if i.item_id.is_local()
49 && !self.access_levels.is_exported(i.item_id.expect_def_id())
5099ac24
FG
50 {
51 debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
52 return None;
29967ef6
XL
53 }
54 }
55
56 clean::StructFieldItem(..) => {
fc512014 57 if !i.visibility.is_public() {
17df50a5 58 return Some(strip_item(i));
29967ef6
XL
59 }
60 }
61
62 clean::ModuleItem(..) => {
04454e1e 63 if i.item_id.is_local() && !i.visibility.is_public() {
29967ef6
XL
64 debug!("Stripper: stripping module {:?}", i.name);
65 let old = mem::replace(&mut self.update_retained, false);
17df50a5 66 let ret = strip_item(self.fold_item_recur(i));
29967ef6 67 self.update_retained = old;
5869c6ff 68 return Some(ret);
29967ef6
XL
69 }
70 }
71
72 // handled in the `strip-priv-imports` pass
6a06907d 73 clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
29967ef6
XL
74
75 clean::ImplItem(..) => {}
76
04454e1e
FG
77 // tymethods etc. have no control over privacy
78 clean::TyMethodItem(..) | clean::TyAssocConstItem(..) | clean::TyAssocTypeItem(..) => {}
29967ef6
XL
79
80 // Proc-macros are always public
81 clean::ProcMacroItem(..) => {}
82
83 // Primitives are never stripped
84 clean::PrimitiveItem(..) => {}
85
29967ef6
XL
86 // Keywords are never stripped
87 clean::KeywordItem(..) => {}
88 }
89
5869c6ff 90 let fastreturn = match *i.kind {
29967ef6
XL
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,
94
95 // implementations of traits are always public.
96 clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
94222f64
XL
97 // Variant fields have inherited visibility
98 clean::VariantItem(clean::Variant::Struct(..) | clean::Variant::Tuple(..)) => true,
29967ef6
XL
99 _ => false,
100 };
101
102 let i = if fastreturn {
103 if self.update_retained {
04454e1e 104 self.retained.insert(i.item_id);
29967ef6
XL
105 }
106 return Some(i);
107 } else {
108 self.fold_item_recur(i)
109 };
110
fc512014 111 if self.update_retained {
04454e1e 112 self.retained.insert(i.item_id);
29967ef6 113 }
fc512014 114 Some(i)
29967ef6
XL
115 }
116}
117
118/// This stripper discards all impls which reference stripped items
fc512014 119crate struct ImplStripper<'a> {
136023e0 120 crate retained: &'a ItemIdSet,
5099ac24 121 crate cache: &'a Cache,
29967ef6
XL
122}
123
124impl<'a> DocFolder for ImplStripper<'a> {
125 fn fold_item(&mut self, i: Item) -> Option<Item> {
5869c6ff 126 if let clean::ImplItem(ref imp) = *i.kind {
29967ef6
XL
127 // emptied none trait impls can be stripped
128 if imp.trait_.is_none() && imp.items.is_empty() {
129 return None;
130 }
5099ac24 131 if let Some(did) = imp.for_.def_id(self.cache) {
c295e0f8 132 if did.is_local() && !imp.for_.is_assoc_ty() && !self.retained.contains(&did.into())
17df50a5 133 {
29967ef6
XL
134 debug!("ImplStripper: impl item for stripped type; removing");
135 return None;
136 }
137 }
c295e0f8 138 if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) {
17df50a5 139 if did.is_local() && !self.retained.contains(&did.into()) {
29967ef6
XL
140 debug!("ImplStripper: impl item for stripped trait; removing");
141 return None;
142 }
143 }
144 if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
145 for typaram in generics {
5099ac24 146 if let Some(did) = typaram.def_id(self.cache) {
17df50a5 147 if did.is_local() && !self.retained.contains(&did.into()) {
29967ef6
XL
148 debug!(
149 "ImplStripper: stripped item in trait's generics; removing impl"
150 );
151 return None;
152 }
153 }
154 }
155 }
156 }
fc512014 157 Some(self.fold_item_recur(i))
29967ef6
XL
158 }
159}
160
161/// This stripper discards all private import statements (`use`, `extern crate`)
fc512014 162crate struct ImportStripper;
29967ef6
XL
163
164impl DocFolder for ImportStripper {
165 fn fold_item(&mut self, i: Item) -> Option<Item> {
5869c6ff 166 match *i.kind {
6a06907d
XL
167 clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => {
168 None
169 }
fc512014 170 _ => Some(self.fold_item_recur(i)),
29967ef6
XL
171 }
172 }
173}