1
+ use std:: sync:: RwLock ;
2
+
3
+ use rustc_data_structures:: fx:: FxHashSet ;
1
4
use rustc_hir:: def:: DefKind ;
2
- use rustc_hir:: def_id:: { DefId , DefIdSet } ;
5
+ use rustc_hir:: def_id:: { CrateNum , DefId , DefIdSet } ;
3
6
use rustc_middle:: ty:: TyCtxt ;
4
7
5
8
use crate :: core:: DocContext ;
@@ -8,6 +11,13 @@ use crate::core::DocContext;
8
11
9
12
#[ derive( Default ) ]
10
13
pub ( crate ) struct RustdocEffectiveVisibilities {
14
+ inner : RwLock < VisInner > ,
15
+ pub ( crate ) document_hidden : bool ,
16
+ }
17
+
18
+ #[ derive( Default ) ]
19
+ struct VisInner {
20
+ visited : FxHashSet < CrateNum > ,
11
21
extern_public : DefIdSet ,
12
22
}
13
23
@@ -16,7 +26,18 @@ macro_rules! define_method {
16
26
pub ( crate ) fn $method( & self , tcx: TyCtxt <' _>, def_id: DefId ) -> bool {
17
27
match def_id. as_local( ) {
18
28
Some ( def_id) => tcx. effective_visibilities( ( ) ) . $method( def_id) ,
19
- None => self . extern_public. contains( & def_id) ,
29
+ None => {
30
+ let vis = self . inner. read( ) . unwrap( ) ;
31
+ if vis. visited. contains( & def_id. krate) {
32
+ vis. extern_public. contains( & def_id)
33
+ } else {
34
+ std:: mem:: drop( vis) ;
35
+ lib_embargo_visit_item_( & self , tcx, def_id. krate. as_def_id( ) ) ;
36
+ let mut vis = self . inner. write( ) . unwrap( ) ;
37
+ vis. visited. insert( def_id. krate) ;
38
+ vis. extern_public. contains( & def_id)
39
+ }
40
+ }
20
41
}
21
42
}
22
43
} ;
@@ -28,17 +49,26 @@ impl RustdocEffectiveVisibilities {
28
49
define_method ! ( is_reachable) ;
29
50
}
30
51
31
- pub ( crate ) fn lib_embargo_visit_item ( cx : & mut DocContext < ' _ > , def_id : DefId ) {
52
+ pub ( crate ) fn lib_embargo_visit_item_ (
53
+ vis : & RustdocEffectiveVisibilities ,
54
+ tcx : TyCtxt < ' _ > ,
55
+ def_id : DefId ,
56
+ ) {
32
57
assert ! ( !def_id. is_local( ) ) ;
33
58
LibEmbargoVisitor {
34
- tcx : cx . tcx ,
35
- extern_public : & mut cx . cache . effective_visibilities . extern_public ,
59
+ tcx,
60
+ extern_public : & mut vis . inner . write ( ) . unwrap ( ) . extern_public ,
36
61
visited_mods : Default :: default ( ) ,
37
- document_hidden : cx . render_options . document_hidden ,
62
+ document_hidden : vis . document_hidden ,
38
63
}
39
64
. visit_item ( def_id)
40
65
}
41
66
67
+ pub ( crate ) fn lib_embargo_visit_item ( cx : & mut DocContext < ' _ > , def_id : DefId ) {
68
+ assert_eq ! ( cx. cache. effective_visibilities. document_hidden, cx. render_options. document_hidden) ;
69
+ lib_embargo_visit_item_ ( & cx. cache . effective_visibilities , cx. tcx , def_id)
70
+ }
71
+
42
72
/// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
43
73
/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
44
74
struct LibEmbargoVisitor < ' a , ' tcx > {
0 commit comments