@@ -8,7 +8,6 @@ use rustc_hir::def_id::DefId;
8
8
use rustc_hir:: intravisit:: { walk_item, Visitor } ;
9
9
use rustc_hir:: Node ;
10
10
use rustc_hir:: CRATE_HIR_ID ;
11
- use rustc_middle:: hir:: map:: Map ;
12
11
use rustc_middle:: hir:: nested_filter;
13
12
use rustc_middle:: ty:: TyCtxt ;
14
13
use rustc_span:: def_id:: { CRATE_DEF_ID , LOCAL_CRATE } ;
@@ -68,7 +67,6 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
68
67
inside_public_path : bool ,
69
68
exact_paths : FxHashMap < DefId , Vec < Symbol > > ,
70
69
modules : Vec < Module < ' tcx > > ,
71
- map : Map < ' tcx > ,
72
70
}
73
71
74
72
impl < ' a , ' tcx > RustdocVisitor < ' a , ' tcx > {
@@ -81,7 +79,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
81
79
hir:: CRATE_HIR_ID ,
82
80
cx. tcx . hir ( ) . root_module ( ) . spans . inner_span ,
83
81
) ;
84
- let map = cx. tcx . hir ( ) ;
85
82
86
83
RustdocVisitor {
87
84
cx,
@@ -90,7 +87,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
90
87
inside_public_path : true ,
91
88
exact_paths : FxHashMap :: default ( ) ,
92
89
modules : vec ! [ om] ,
93
- map,
94
90
}
95
91
}
96
92
@@ -99,6 +95,95 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
99
95
self . exact_paths . entry ( did) . or_insert_with ( || def_id_to_path ( tcx, did) ) ;
100
96
}
101
97
98
+ pub ( crate ) fn visit ( mut self ) -> Module < ' tcx > {
99
+ let root_module = self . cx . tcx . hir ( ) . root_module ( ) ;
100
+ self . visit_mod_contents ( CRATE_HIR_ID , root_module) ;
101
+
102
+ let mut top_level_module = self . modules . pop ( ) . unwrap ( ) ;
103
+
104
+ // `#[macro_export] macro_rules!` items are reexported at the top level of the
105
+ // crate, regardless of where they're defined. We want to document the
106
+ // top level rexport of the macro, not its original definition, since
107
+ // the rexport defines the path that a user will actually see. Accordingly,
108
+ // we add the rexport as an item here, and then skip over the original
109
+ // definition in `visit_item()` below.
110
+ //
111
+ // We also skip `#[macro_export] macro_rules!` that have already been inserted,
112
+ // it can happen if within the same module a `#[macro_export] macro_rules!`
113
+ // is declared but also a reexport of itself producing two exports of the same
114
+ // macro in the same module.
115
+ let mut inserted = FxHashSet :: default ( ) ;
116
+ for export in self . cx . tcx . module_reexports ( CRATE_DEF_ID ) . unwrap_or ( & [ ] ) {
117
+ if let Res :: Def ( DefKind :: Macro ( _) , def_id) = export. res &&
118
+ let Some ( local_def_id) = def_id. as_local ( ) &&
119
+ self . cx . tcx . has_attr ( def_id, sym:: macro_export) &&
120
+ inserted. insert ( def_id)
121
+ {
122
+ let item = self . cx . tcx . hir ( ) . expect_item ( local_def_id) ;
123
+ top_level_module. items . push ( ( item, None , None ) ) ;
124
+ }
125
+ }
126
+
127
+ self . cx . cache . hidden_cfg = self
128
+ . cx
129
+ . tcx
130
+ . hir ( )
131
+ . attrs ( CRATE_HIR_ID )
132
+ . iter ( )
133
+ . filter ( |attr| attr. has_name ( sym:: doc) )
134
+ . flat_map ( |attr| attr. meta_item_list ( ) . into_iter ( ) . flatten ( ) )
135
+ . filter ( |attr| attr. has_name ( sym:: cfg_hide) )
136
+ . flat_map ( |attr| {
137
+ attr. meta_item_list ( )
138
+ . unwrap_or ( & [ ] )
139
+ . iter ( )
140
+ . filter_map ( |attr| {
141
+ Cfg :: parse ( attr. meta_item ( ) ?)
142
+ . map_err ( |e| self . cx . sess ( ) . diagnostic ( ) . span_err ( e. span , e. msg ) )
143
+ . ok ( )
144
+ } )
145
+ . collect :: < Vec < _ > > ( )
146
+ } )
147
+ . chain (
148
+ [ Cfg :: Cfg ( sym:: test, None ) , Cfg :: Cfg ( sym:: doc, None ) , Cfg :: Cfg ( sym:: doctest, None ) ]
149
+ . into_iter ( ) ,
150
+ )
151
+ . collect ( ) ;
152
+
153
+ self . cx . cache . exact_paths = self . exact_paths ;
154
+ top_level_module
155
+ }
156
+
157
+ /// This method will go through the given module items in two passes:
158
+ /// 1. The items which are not glob imports/reexports.
159
+ /// 2. The glob imports/reexports.
160
+ fn visit_mod_contents ( & mut self , id : hir:: HirId , m : & ' tcx hir:: Mod < ' tcx > ) {
161
+ debug ! ( "Going through module {:?}" , m) ;
162
+ let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) . to_def_id ( ) ;
163
+ // Keep track of if there were any private modules in the path.
164
+ let orig_inside_public_path = self . inside_public_path ;
165
+ self . inside_public_path &= self . cx . tcx . visibility ( def_id) . is_public ( ) ;
166
+
167
+ // Reimplementation of `walk_mod` because we need to do it in two passes (explanations in
168
+ // the second loop):
169
+ for & i in m. item_ids {
170
+ let item = self . cx . tcx . hir ( ) . item ( i) ;
171
+ if !matches ! ( item. kind, hir:: ItemKind :: Use ( _, hir:: UseKind :: Glob ) ) {
172
+ self . visit_item ( item) ;
173
+ }
174
+ }
175
+ for & i in m. item_ids {
176
+ let item = self . cx . tcx . hir ( ) . item ( i) ;
177
+ // To match the way import precedence works, visit glob imports last.
178
+ // Later passes in rustdoc will de-duplicate by name and kind, so if glob-
179
+ // imported items appear last, then they'll be the ones that get discarded.
180
+ if matches ! ( item. kind, hir:: ItemKind :: Use ( _, hir:: UseKind :: Glob ) ) {
181
+ self . visit_item ( item) ;
182
+ }
183
+ }
184
+ self . inside_public_path = orig_inside_public_path;
185
+ }
186
+
102
187
/// Tries to resolve the target of a `pub use` statement and inlines the
103
188
/// target if it is defined locally and would not be documented otherwise,
104
189
/// or when it is specifically requested with `please_inline`.
@@ -323,65 +408,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
323
408
}
324
409
}
325
410
326
- pub ( crate ) fn visit ( mut self ) -> Module < ' tcx > {
327
- let root_module = self . cx . tcx . hir ( ) . root_module ( ) ;
328
- self . visit_mod_contents ( CRATE_HIR_ID , root_module) ;
329
-
330
- let mut top_level_module = self . modules . pop ( ) . unwrap ( ) ;
331
-
332
- // `#[macro_export] macro_rules!` items are reexported at the top level of the
333
- // crate, regardless of where they're defined. We want to document the
334
- // top level rexport of the macro, not its original definition, since
335
- // the rexport defines the path that a user will actually see. Accordingly,
336
- // we add the rexport as an item here, and then skip over the original
337
- // definition in `visit_item()` below.
338
- //
339
- // We also skip `#[macro_export] macro_rules!` that have already been inserted,
340
- // it can happen if within the same module a `#[macro_export] macro_rules!`
341
- // is declared but also a reexport of itself producing two exports of the same
342
- // macro in the same module.
343
- let mut inserted = FxHashSet :: default ( ) ;
344
- for export in self . cx . tcx . module_reexports ( CRATE_DEF_ID ) . unwrap_or ( & [ ] ) {
345
- if let Res :: Def ( DefKind :: Macro ( _) , def_id) = export. res &&
346
- let Some ( local_def_id) = def_id. as_local ( ) &&
347
- self . cx . tcx . has_attr ( def_id, sym:: macro_export) &&
348
- inserted. insert ( def_id)
349
- {
350
- let item = self . cx . tcx . hir ( ) . expect_item ( local_def_id) ;
351
- top_level_module. items . push ( ( item, None , None ) ) ;
352
- }
353
- }
354
-
355
- self . cx . cache . hidden_cfg = self
356
- . cx
357
- . tcx
358
- . hir ( )
359
- . attrs ( CRATE_HIR_ID )
360
- . iter ( )
361
- . filter ( |attr| attr. has_name ( sym:: doc) )
362
- . flat_map ( |attr| attr. meta_item_list ( ) . into_iter ( ) . flatten ( ) )
363
- . filter ( |attr| attr. has_name ( sym:: cfg_hide) )
364
- . flat_map ( |attr| {
365
- attr. meta_item_list ( )
366
- . unwrap_or ( & [ ] )
367
- . iter ( )
368
- . filter_map ( |attr| {
369
- Cfg :: parse ( attr. meta_item ( ) ?)
370
- . map_err ( |e| self . cx . sess ( ) . diagnostic ( ) . span_err ( e. span , e. msg ) )
371
- . ok ( )
372
- } )
373
- . collect :: < Vec < _ > > ( )
374
- } )
375
- . chain (
376
- [ Cfg :: Cfg ( sym:: test, None ) , Cfg :: Cfg ( sym:: doc, None ) , Cfg :: Cfg ( sym:: doctest, None ) ]
377
- . into_iter ( ) ,
378
- )
379
- . collect ( ) ;
380
-
381
- self . cx . cache . exact_paths = self . exact_paths ;
382
- top_level_module
383
- }
384
-
385
411
/// This method will create a new module and push it onto the "modules stack" then call
386
412
/// `visit_mod_contents`. Once done, it'll remove it from the "modules stack" and instead
387
413
/// add into into the list of modules of the current module.
@@ -393,35 +419,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
393
419
let last = self . modules . pop ( ) . unwrap ( ) ;
394
420
self . modules . last_mut ( ) . unwrap ( ) . mods . push ( last) ;
395
421
}
396
-
397
- /// This method will go through the given module items in two passes:
398
- /// 1. The items which are not glob imports/reexports.
399
- /// 2. The glob imports/reexports.
400
- fn visit_mod_contents ( & mut self , id : hir:: HirId , m : & ' tcx hir:: Mod < ' tcx > ) {
401
- debug ! ( "Going through module {:?}" , m) ;
402
- let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) . to_def_id ( ) ;
403
- // Keep track of if there were any private modules in the path.
404
- let orig_inside_public_path = self . inside_public_path ;
405
- self . inside_public_path &= self . cx . tcx . visibility ( def_id) . is_public ( ) ;
406
-
407
- // Reimplementation of `walk_mod`:
408
- for & i in m. item_ids {
409
- let item = self . cx . tcx . hir ( ) . item ( i) ;
410
- if !matches ! ( item. kind, hir:: ItemKind :: Use ( _, hir:: UseKind :: Glob ) ) {
411
- self . visit_item ( item) ;
412
- }
413
- }
414
- for & i in m. item_ids {
415
- let item = self . cx . tcx . hir ( ) . item ( i) ;
416
- // To match the way import precedence works, visit glob imports last.
417
- // Later passes in rustdoc will de-duplicate by name and kind, so if glob-
418
- // imported items appear last, then they'll be the ones that get discarded.
419
- if matches ! ( item. kind, hir:: ItemKind :: Use ( _, hir:: UseKind :: Glob ) ) {
420
- self . visit_item ( item) ;
421
- }
422
- }
423
- self . inside_public_path = orig_inside_public_path;
424
- }
425
422
}
426
423
427
424
// We need to implement this visitor so it'll go everywhere and retrieve items we're interested in
@@ -430,7 +427,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
430
427
type NestedFilter = nested_filter:: All ;
431
428
432
429
fn nested_visit_map ( & mut self ) -> Self :: Map {
433
- self . map
430
+ self . cx . tcx . hir ( )
434
431
}
435
432
436
433
fn visit_item ( & mut self , i : & ' tcx hir:: Item < ' tcx > ) {
0 commit comments