]> git.lizzy.rs Git - rust.git/blobdiff - src/librustdoc/visit_ast.rs
Rollup merge of #41249 - GuillaumeGomez:rustdoc-render, r=steveklabnik,frewsxcv
[rust.git] / src / librustdoc / visit_ast.rs
index 2793307697852b8aa1b36a0e971e2bc115f549e4..4252f2981ed6193e1ba5d59166c7c7eea0b037ab 100644 (file)
@@ -21,7 +21,7 @@
 
 use rustc::hir::map as hir_map;
 use rustc::hir::def::Def;
-use rustc::hir::def_id::LOCAL_CRATE;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::middle::cstore::LoadedMacro;
 use rustc::middle::privacy::AccessLevel;
 use rustc::util::nodemap::FxHashSet;
@@ -48,6 +48,7 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> {
     inlining: bool,
     /// Is the current module and all of its parents public?
     inside_public_path: bool,
+    reexported_macros: FxHashSet<DefId>,
 }
 
 impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
@@ -62,6 +63,7 @@ pub fn new(cx: &'a core::DocContext<'a, 'tcx>) -> RustdocVisitor<'a, 'tcx> {
             view_item_stack: stack,
             inlining: false,
             inside_public_path: true,
+            reexported_macros: FxHashSet(),
         }
     }
 
@@ -201,9 +203,10 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
         if let Some(exports) = self.cx.tcx.export_map.get(&id) {
             for export in exports {
                 if let Def::Macro(def_id, ..) = export.def {
-                    if def_id.krate == LOCAL_CRATE {
+                    if def_id.krate == LOCAL_CRATE || self.reexported_macros.contains(&def_id) {
                         continue // These are `krate.exported_macros`, handled in `self.visit()`.
                     }
+
                     let imported_from = self.cx.sess().cstore.original_crate_name(def_id.krate);
                     let def = match self.cx.sess().cstore.load_macro(def_id, self.cx.sess()) {
                         LoadedMacro::MacroDef(macro_def) => macro_def,
@@ -217,6 +220,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribu
                     } else {
                         unreachable!()
                     };
+
                     om.macros.push(Macro {
                         def_id: def_id,
                         attrs: def.attrs.clone().into(),
@@ -263,6 +267,8 @@ fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
             false
         }
 
+        debug!("maybe_inline_local def: {:?}", def);
+
         let tcx = self.cx.tcx;
         if def == Def::Err {
             return false;
@@ -274,6 +280,17 @@ fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
         let is_no_inline = use_attrs.lists("doc").has_word("no_inline") ||
                            use_attrs.lists("doc").has_word("hidden");
 
+        // Memoize the non-inlined `pub use`'d macros so we don't push an extra
+        // declaration in `visit_mod_contents()`
+        if !def_did.is_local() {
+            if let Def::Macro(did, _) = def {
+                if please_inline { return true }
+                debug!("memoizing non-inlined macro export: {:?}", def);
+                self.reexported_macros.insert(did);
+                return false;
+            }
+        }
+
         // For cross-crate impl inlining we need to know whether items are
         // reachable in documentation - a previously nonreachable item can be
         // made reachable by cross-crate inlining which we're checking here.
@@ -294,6 +311,7 @@ fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
                 },
                 _ => {},
             }
+
             return false
         }
 
@@ -355,6 +373,7 @@ pub fn visit_item(&mut self, item: &hir::Item,
             }
             // If we're inlining, skip private items.
             _ if self.inlining && item.vis != hir::Public => {}
+            hir::ItemGlobalAsm(..) => {}
             hir::ItemExternCrate(ref p) => {
                 let cstore = &self.cx.sess().cstore;
                 om.extern_crates.push(ExternCrate {