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