Skip to content

Commit ea9c8b9

Browse files
authored
Rollup merge of rust-lang#40814 - abonander:issue_39436, r=jseyfried
Rustdoc: memoize `pub use`-reexported macros so they don't appear twice in docs Closes rust-lang#39436 Preserves existing behavior for `#[macro_reexport]`. `pub use`'d macros are shown as reexports unless inlined, and also correctly obey `#[doc(hidden)]`. r? @jseyfried cc @SergioBenitez
2 parents a9dc8ac + d8fc5b8 commit ea9c8b9

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

src/librustdoc/visit_ast.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use syntax_pos::Span;
2121

2222
use rustc::hir::map as hir_map;
2323
use rustc::hir::def::Def;
24-
use rustc::hir::def_id::LOCAL_CRATE;
24+
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
2525
use rustc::middle::cstore::LoadedMacro;
2626
use rustc::middle::privacy::AccessLevel;
2727
use rustc::util::nodemap::FxHashSet;
@@ -48,6 +48,7 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> {
4848
inlining: bool,
4949
/// Is the current module and all of its parents public?
5050
inside_public_path: bool,
51+
reexported_macros: FxHashSet<DefId>,
5152
}
5253

5354
impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
@@ -62,6 +63,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
6263
view_item_stack: stack,
6364
inlining: false,
6465
inside_public_path: true,
66+
reexported_macros: FxHashSet(),
6567
}
6668
}
6769

@@ -201,9 +203,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
201203
if let Some(exports) = self.cx.tcx.export_map.get(&id) {
202204
for export in exports {
203205
if let Def::Macro(def_id, ..) = export.def {
204-
if def_id.krate == LOCAL_CRATE {
206+
if def_id.krate == LOCAL_CRATE || self.reexported_macros.contains(&def_id) {
205207
continue // These are `krate.exported_macros`, handled in `self.visit()`.
206208
}
209+
207210
let imported_from = self.cx.sess().cstore.original_crate_name(def_id.krate);
208211
let def = match self.cx.sess().cstore.load_macro(def_id, self.cx.sess()) {
209212
LoadedMacro::MacroDef(macro_def) => macro_def,
@@ -217,6 +220,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
217220
} else {
218221
unreachable!()
219222
};
223+
220224
om.macros.push(Macro {
221225
def_id: def_id,
222226
attrs: def.attrs.clone().into(),
@@ -263,6 +267,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
263267
false
264268
}
265269

270+
debug!("maybe_inline_local def: {:?}", def);
271+
266272
let tcx = self.cx.tcx;
267273
if def == Def::Err {
268274
return false;
@@ -274,6 +280,17 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
274280
let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
275281
use_attrs.lists("doc").has_word("hidden");
276282

283+
// Memoize the non-inlined `pub use`'d macros so we don't push an extra
284+
// declaration in `visit_mod_contents()`
285+
if !def_did.is_local() {
286+
if let Def::Macro(did, _) = def {
287+
if please_inline { return true }
288+
debug!("memoizing non-inlined macro export: {:?}", def);
289+
self.reexported_macros.insert(did);
290+
return false;
291+
}
292+
}
293+
277294
// For cross-crate impl inlining we need to know whether items are
278295
// reachable in documentation - a previously nonreachable item can be
279296
// made reachable by cross-crate inlining which we're checking here.
@@ -294,6 +311,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
294311
},
295312
_ => {},
296313
}
314+
297315
return false
298316
}
299317

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2017 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+
#![crate_name="macros"]
11+
12+
#[macro_export]
13+
macro_rules! foo {
14+
() => {};
15+
}
16+
17+
#[macro_export]
18+
macro_rules! bar {
19+
() => {};
20+
}
21+
22+
#[macro_export]
23+
macro_rules! baz {
24+
() => {};
25+
}
26+
27+
#[macro_export]
28+
macro_rules! quux {
29+
() => {};
30+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2017 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+
// aux-build:pub-use-extern-macros.rs
12+
13+
#![feature(use_extern_macros, macro_reexport)]
14+
15+
// @has pub_use_extern_macros/macro.foo.html
16+
// @!has pub_use_extern_macros/index.html 'pub use macros::foo;'
17+
#[macro_reexport(foo)] extern crate macros;
18+
19+
// @has pub_use_extern_macros/index.html 'pub use macros::bar;'
20+
// @!has pub_use_extern_macros/macro.bar.html
21+
pub use macros::bar;
22+
23+
// @has pub_use_extern_macros/macro.baz.html
24+
// @!has pub_use_extern_macros/index.html 'pub use macros::baz;'
25+
#[doc(inline)]
26+
pub use macros::baz;
27+
28+
// @!has pub_use_extern_macros/macro.quux.html
29+
// @!has pub_use_extern_macros/index.html 'pub use macros::quux;'
30+
#[doc(hidden)]
31+
pub use macros::quux;

0 commit comments

Comments
 (0)