@@ -21,7 +21,7 @@ use syntax_pos::Span;
2121
2222use rustc:: hir:: map as hir_map;
2323use rustc:: hir:: def:: Def ;
24- use rustc:: hir:: def_id:: LOCAL_CRATE ;
24+ use rustc:: hir:: def_id:: { DefId , LOCAL_CRATE } ;
2525use rustc:: middle:: cstore:: LoadedMacro ;
2626use rustc:: middle:: privacy:: AccessLevel ;
2727use 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
5354impl < ' 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
0 commit comments