11// Decoding metadata from a single crate's metadata
22
3- use crate :: cstore:: CrateMetadata ;
43use crate :: rmeta:: * ;
54use crate :: rmeta:: table:: { FixedSizeEncoding , PerDefTable } ;
65
76use rustc_index:: vec:: IndexVec ;
8- use rustc_data_structures:: sync:: Lrc ;
7+ use rustc_data_structures:: sync:: { Lrc , Lock , Once , AtomicCell } ;
98use rustc:: hir:: map:: { DefKey , DefPath , DefPathData , DefPathHash } ;
9+ use rustc:: hir:: map:: definitions:: DefPathTable ;
1010use rustc:: hir;
11+ use rustc:: middle:: cstore:: { CrateSource , ExternCrate } ;
1112use rustc:: middle:: cstore:: { LinkagePreference , NativeLibrary , ForeignModule } ;
1213use rustc:: middle:: exported_symbols:: { ExportedSymbol , SymbolExportLevel } ;
1314use rustc:: hir:: def:: { self , Res , DefKind , CtorOf , CtorKind } ;
1415use rustc:: hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , CRATE_DEF_INDEX , LOCAL_CRATE } ;
1516use rustc_data_structures:: fingerprint:: Fingerprint ;
1617use rustc_data_structures:: fx:: FxHashMap ;
17- use rustc:: dep_graph:: { DepNodeIndex , DepKind } ;
18+ use rustc_data_structures:: svh:: Svh ;
19+ use rustc:: dep_graph:: { self , DepNodeIndex } ;
1820use rustc:: middle:: lang_items;
1921use rustc:: mir:: { self , interpret} ;
20- use rustc:: mir:: interpret:: AllocDecodingSession ;
22+ use rustc:: mir:: interpret:: { AllocDecodingSession , AllocDecodingState } ;
2123use rustc:: session:: Session ;
2224use rustc:: ty:: { self , Ty , TyCtxt } ;
2325use rustc:: ty:: codec:: TyDecoder ;
2426use rustc:: mir:: { Body , Promoted } ;
27+ use rustc:: util:: common:: record_time;
2528use rustc:: util:: captures:: Captures ;
2629
2730use std:: io;
@@ -46,9 +49,75 @@ mod cstore_impl;
4649
4750crate struct MetadataBlob ( MetadataRef ) ;
4851
52+ // A map from external crate numbers (as decoded from some crate file) to
53+ // local crate numbers (as generated during this session). Each external
54+ // crate may refer to types in other external crates, and each has their
55+ // own crate numbers.
56+ crate type CrateNumMap = IndexVec < CrateNum , CrateNum > ;
57+
58+ crate struct CrateMetadata {
59+ /// The primary crate data - binary metadata blob.
60+ blob : MetadataBlob ,
61+
62+ // --- Some data pre-decoded from the metadata blob, usually for performance ---
63+
64+ /// Properties of the whole crate.
65+ /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
66+ /// lifetime is only used behind `Lazy`, and therefore acts like an
67+ /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
68+ /// is being used to decode those values.
69+ crate root : CrateRoot < ' static > ,
70+ /// For each definition in this crate, we encode a key. When the
71+ /// crate is loaded, we read all the keys and put them in this
72+ /// hashmap, which gives the reverse mapping. This allows us to
73+ /// quickly retrace a `DefPath`, which is needed for incremental
74+ /// compilation support.
75+ def_path_table : DefPathTable ,
76+ /// Trait impl data.
77+ /// FIXME: Used only from queries and can use query cache,
78+ /// so pre-decoding can probably be avoided.
79+ trait_impls : FxHashMap < ( u32 , DefIndex ) , Lazy < [ DefIndex ] > > ,
80+ /// Proc macro descriptions for this crate, if it's a proc macro crate.
81+ raw_proc_macros : Option < & ' static [ ProcMacro ] > ,
82+ /// Source maps for code from the crate.
83+ source_map_import_info : Once < Vec < ImportedSourceFile > > ,
84+ /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
85+ alloc_decoding_state : AllocDecodingState ,
86+ /// The `DepNodeIndex` of the `DepNode` representing this upstream crate.
87+ /// It is initialized on the first access in `get_crate_dep_node_index()`.
88+ /// Do not access the value directly, as it might not have been initialized yet.
89+ /// The field must always be initialized to `DepNodeIndex::INVALID`.
90+ dep_node_index : AtomicCell < DepNodeIndex > ,
91+
92+ // --- Other significant crate properties ---
93+
94+ /// ID of this crate, from the current compilation session's point of view.
95+ cnum : CrateNum ,
96+ /// Maps crate IDs as they are were seen from this crate's compilation sessions into
97+ /// IDs as they are seen from the current compilation session.
98+ cnum_map : CrateNumMap ,
99+ /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
100+ crate dependencies : Lock < Vec < CrateNum > > ,
101+ /// How to link (or not link) this crate to the currently compiled crate.
102+ crate dep_kind : Lock < DepKind > ,
103+ /// Filesystem location of this crate.
104+ crate source : CrateSource ,
105+ /// Whether or not this crate should be consider a private dependency
106+ /// for purposes of the 'exported_private_dependencies' lint
107+ private_dep : bool ,
108+ /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
109+ host_hash : Option < Svh > ,
110+
111+ // --- Data used only for improving diagnostics ---
112+
113+ /// Information about the `extern crate` item or path that caused this crate to be loaded.
114+ /// If this is `None`, then the crate was injected (e.g., by the allocator).
115+ crate extern_crate : Lock < Option < ExternCrate > > ,
116+ }
117+
49118/// Holds information about a syntax_pos::SourceFile imported from another crate.
50119/// See `imported_source_files()` for more information.
51- crate struct ImportedSourceFile {
120+ struct ImportedSourceFile {
52121 /// This SourceFile's byte-offset within the source_map of its original crate
53122 original_start_pos : syntax_pos:: BytePos ,
54123 /// The end of this SourceFile within the source_map of its original crate
@@ -485,6 +554,46 @@ impl<'tcx> EntryKind<'tcx> {
485554}
486555
487556impl < ' a , ' tcx > CrateMetadata {
557+ crate fn new (
558+ sess : & Session ,
559+ blob : MetadataBlob ,
560+ root : CrateRoot < ' static > ,
561+ raw_proc_macros : Option < & ' static [ ProcMacro ] > ,
562+ cnum : CrateNum ,
563+ cnum_map : CrateNumMap ,
564+ dep_kind : DepKind ,
565+ source : CrateSource ,
566+ private_dep : bool ,
567+ host_hash : Option < Svh > ,
568+ ) -> CrateMetadata {
569+ let def_path_table = record_time ( & sess. perf_stats . decode_def_path_tables_time , || {
570+ root. def_path_table . decode ( ( & blob, sess) )
571+ } ) ;
572+ let trait_impls = root. impls . decode ( ( & blob, sess) )
573+ . map ( |trait_impls| ( trait_impls. trait_id , trait_impls. impls ) ) . collect ( ) ;
574+ let alloc_decoding_state =
575+ AllocDecodingState :: new ( root. interpret_alloc_index . decode ( & blob) . collect ( ) ) ;
576+ let dependencies = Lock :: new ( cnum_map. iter ( ) . cloned ( ) . collect ( ) ) ;
577+ CrateMetadata {
578+ blob,
579+ root,
580+ def_path_table,
581+ trait_impls,
582+ raw_proc_macros,
583+ source_map_import_info : Once :: new ( ) ,
584+ alloc_decoding_state,
585+ dep_node_index : AtomicCell :: new ( DepNodeIndex :: INVALID ) ,
586+ cnum,
587+ cnum_map,
588+ dependencies,
589+ dep_kind : Lock :: new ( dep_kind) ,
590+ source,
591+ private_dep,
592+ host_hash,
593+ extern_crate : Lock :: new ( None ) ,
594+ }
595+ }
596+
488597 fn is_proc_macro_crate ( & self ) -> bool {
489598 self . root . proc_macro_decls_static . is_some ( )
490599 }
@@ -1391,7 +1500,7 @@ impl<'a, 'tcx> CrateMetadata {
13911500 // would always write the same value.
13921501
13931502 let def_path_hash = self . def_path_hash ( CRATE_DEF_INDEX ) ;
1394- let dep_node = def_path_hash. to_dep_node ( DepKind :: CrateMetadata ) ;
1503+ let dep_node = def_path_hash. to_dep_node ( dep_graph :: DepKind :: CrateMetadata ) ;
13951504
13961505 dep_node_index = tcx. dep_graph . dep_node_index_of ( & dep_node) ;
13971506 assert ! ( dep_node_index != DepNodeIndex :: INVALID ) ;
0 commit comments