@@ -21,7 +21,7 @@ use syntax_pos::Span;
21
21
22
22
use rustc:: hir:: map as hir_map;
23
23
use rustc:: hir:: def:: Def ;
24
- use rustc:: hir:: def_id:: LOCAL_CRATE ;
24
+ use rustc:: hir:: def_id:: { DefId , LOCAL_CRATE } ;
25
25
use rustc:: middle:: cstore:: LoadedMacro ;
26
26
use rustc:: middle:: privacy:: AccessLevel ;
27
27
use rustc:: util:: nodemap:: FxHashSet ;
@@ -48,6 +48,7 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> {
48
48
inlining : bool ,
49
49
/// Is the current module and all of its parents public?
50
50
inside_public_path : bool ,
51
+ reexported_macros : FxHashSet < DefId > ,
51
52
}
52
53
53
54
impl < ' a , ' tcx > RustdocVisitor < ' a , ' tcx > {
@@ -62,6 +63,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
62
63
view_item_stack : stack,
63
64
inlining : false ,
64
65
inside_public_path : true ,
66
+ reexported_macros : FxHashSet ( ) ,
65
67
}
66
68
}
67
69
@@ -201,9 +203,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
201
203
if let Some ( exports) = self . cx . tcx . export_map . get ( & id) {
202
204
for export in exports {
203
205
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 ) {
205
207
continue // These are `krate.exported_macros`, handled in `self.visit()`.
206
208
}
209
+
207
210
let imported_from = self . cx . sess ( ) . cstore . original_crate_name ( def_id. krate ) ;
208
211
let def = match self . cx . sess ( ) . cstore . load_macro ( def_id, self . cx . sess ( ) ) {
209
212
LoadedMacro :: MacroDef ( macro_def) => macro_def,
@@ -217,6 +220,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
217
220
} else {
218
221
unreachable ! ( )
219
222
} ;
223
+
220
224
om. macros . push ( Macro {
221
225
def_id : def_id,
222
226
attrs : def. attrs . clone ( ) . into ( ) ,
@@ -263,6 +267,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
263
267
false
264
268
}
265
269
270
+ debug ! ( "maybe_inline_local def: {:?}" , def) ;
271
+
266
272
let tcx = self . cx . tcx ;
267
273
if def == Def :: Err {
268
274
return false ;
@@ -274,6 +280,17 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
274
280
let is_no_inline = use_attrs. lists ( "doc" ) . has_word ( "no_inline" ) ||
275
281
use_attrs. lists ( "doc" ) . has_word ( "hidden" ) ;
276
282
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
+
277
294
// For cross-crate impl inlining we need to know whether items are
278
295
// reachable in documentation - a previously nonreachable item can be
279
296
// made reachable by cross-crate inlining which we're checking here.
@@ -294,6 +311,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
294
311
} ,
295
312
_ => { } ,
296
313
}
314
+
297
315
return false
298
316
}
299
317
0 commit comments