@@ -1596,6 +1596,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15961596 let table = tcx. associated_types_for_impl_traits_in_associated_fn ( def_id) ;
15971597 record_defaulted_array ! ( self . tables. associated_types_for_impl_traits_in_associated_fn[ def_id] <- table) ;
15981598 }
1599+ if let DefKind :: Mod = tcx. def_kind ( def_id) {
1600+ record ! ( self . tables. doc_link_resolutions[ def_id] <- tcx. doc_link_resolutions( def_id) ) ;
1601+ record_array ! ( self . tables. doc_link_traits_in_scope[ def_id] <- tcx. doc_link_traits_in_scope( def_id) ) ;
1602+ }
15991603 }
16001604
16011605 for ( def_id, impls) in & tcx. crate_inherent_impls ( ( ) ) . 0 . inherent_impls {
@@ -1604,14 +1608,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
16041608 def_id. index
16051609 } ) ) ;
16061610 }
1607-
1608- for ( def_id, res_map) in & tcx. resolutions ( ( ) ) . doc_link_resolutions {
1609- record ! ( self . tables. doc_link_resolutions[ def_id. to_def_id( ) ] <- res_map) ;
1610- }
1611-
1612- for ( def_id, traits) in & tcx. resolutions ( ( ) ) . doc_link_traits_in_scope {
1613- record_array ! ( self . tables. doc_link_traits_in_scope[ def_id. to_def_id( ) ] <- traits) ;
1614- }
16151611 }
16161612
16171613 #[ instrument( level = "trace" , skip( self ) ) ]
@@ -2283,6 +2279,8 @@ pub struct EncodedMetadata {
22832279 // This is an optional stub metadata containing only the crate header.
22842280 // The header should be very small, so we load it directly into memory.
22852281 stub_metadata : Option < Vec < u8 > > ,
2282+ // The path containing the metadata, to record as work product.
2283+ path : Option < Box < Path > > ,
22862284 // We need to carry MaybeTempDir to avoid deleting the temporary
22872285 // directory while accessing the Mmap.
22882286 _temp_dir : Option < MaybeTempDir > ,
@@ -2298,14 +2296,24 @@ impl EncodedMetadata {
22982296 let file = std:: fs:: File :: open ( & path) ?;
22992297 let file_metadata = file. metadata ( ) ?;
23002298 if file_metadata. len ( ) == 0 {
2301- return Ok ( Self { full_metadata : None , stub_metadata : None , _temp_dir : None } ) ;
2299+ return Ok ( Self {
2300+ full_metadata : None ,
2301+ stub_metadata : None ,
2302+ path : None ,
2303+ _temp_dir : None ,
2304+ } ) ;
23022305 }
23032306 let full_mmap = unsafe { Some ( Mmap :: map ( file) ?) } ;
23042307
23052308 let stub =
23062309 if let Some ( stub_path) = stub_path { Some ( std:: fs:: read ( stub_path) ?) } else { None } ;
23072310
2308- Ok ( Self { full_metadata : full_mmap, stub_metadata : stub, _temp_dir : temp_dir } )
2311+ Ok ( Self {
2312+ full_metadata : full_mmap,
2313+ stub_metadata : stub,
2314+ path : Some ( path. into ( ) ) ,
2315+ _temp_dir : temp_dir,
2316+ } )
23092317 }
23102318
23112319 #[ inline]
@@ -2317,6 +2325,11 @@ impl EncodedMetadata {
23172325 pub fn stub_or_full ( & self ) -> & [ u8 ] {
23182326 self . stub_metadata . as_deref ( ) . unwrap_or ( self . full ( ) )
23192327 }
2328+
2329+ #[ inline]
2330+ pub fn path ( & self ) -> Option < & Path > {
2331+ self . path . as_deref ( )
2332+ }
23202333}
23212334
23222335impl < S : Encoder > Encodable < S > for EncodedMetadata {
@@ -2341,11 +2354,47 @@ impl<D: Decoder> Decodable<D> for EncodedMetadata {
23412354 None
23422355 } ;
23432356
2344- Self { full_metadata, stub_metadata : stub, _temp_dir : None }
2357+ Self { full_metadata, stub_metadata : stub, path : None , _temp_dir : None }
23452358 }
23462359}
23472360
2361+ #[ instrument( level = "trace" , skip( tcx) ) ]
23482362pub fn encode_metadata ( tcx : TyCtxt < ' _ > , path : & Path , ref_path : Option < & Path > ) {
2363+ if let Some ( ref_path) = ref_path {
2364+ let _prof_timer = tcx. prof . verbose_generic_activity ( "generate_crate_metadata_stub" ) ;
2365+
2366+ with_encode_metadata_header ( tcx, ref_path, |ecx| {
2367+ let header: LazyValue < CrateHeader > = ecx. lazy ( CrateHeader {
2368+ name : tcx. crate_name ( LOCAL_CRATE ) ,
2369+ triple : tcx. sess . opts . target_triple . clone ( ) ,
2370+ hash : tcx. crate_hash ( LOCAL_CRATE ) ,
2371+ is_proc_macro_crate : false ,
2372+ is_stub : true ,
2373+ } ) ;
2374+ header. position . get ( )
2375+ } ) ;
2376+ }
2377+
2378+ let dep_node = tcx. metadata_dep_node ( ) ;
2379+
2380+ if tcx. dep_graph . is_fully_enabled ( )
2381+ && let work_product_id = & rustc_middle:: dep_graph:: WorkProductId :: from_cgu_name ( "metadata" )
2382+ && let Some ( work_product) = tcx. dep_graph . previous_work_product ( work_product_id)
2383+ && tcx. try_mark_green ( & dep_node)
2384+ {
2385+ let saved_path = & work_product. saved_files [ "rmeta" ] ;
2386+ let incr_comp_session_dir = tcx. sess . incr_comp_session_dir_opt ( ) . unwrap ( ) ;
2387+ let source_file = rustc_incremental:: in_incr_comp_dir ( & incr_comp_session_dir, saved_path) ;
2388+ debug ! ( "copying preexisting metadata from {source_file:?} to {path:?}" ) ;
2389+ match rustc_fs_util:: link_or_copy ( & source_file, path) {
2390+ Ok ( _) => { }
2391+ Err ( err) => {
2392+ tcx. dcx ( ) . emit_fatal ( FailCreateFileEncoder { err } ) ;
2393+ }
2394+ } ;
2395+ return ;
2396+ } ;
2397+
23492398 let _prof_timer = tcx. prof . verbose_generic_activity ( "generate_crate_metadata" ) ;
23502399
23512400 // Since encoding metadata is not in a query, and nothing is cached,
@@ -2359,35 +2408,30 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
23592408 join ( || prefetch_mir ( tcx) , || tcx. exported_symbols ( LOCAL_CRATE ) ) ;
23602409 }
23612410
2362- with_encode_metadata_header ( tcx, path, |ecx| {
2363- // Encode all the entries and extra information in the crate,
2364- // culminating in the `CrateRoot` which points to all of it.
2365- let root = ecx. encode_crate_root ( ) ;
2366-
2367- // Flush buffer to ensure backing file has the correct size.
2368- ecx. opaque . flush ( ) ;
2369- // Record metadata size for self-profiling
2370- tcx. prof . artifact_size (
2371- "crate_metadata" ,
2372- "crate_metadata" ,
2373- ecx. opaque . file ( ) . metadata ( ) . unwrap ( ) . len ( ) ,
2374- ) ;
2375-
2376- root. position . get ( )
2377- } ) ;
2411+ tcx. dep_graph . with_task (
2412+ dep_node,
2413+ tcx,
2414+ path,
2415+ |tcx, path| {
2416+ with_encode_metadata_header ( tcx, path, |ecx| {
2417+ // Encode all the entries and extra information in the crate,
2418+ // culminating in the `CrateRoot` which points to all of it.
2419+ let root = ecx. encode_crate_root ( ) ;
2420+
2421+ // Flush buffer to ensure backing file has the correct size.
2422+ ecx. opaque . flush ( ) ;
2423+ // Record metadata size for self-profiling
2424+ tcx. prof . artifact_size (
2425+ "crate_metadata" ,
2426+ "crate_metadata" ,
2427+ ecx. opaque . file ( ) . metadata ( ) . unwrap ( ) . len ( ) ,
2428+ ) ;
23782429
2379- if let Some ( ref_path) = ref_path {
2380- with_encode_metadata_header ( tcx, ref_path, |ecx| {
2381- let header: LazyValue < CrateHeader > = ecx. lazy ( CrateHeader {
2382- name : tcx. crate_name ( LOCAL_CRATE ) ,
2383- triple : tcx. sess . opts . target_triple . clone ( ) ,
2384- hash : tcx. crate_hash ( LOCAL_CRATE ) ,
2385- is_proc_macro_crate : false ,
2386- is_stub : true ,
2430+ root. position . get ( )
23872431 } ) ;
2388- header . position . get ( )
2389- } ) ;
2390- }
2432+ } ,
2433+ None ,
2434+ ) ;
23912435}
23922436
23932437fn with_encode_metadata_header (
0 commit comments