1
1
use crate :: core:: DocContext ;
2
- use rustc_hir:: def:: DefKind ;
2
+ use rustc_hir:: def:: { DefKind , Res } ;
3
3
use rustc_hir:: def_id:: { DefId , DefIdSet } ;
4
4
use rustc_middle:: ty:: TyCtxt ;
5
+ use rustc_resolve:: Resolver ;
5
6
6
7
// FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
7
8
@@ -25,6 +26,10 @@ impl RustdocEffectiveVisibilities {
25
26
define_method ! ( is_directly_public) ;
26
27
define_method ! ( is_exported) ;
27
28
define_method ! ( is_reachable) ;
29
+
30
+ pub ( crate ) fn init ( & mut self , extern_public : DefIdSet ) {
31
+ self . extern_public = extern_public;
32
+ }
28
33
}
29
34
30
35
pub ( crate ) fn lib_embargo_visit_item ( cx : & mut DocContext < ' _ > , def_id : DefId ) {
@@ -37,6 +42,17 @@ pub(crate) fn lib_embargo_visit_item(cx: &mut DocContext<'_>, def_id: DefId) {
37
42
. visit_item ( def_id)
38
43
}
39
44
45
+ pub ( crate ) fn early_lib_embargo_visit_item (
46
+ resolver : & Resolver < ' _ > ,
47
+ extern_public : & mut DefIdSet ,
48
+ def_id : DefId ,
49
+ is_mod : bool ,
50
+ ) {
51
+ assert ! ( !def_id. is_local( ) ) ;
52
+ EarlyLibEmbargoVisitor { resolver, extern_public, visited_mods : Default :: default ( ) }
53
+ . visit_item ( def_id, is_mod)
54
+ }
55
+
40
56
/// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
41
57
/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
42
58
struct LibEmbargoVisitor < ' a , ' tcx > {
@@ -47,6 +63,14 @@ struct LibEmbargoVisitor<'a, 'tcx> {
47
63
visited_mods : DefIdSet ,
48
64
}
49
65
66
+ struct EarlyLibEmbargoVisitor < ' r , ' ra > {
67
+ resolver : & ' r Resolver < ' ra > ,
68
+ // Effective visibilities for reachable nodes
69
+ extern_public : & ' r mut DefIdSet ,
70
+ // Keeps track of already visited modules, in case a module re-exports its parent
71
+ visited_mods : DefIdSet ,
72
+ }
73
+
50
74
impl LibEmbargoVisitor < ' _ , ' _ > {
51
75
fn visit_mod ( & mut self , def_id : DefId ) {
52
76
if !self . visited_mods . insert ( def_id) {
@@ -71,3 +95,28 @@ impl LibEmbargoVisitor<'_, '_> {
71
95
}
72
96
}
73
97
}
98
+
99
+ impl EarlyLibEmbargoVisitor < ' _ , ' _ > {
100
+ fn visit_mod ( & mut self , def_id : DefId ) {
101
+ if !self . visited_mods . insert ( def_id) {
102
+ return ;
103
+ }
104
+
105
+ for item in self . resolver . cstore ( ) . module_children_untracked ( def_id, self . resolver . sess ( ) ) {
106
+ if let Some ( def_id) = item. res . opt_def_id ( ) {
107
+ if item. vis . is_public ( ) {
108
+ self . visit_item ( def_id, matches ! ( item. res, Res :: Def ( DefKind :: Mod , _) ) ) ;
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ fn visit_item ( & mut self , def_id : DefId , is_mod : bool ) {
115
+ if !self . resolver . cstore ( ) . is_doc_hidden_untracked ( def_id) {
116
+ self . extern_public . insert ( def_id) ;
117
+ if is_mod {
118
+ self . visit_mod ( def_id) ;
119
+ }
120
+ }
121
+ }
122
+ }
0 commit comments