Skip to content

Commit a20e6bb

Browse files
committed
Consider doc(hidden) for crate-local inlining
1 parent ae7fca1 commit a20e6bb

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

src/librustdoc/visit_ast.rs

+36-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc::middle::stability;
2626
use rustc_front::hir;
2727

2828
use core;
29+
use clean::{Clean, Attributes};
2930
use doctree::*;
3031

3132
// looks to me like the first two of these are actually
@@ -182,15 +183,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
182183
please_inline: bool) -> Option<hir::ViewPath_> {
183184
match path {
184185
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) {
186187
None
187188
} else {
188189
Some(hir::ViewPathSimple(dst, base))
189190
}
190191
}
191192
hir::ViewPathList(p, paths) => {
192193
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,
194195
please_inline)
195196
}).collect::<hir::HirVec<hir::PathListItem>>();
196197

@@ -201,9 +202,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
201202
}
202203
}
203204

204-
// these are feature gated anyway
205205
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) {
207207
None
208208
} else {
209209
Some(hir::ViewPathGlob(base))
@@ -213,8 +213,32 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
213213

214214
}
215215

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>,
217226
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+
218242
let tcx = match self.cx.tcx_opt() {
219243
Some(tcx) => tcx,
220244
None => return false
@@ -226,9 +250,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
226250
let analysis = match self.analysis {
227251
Some(analysis) => analysis, None => return false
228252
};
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 {
230259
return false
231260
}
261+
232262
if !self.view_item_stack.insert(def_node_id) { return false }
233263

234264
let ret = match tcx.map.get(def_node_id) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[doc(hidden)]
12+
pub mod foo {
13+
pub struct Foo;
14+
}
15+
16+
mod bar {
17+
pub use self::bar::Bar;
18+
mod bar {
19+
pub struct Bar;
20+
}
21+
}
22+
23+
// @has issue_28537/struct.Foo.html
24+
pub use foo::Foo;
25+
26+
// @has issue_28537/struct.Bar.html
27+
pub use self::bar::Bar;

0 commit comments

Comments
 (0)