]> git.proxmox.com Git - rustc.git/blame - src/librustdoc/passes/stripper.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / src / librustdoc / passes / stripper.rs
CommitLineData
29967ef6
XL
1use rustc_hir::def_id::{DefId, DefIdSet};
2use rustc_middle::middle::privacy::AccessLevels;
3use std::mem;
4
5use crate::clean::{self, GetDefId, Item};
6use crate::fold::{DocFolder, StripItem};
7
fc512014
XL
8crate struct Stripper<'a> {
9 crate retained: &'a mut DefIdSet,
10 crate access_levels: &'a AccessLevels<DefId>,
11 crate update_retained: bool,
29967ef6
XL
12}
13
14impl<'a> DocFolder for Stripper<'a> {
15 fn fold_item(&mut self, i: Item) -> Option<Item> {
5869c6ff 16 match *i.kind {
29967ef6
XL
17 clean::StrippedItem(..) => {
18 // We need to recurse into stripped modules to strip things
19 // like impl methods but when doing so we must not add any
20 // items to the `retained` set.
21 debug!("Stripper: recursing into stripped {:?} {:?}", i.type_(), i.name);
22 let old = mem::replace(&mut self.update_retained, false);
23 let ret = self.fold_item_recur(i);
24 self.update_retained = old;
fc512014 25 return Some(ret);
29967ef6
XL
26 }
27 // These items can all get re-exported
28 clean::OpaqueTyItem(..)
29 | clean::TypedefItem(..)
30 | clean::StaticItem(..)
31 | clean::StructItem(..)
32 | clean::EnumItem(..)
33 | clean::TraitItem(..)
34 | clean::FunctionItem(..)
35 | clean::VariantItem(..)
36 | clean::MethodItem(..)
37 | clean::ForeignFunctionItem(..)
38 | clean::ForeignStaticItem(..)
39 | clean::ConstantItem(..)
40 | clean::UnionItem(..)
41 | clean::AssocConstItem(..)
42 | clean::TraitAliasItem(..)
43 | clean::ForeignTypeItem => {
44 if i.def_id.is_local() {
45 if !self.access_levels.is_exported(i.def_id) {
46 debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
47 return None;
48 }
49 }
50 }
51
52 clean::StructFieldItem(..) => {
fc512014 53 if !i.visibility.is_public() {
5869c6ff 54 return Some(StripItem(i).strip());
29967ef6
XL
55 }
56 }
57
58 clean::ModuleItem(..) => {
fc512014 59 if i.def_id.is_local() && !i.visibility.is_public() {
29967ef6
XL
60 debug!("Stripper: stripping module {:?}", i.name);
61 let old = mem::replace(&mut self.update_retained, false);
fc512014 62 let ret = StripItem(self.fold_item_recur(i)).strip();
29967ef6 63 self.update_retained = old;
5869c6ff 64 return Some(ret);
29967ef6
XL
65 }
66 }
67
68 // handled in the `strip-priv-imports` pass
6a06907d 69 clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
29967ef6
XL
70
71 clean::ImplItem(..) => {}
72
73 // tymethods/macros have no control over privacy
74 clean::MacroItem(..) | clean::TyMethodItem(..) => {}
75
76 // Proc-macros are always public
77 clean::ProcMacroItem(..) => {}
78
79 // Primitives are never stripped
80 clean::PrimitiveItem(..) => {}
81
82 // Associated types are never stripped
83 clean::AssocTypeItem(..) => {}
84
85 // Keywords are never stripped
86 clean::KeywordItem(..) => {}
87 }
88
5869c6ff 89 let fastreturn = match *i.kind {
29967ef6
XL
90 // nothing left to do for traits (don't want to filter their
91 // methods out, visibility controlled by the trait)
92 clean::TraitItem(..) => true,
93
94 // implementations of traits are always public.
95 clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
96 // Struct variant fields have inherited visibility
5869c6ff 97 clean::VariantItem(clean::Variant::Struct(..)) => true,
29967ef6
XL
98 _ => false,
99 };
100
101 let i = if fastreturn {
102 if self.update_retained {
103 self.retained.insert(i.def_id);
104 }
105 return Some(i);
106 } else {
107 self.fold_item_recur(i)
108 };
109
fc512014
XL
110 if self.update_retained {
111 self.retained.insert(i.def_id);
29967ef6 112 }
fc512014 113 Some(i)
29967ef6
XL
114 }
115}
116
117/// This stripper discards all impls which reference stripped items
fc512014
XL
118crate struct ImplStripper<'a> {
119 crate retained: &'a DefIdSet,
29967ef6
XL
120}
121
122impl<'a> DocFolder for ImplStripper<'a> {
123 fn fold_item(&mut self, i: Item) -> Option<Item> {
5869c6ff 124 if let clean::ImplItem(ref imp) = *i.kind {
29967ef6
XL
125 // emptied none trait impls can be stripped
126 if imp.trait_.is_none() && imp.items.is_empty() {
127 return None;
128 }
129 if let Some(did) = imp.for_.def_id() {
130 if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did) {
131 debug!("ImplStripper: impl item for stripped type; removing");
132 return None;
133 }
134 }
135 if let Some(did) = imp.trait_.def_id() {
136 if did.is_local() && !self.retained.contains(&did) {
137 debug!("ImplStripper: impl item for stripped trait; removing");
138 return None;
139 }
140 }
141 if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
142 for typaram in generics {
143 if let Some(did) = typaram.def_id() {
144 if did.is_local() && !self.retained.contains(&did) {
145 debug!(
146 "ImplStripper: stripped item in trait's generics; removing impl"
147 );
148 return None;
149 }
150 }
151 }
152 }
153 }
fc512014 154 Some(self.fold_item_recur(i))
29967ef6
XL
155 }
156}
157
158/// This stripper discards all private import statements (`use`, `extern crate`)
fc512014 159crate struct ImportStripper;
29967ef6
XL
160
161impl DocFolder for ImportStripper {
162 fn fold_item(&mut self, i: Item) -> Option<Item> {
5869c6ff 163 match *i.kind {
6a06907d
XL
164 clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => {
165 None
166 }
fc512014 167 _ => Some(self.fold_item_recur(i)),
29967ef6
XL
168 }
169 }
170}