@@ -26,6 +26,7 @@ use rustc::middle::stability;
26
26
use rustc_front:: hir;
27
27
28
28
use core;
29
+ use clean:: { Clean , Attributes } ;
29
30
use doctree:: * ;
30
31
31
32
// looks to me like the first two of these are actually
@@ -182,15 +183,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
182
183
please_inline : bool ) -> Option < hir:: ViewPath_ > {
183
184
match path {
184
185
hir:: ViewPathSimple ( dst, base) => {
185
- if self . resolve_id ( id, Some ( dst) , false , om, please_inline) {
186
+ if self . maybe_inline_local ( id, Some ( dst) , false , om, please_inline) {
186
187
None
187
188
} else {
188
189
Some ( hir:: ViewPathSimple ( dst, base) )
189
190
}
190
191
}
191
192
hir:: ViewPathList ( p, paths) => {
192
193
let mine = paths. into_iter ( ) . filter ( |path| {
193
- !self . resolve_id ( path. node . id ( ) , None , false , om,
194
+ !self . maybe_inline_local ( path. node . id ( ) , None , false , om,
194
195
please_inline)
195
196
} ) . collect :: < hir:: HirVec < hir:: PathListItem > > ( ) ;
196
197
@@ -201,9 +202,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
201
202
}
202
203
}
203
204
204
- // these are feature gated anyway
205
205
hir:: ViewPathGlob ( base) => {
206
- if self . resolve_id ( id, None , true , om, please_inline) {
206
+ if self . maybe_inline_local ( id, None , true , om, please_inline) {
207
207
None
208
208
} else {
209
209
Some ( hir:: ViewPathGlob ( base) )
@@ -213,8 +213,32 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
213
213
214
214
}
215
215
216
- fn resolve_id ( & mut self , id : ast:: NodeId , renamed : Option < ast:: Name > ,
216
+ /// Tries to resolve the target of a `pub use` statement and inlines the
217
+ /// target if it is defined locally and would not be documented otherwise,
218
+ /// or when it is specifically requested with `please_inline`.
219
+ /// (the latter is the case when the import is marked `doc(inline)`)
220
+ ///
221
+ /// Cross-crate inlining occurs later on during crate cleaning
222
+ /// and follows different rules.
223
+ ///
224
+ /// Returns true if the target has been inlined.
225
+ fn maybe_inline_local ( & mut self , id : ast:: NodeId , renamed : Option < ast:: Name > ,
217
226
glob : bool , om : & mut Module , please_inline : bool ) -> bool {
227
+
228
+ fn inherits_doc_hidden ( cx : & core:: DocContext , mut node : ast:: NodeId ) -> bool {
229
+ while let Some ( id) = cx. map . get_enclosing_scope ( node) {
230
+ node = id;
231
+ let attrs = cx. map . attrs ( node) . clean ( cx) ;
232
+ if attrs. list_def ( "doc" ) . has_word ( "hidden" ) {
233
+ return true ;
234
+ }
235
+ if node == ast:: CRATE_NODE_ID {
236
+ break ;
237
+ }
238
+ }
239
+ false
240
+ }
241
+
218
242
let tcx = match self . cx . tcx_opt ( ) {
219
243
Some ( tcx) => tcx,
220
244
None => return false
@@ -226,9 +250,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
226
250
let analysis = match self . analysis {
227
251
Some ( analysis) => analysis, None => return false
228
252
} ;
229
- if !please_inline && analysis. access_levels . is_public ( def) {
253
+
254
+ let is_private = !analysis. access_levels . is_public ( def) ;
255
+ let is_hidden = inherits_doc_hidden ( self . cx , def_node_id) ;
256
+
257
+ // Only inline if requested or if the item would otherwise be stripped
258
+ if !please_inline && !is_private && !is_hidden {
230
259
return false
231
260
}
261
+
232
262
if !self . view_item_stack . insert ( def_node_id) { return false }
233
263
234
264
let ret = match tcx. map . get ( def_node_id) {
@@ -276,10 +306,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
276
306
let node = if item. vis == hir:: Public {
277
307
let please_inline = item. attrs . iter ( ) . any ( |item| {
278
308
match item. meta_item_list ( ) {
279
- Some ( list) => {
309
+ Some ( list) if & item . name ( ) [ .. ] == "doc" => {
280
310
list. iter ( ) . any ( |i| & i. name ( ) [ ..] == "inline" )
281
311
}
282
- None => false ,
312
+ _ => false ,
283
313
}
284
314
} ) ;
285
315
match self . visit_view_path ( node, om, item. id , please_inline) {
0 commit comments