@@ -5,7 +5,7 @@ use crate::rmeta::*;
5
5
6
6
use rustc_ast:: Attribute ;
7
7
use rustc_data_structures:: fingerprint:: Fingerprint ;
8
- use rustc_data_structures:: fx:: { FxHashMap , FxIndexSet } ;
8
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexSet } ;
9
9
use rustc_data_structures:: memmap:: { Mmap , MmapMut } ;
10
10
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
11
11
use rustc_data_structures:: sync:: { join, par_iter, Lrc , ParallelIterator } ;
@@ -598,6 +598,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
598
598
599
599
let incoherent_impls = stat ! ( "incoherent-impls" , || self . encode_incoherent_impls( ) ) ;
600
600
601
+ let rustdoc_reachable = stat ! ( "rustdoc-reachable" , || self . encode_rustdoc_reachable( ) ) ;
602
+
601
603
_ = stat ! ( "mir" , || self . encode_mir( ) ) ;
602
604
603
605
_ = stat ! ( "items" , || {
@@ -698,6 +700,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
698
700
traits,
699
701
impls,
700
702
incoherent_impls,
703
+ rustdoc_reachable,
701
704
exported_symbols,
702
705
interpret_alloc_index,
703
706
tables,
@@ -1256,7 +1259,40 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
1256
1259
}
1257
1260
}
1258
1261
1259
- fn encode_info_for_mod ( & mut self , local_def_id : LocalDefId , md : & hir:: Mod < ' _ > ) {
1262
+ fn module_children (
1263
+ tcx : TyCtxt < ' tcx > ,
1264
+ md : & ' tcx hir:: Mod < ' tcx > ,
1265
+ ) -> impl Iterator < Item = DefIndex > + ' tcx {
1266
+ iter:: from_generator ( move || {
1267
+ for item_id in md. item_ids {
1268
+ match tcx. hir ( ) . item ( * item_id) . kind {
1269
+ // Foreign items are planted into their parent modules
1270
+ // from name resolution point of view.
1271
+ hir:: ItemKind :: ForeignMod { items, .. } => {
1272
+ for foreign_item in items {
1273
+ yield foreign_item. id . owner_id . def_id . local_def_index ;
1274
+ }
1275
+ }
1276
+ // Only encode named non-reexport children, reexports are encoded
1277
+ // separately and unnamed items are not used by name resolution.
1278
+ hir:: ItemKind :: ExternCrate ( ..) => continue ,
1279
+ hir:: ItemKind :: Struct ( ref vdata, _) => {
1280
+ yield item_id. owner_id . def_id . local_def_index ;
1281
+ // Encode constructors which take a separate slot in value namespace.
1282
+ if let Some ( ctor_hir_id) = vdata. ctor_hir_id ( ) {
1283
+ yield tcx. hir ( ) . local_def_id ( ctor_hir_id) . local_def_index ;
1284
+ }
1285
+ }
1286
+ _ if tcx. def_key ( item_id. owner_id . to_def_id ( ) ) . get_opt_name ( ) . is_some ( ) => {
1287
+ yield item_id. owner_id . def_id . local_def_index ;
1288
+ }
1289
+ _ => continue ,
1290
+ }
1291
+ }
1292
+ } )
1293
+ }
1294
+
1295
+ fn encode_info_for_mod ( & mut self , local_def_id : LocalDefId , md : & ' tcx hir:: Mod < ' tcx > ) {
1260
1296
let tcx = self . tcx ;
1261
1297
let def_id = local_def_id. to_def_id ( ) ;
1262
1298
debug ! ( "EncodeContext::encode_info_for_mod({:?})" , def_id) ;
@@ -1270,33 +1306,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
1270
1306
// Encode this here because we don't do it in encode_def_ids.
1271
1307
record ! ( self . tables. expn_that_defined[ def_id] <- tcx. expn_that_defined( local_def_id) ) ;
1272
1308
} else {
1273
- record_array ! ( self . tables. children[ def_id] <- iter:: from_generator( || {
1274
- for item_id in md. item_ids {
1275
- match tcx. hir( ) . item( * item_id) . kind {
1276
- // Foreign items are planted into their parent modules
1277
- // from name resolution point of view.
1278
- hir:: ItemKind :: ForeignMod { items, .. } => {
1279
- for foreign_item in items {
1280
- yield foreign_item. id. owner_id. def_id. local_def_index;
1281
- }
1282
- }
1283
- // Only encode named non-reexport children, reexports are encoded
1284
- // separately and unnamed items are not used by name resolution.
1285
- hir:: ItemKind :: ExternCrate ( ..) => continue ,
1286
- hir:: ItemKind :: Struct ( ref vdata, _) => {
1287
- yield item_id. owner_id. def_id. local_def_index;
1288
- // Encode constructors which take a separate slot in value namespace.
1289
- if let Some ( ctor_hir_id) = vdata. ctor_hir_id( ) {
1290
- yield tcx. hir( ) . local_def_id( ctor_hir_id) . local_def_index;
1291
- }
1292
- }
1293
- _ if tcx. def_key( item_id. owner_id. to_def_id( ) ) . get_opt_name( ) . is_some( ) => {
1294
- yield item_id. owner_id. def_id. local_def_index;
1295
- }
1296
- _ => continue ,
1297
- }
1298
- }
1299
- } ) ) ;
1309
+ record_array ! ( self . tables. children[ def_id] <- Self :: module_children( tcx, md) ) ;
1300
1310
1301
1311
if let Some ( reexports) = tcx. module_reexports ( local_def_id) {
1302
1312
assert ! ( !reexports. is_empty( ) ) ;
@@ -1974,6 +1984,74 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
1974
1984
self . lazy_array ( & all_impls)
1975
1985
}
1976
1986
1987
+ fn encode_rustdoc_reachable ( & mut self ) -> LazyArray < DefId > {
1988
+ struct LibEmbargoVisitor < ' tcx > {
1989
+ tcx : TyCtxt < ' tcx > ,
1990
+ extern_public : FxHashSet < DefId > ,
1991
+ visited_mods : FxHashSet < DefId > ,
1992
+ }
1993
+
1994
+ impl LibEmbargoVisitor < ' _ > {
1995
+ fn visit_mod ( & mut self , def_id : DefId ) {
1996
+ if !self . visited_mods . insert ( def_id) {
1997
+ return ;
1998
+ }
1999
+
2000
+ let tcx = self . tcx ;
2001
+ match def_id. as_local ( ) {
2002
+ Some ( def_id) => {
2003
+ let ( md, ..) = tcx. hir ( ) . get_module ( def_id) ;
2004
+ for local_def_index in EncodeContext :: module_children ( tcx, md) {
2005
+ let def_id = LocalDefId { local_def_index } . to_def_id ( ) ;
2006
+ if tcx. visibility ( def_id) . is_public ( ) {
2007
+ self . visit_item ( def_id) ;
2008
+ }
2009
+ }
2010
+ if let Some ( reexports) = tcx. module_reexports ( def_id) {
2011
+ for item in reexports {
2012
+ if let Some ( def_id) = item. res . opt_def_id ( ) {
2013
+ if item. vis . is_public ( ) {
2014
+ self . visit_item ( def_id) ;
2015
+ }
2016
+ }
2017
+ }
2018
+ }
2019
+ }
2020
+ None => {
2021
+ for item in tcx. module_children ( def_id) . iter ( ) {
2022
+ if let Some ( def_id) = item. res . opt_def_id ( ) {
2023
+ if item. vis . is_public ( ) {
2024
+ self . visit_item ( def_id) ;
2025
+ }
2026
+ }
2027
+ }
2028
+ }
2029
+ }
2030
+ }
2031
+
2032
+ fn visit_item ( & mut self , def_id : DefId ) {
2033
+ if !self . tcx . is_doc_hidden ( def_id) {
2034
+ self . extern_public . insert ( def_id) ;
2035
+ if self . tcx . def_kind ( def_id) == DefKind :: Mod {
2036
+ self . visit_mod ( def_id) ;
2037
+ }
2038
+ }
2039
+ }
2040
+ }
2041
+
2042
+ let mut visitor = LibEmbargoVisitor {
2043
+ tcx : self . tcx ,
2044
+ extern_public : Default :: default ( ) ,
2045
+ visited_mods : Default :: default ( ) ,
2046
+ } ;
2047
+ visitor. visit_item ( CRATE_DEF_ID . to_def_id ( ) ) ;
2048
+
2049
+ let mut rustdoc_reachable: Vec < _ > = visitor. extern_public . into_iter ( ) . collect ( ) ;
2050
+ rustdoc_reachable. sort_by_cached_key ( |& def_id| self . tcx . def_path_hash ( def_id) ) ;
2051
+
2052
+ self . lazy_array ( rustdoc_reachable)
2053
+ }
2054
+
1977
2055
// Encodes all symbols exported from this crate into the metadata.
1978
2056
//
1979
2057
// This pass is seeded off the reachability list calculated in the
0 commit comments