1+ use std:: sync:: RwLock ;
2+
3+ use rustc_data_structures:: fx:: FxHashSet ;
14use rustc_hir:: def:: DefKind ;
2- use rustc_hir:: def_id:: { DefId , DefIdSet } ;
5+ use rustc_hir:: def_id:: { CrateNum , DefId , DefIdSet } ;
36use rustc_middle:: ty:: TyCtxt ;
47
58use crate :: core:: DocContext ;
@@ -8,6 +11,13 @@ use crate::core::DocContext;
811
912#[ derive( Default ) ]
1013pub ( 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 > ,
1121 extern_public : DefIdSet ,
1222}
1323
@@ -16,7 +26,18 @@ macro_rules! define_method {
1626 pub ( crate ) fn $method( & self , tcx: TyCtxt <' _>, def_id: DefId ) -> bool {
1727 match def_id. as_local( ) {
1828 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+ }
2041 }
2142 }
2243 } ;
@@ -28,17 +49,26 @@ impl RustdocEffectiveVisibilities {
2849 define_method ! ( is_reachable) ;
2950}
3051
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+ ) {
3257 assert ! ( !def_id. is_local( ) ) ;
3358 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 ,
3661 visited_mods : Default :: default ( ) ,
37- document_hidden : cx . render_options . document_hidden ,
62+ document_hidden : vis . document_hidden ,
3863 }
3964 . visit_item ( def_id)
4065}
4166
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+
4272/// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
4373/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
4474struct LibEmbargoVisitor < ' a , ' tcx > {
0 commit comments