11// Decoding metadata from a single crate's metadata
22
33use crate :: creader:: { CStore , CrateMetadataRef } ;
4- use crate :: rmeta:: table:: { FixedSizeEncoding , Table } ;
54use crate :: rmeta:: * ;
65
76use rustc_ast as ast;
87use rustc_ast:: ptr:: P ;
9- use rustc_attr as attr;
108use rustc_data_structures:: captures:: Captures ;
119use rustc_data_structures:: fx:: FxHashMap ;
1210use rustc_data_structures:: svh:: Svh ;
@@ -20,10 +18,8 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
2018use rustc_hir:: diagnostic_items:: DiagnosticItems ;
2119use rustc_hir:: lang_items;
2220use rustc_index:: vec:: { Idx , IndexVec } ;
23- use rustc_middle:: arena:: ArenaAllocatable ;
2421use rustc_middle:: metadata:: ModChild ;
2522use rustc_middle:: middle:: exported_symbols:: { ExportedSymbol , SymbolExportInfo } ;
26- use rustc_middle:: middle:: stability:: DeprecationEntry ;
2723use rustc_middle:: mir:: interpret:: { AllocDecodingSession , AllocDecodingState } ;
2824use rustc_middle:: thir;
2925use rustc_middle:: ty:: codec:: TyDecoder ;
@@ -42,6 +38,7 @@ use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
4238
4339use proc_macro:: bridge:: client:: ProcMacro ;
4440use std:: io;
41+ use std:: iter:: TrustedLen ;
4542use std:: mem;
4643use std:: num:: NonZeroUsize ;
4744use std:: path:: Path ;
@@ -85,7 +82,6 @@ pub(crate) struct CrateMetadata {
8582 blob : MetadataBlob ,
8683
8784 // --- Some data pre-decoded from the metadata blob, usually for performance ---
88- /// Properties of the whole crate.
8985 /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
9086 /// lifetime is only used behind `Lazy`, and therefore acts like a
9187 /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
@@ -94,12 +90,12 @@ pub(crate) struct CrateMetadata {
9490 /// Trait impl data.
9591 /// FIXME: Used only from queries and can use query cache,
9692 /// so pre-decoding can probably be avoided.
97- trait_impls : FxHashMap < ( u32 , DefIndex ) , Lazy < [ ( DefIndex , Option < SimplifiedType > ) ] > > ,
93+ trait_impls : FxHashMap < ( u32 , DefIndex ) , LazyArray < ( DefIndex , Option < SimplifiedType > ) > > ,
9894 /// Inherent impls which do not follow the normal coherence rules.
9995 ///
10096 /// These can be introduced using either `#![rustc_coherence_is_core]`
10197 /// or `#[rustc_allow_incoherent_impl]`.
102- incoherent_impls : FxHashMap < SimplifiedType , Lazy < [ DefIndex ] > > ,
98+ incoherent_impls : FxHashMap < SimplifiedType , LazyArray < DefIndex > > ,
10399 /// Proc macro descriptions for this crate, if it's a proc macro crate.
104100 raw_proc_macros : Option < & ' static [ ProcMacro ] > ,
105101 /// Source maps for code from the crate.
@@ -265,138 +261,49 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
265261 }
266262}
267263
268- impl < ' a , ' tcx , T : Decodable < DecodeContext < ' a , ' tcx > > > Lazy < T > {
264+ impl < ' a , ' tcx , T : Decodable < DecodeContext < ' a , ' tcx > > > LazyValue < T > {
269265 fn decode < M : Metadata < ' a , ' tcx > > ( self , metadata : M ) -> T {
270266 let mut dcx = metadata. decoder ( self . position . get ( ) ) ;
271267 dcx. lazy_state = LazyState :: NodeStart ( self . position ) ;
272268 T :: decode ( & mut dcx)
273269 }
274270}
275271
276- impl < ' a : ' x , ' tcx : ' x , ' x , T : Decodable < DecodeContext < ' a , ' tcx > > > Lazy < [ T ] > {
277- fn decode < M : Metadata < ' a , ' tcx > > (
278- self ,
279- metadata : M ,
280- ) -> impl ExactSizeIterator < Item = T > + Captures < ' a > + Captures < ' tcx > + ' x {
281- let mut dcx = metadata. decoder ( self . position . get ( ) ) ;
282- dcx. lazy_state = LazyState :: NodeStart ( self . position ) ;
283- ( 0 ..self . meta ) . map ( move |_| T :: decode ( & mut dcx) )
284- }
285- }
286-
287- trait LazyQueryDecodable < ' a , ' tcx , T > {
288- fn decode_query (
289- self ,
290- cdata : CrateMetadataRef < ' a > ,
291- tcx : TyCtxt < ' tcx > ,
292- err : impl FnOnce ( ) -> !,
293- ) -> T ;
294- }
295-
296- impl < ' a , ' tcx , T > LazyQueryDecodable < ' a , ' tcx , T > for T {
297- fn decode_query ( self , _: CrateMetadataRef < ' a > , _: TyCtxt < ' tcx > , _: impl FnOnce ( ) -> !) -> T {
298- self
299- }
300- }
301-
302- impl < ' a , ' tcx , T > LazyQueryDecodable < ' a , ' tcx , T > for Option < T > {
303- fn decode_query ( self , _: CrateMetadataRef < ' a > , _: TyCtxt < ' tcx > , err : impl FnOnce ( ) -> !) -> T {
304- if let Some ( l) = self { l } else { err ( ) }
305- }
272+ struct DecodeIterator < ' a , ' tcx , T > {
273+ elem_counter : std:: ops:: Range < usize > ,
274+ dcx : DecodeContext < ' a , ' tcx > ,
275+ _phantom : PhantomData < fn ( ) -> T > ,
306276}
307277
308- impl < ' a , ' tcx , T > LazyQueryDecodable < ' a , ' tcx , T > for Option < Lazy < T > >
309- where
310- T : Decodable < DecodeContext < ' a , ' tcx > > ,
311- {
312- fn decode_query (
313- self ,
314- cdata : CrateMetadataRef < ' a > ,
315- tcx : TyCtxt < ' tcx > ,
316- err : impl FnOnce ( ) -> !,
317- ) -> T {
318- if let Some ( l) = self { l. decode ( ( cdata, tcx) ) } else { err ( ) }
319- }
320- }
321-
322- impl < ' a , ' tcx , T > LazyQueryDecodable < ' a , ' tcx , & ' tcx T > for Option < Lazy < T > >
323- where
324- T : Decodable < DecodeContext < ' a , ' tcx > > ,
325- T : ArenaAllocatable < ' tcx > ,
326- {
327- fn decode_query (
328- self ,
329- cdata : CrateMetadataRef < ' a > ,
330- tcx : TyCtxt < ' tcx > ,
331- err : impl FnOnce ( ) -> !,
332- ) -> & ' tcx T {
333- if let Some ( l) = self { tcx. arena . alloc ( l. decode ( ( cdata, tcx) ) ) } else { err ( ) }
334- }
335- }
278+ impl < ' a , ' tcx , T : Decodable < DecodeContext < ' a , ' tcx > > > Iterator for DecodeIterator < ' a , ' tcx , T > {
279+ type Item = T ;
336280
337- impl < ' a , ' tcx , T > LazyQueryDecodable < ' a , ' tcx , Option < T > > for Option < Lazy < T > >
338- where
339- T : Decodable < DecodeContext < ' a , ' tcx > > ,
340- {
341- fn decode_query (
342- self ,
343- cdata : CrateMetadataRef < ' a > ,
344- tcx : TyCtxt < ' tcx > ,
345- _err : impl FnOnce ( ) -> !,
346- ) -> Option < T > {
347- self . map ( |l| l. decode ( ( cdata, tcx) ) )
281+ #[ inline( always) ]
282+ fn next ( & mut self ) -> Option < Self :: Item > {
283+ self . elem_counter . next ( ) . map ( |_| T :: decode ( & mut self . dcx ) )
348284 }
349- }
350285
351- impl < ' a , ' tcx , T , E > LazyQueryDecodable < ' a , ' tcx , Result < Option < T > , E > > for Option < Lazy < T > >
352- where
353- T : Decodable < DecodeContext < ' a , ' tcx > > ,
354- {
355- fn decode_query (
356- self ,
357- cdata : CrateMetadataRef < ' a > ,
358- tcx : TyCtxt < ' tcx > ,
359- _err : impl FnOnce ( ) -> !,
360- ) -> Result < Option < T > , E > {
361- Ok ( self . map ( |l| l. decode ( ( cdata, tcx) ) ) )
286+ #[ inline( always) ]
287+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
288+ self . elem_counter . size_hint ( )
362289 }
363290}
364291
365- impl < ' a , ' tcx , T > LazyQueryDecodable < ' a , ' tcx , & ' tcx [ T ] > for Option < Lazy < [ T ] , usize > >
366- where
367- T : Decodable < DecodeContext < ' a , ' tcx > > + Copy ,
292+ impl < ' a , ' tcx , T : Decodable < DecodeContext < ' a , ' tcx > > > ExactSizeIterator
293+ for DecodeIterator < ' a , ' tcx , T >
368294{
369- fn decode_query (
370- self ,
371- cdata : CrateMetadataRef < ' a > ,
372- tcx : TyCtxt < ' tcx > ,
373- _err : impl FnOnce ( ) -> !,
374- ) -> & ' tcx [ T ] {
375- if let Some ( l) = self { tcx. arena . alloc_from_iter ( l. decode ( ( cdata, tcx) ) ) } else { & [ ] }
376- }
377295}
378296
379- impl < ' a , ' tcx > LazyQueryDecodable < ' a , ' tcx , Option < DeprecationEntry > >
380- for Option < Lazy < attr :: Deprecation > >
297+ unsafe impl < ' a , ' tcx , T : Decodable < DecodeContext < ' a , ' tcx > > > TrustedLen
298+ for DecodeIterator < ' a , ' tcx , T >
381299{
382- fn decode_query (
383- self ,
384- cdata : CrateMetadataRef < ' a > ,
385- tcx : TyCtxt < ' tcx > ,
386- _err : impl FnOnce ( ) -> !,
387- ) -> Option < DeprecationEntry > {
388- self . map ( |l| l. decode ( ( cdata, tcx) ) ) . map ( DeprecationEntry :: external)
389- }
390300}
391301
392- impl < ' a , ' tcx > LazyQueryDecodable < ' a , ' tcx , Option < DefId > > for Option < RawDefId > {
393- fn decode_query (
394- self ,
395- cdata : CrateMetadataRef < ' a > ,
396- _: TyCtxt < ' tcx > ,
397- _: impl FnOnce ( ) -> !,
398- ) -> Option < DefId > {
399- self . map ( |raw_def_id| raw_def_id. decode ( cdata) )
302+ impl < ' a : ' x , ' tcx : ' x , ' x , T : Decodable < DecodeContext < ' a , ' tcx > > > LazyArray < T > {
303+ fn decode < M : Metadata < ' a , ' tcx > > ( self , metadata : M ) -> DecodeIterator < ' a , ' tcx , T > {
304+ let mut dcx = metadata. decoder ( self . position . get ( ) ) ;
305+ dcx. lazy_state = LazyState :: NodeStart ( self . position ) ;
306+ DecodeIterator { elem_counter : ( 0 ..self . num_elems ) , dcx, _phantom : PhantomData }
400307 }
401308}
402309
@@ -423,7 +330,8 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
423330 self . cdata ( ) . map_encoded_cnum_to_current ( cnum)
424331 }
425332
426- fn read_lazy_with_meta < T : ?Sized + LazyMeta > ( & mut self , meta : T :: Meta ) -> Lazy < T > {
333+ #[ inline]
334+ fn read_lazy_offset_then < T > ( & mut self , f : impl Fn ( NonZeroUsize ) -> T ) -> T {
427335 let distance = self . read_usize ( ) ;
428336 let position = match self . lazy_state {
429337 LazyState :: NoNode => bug ! ( "read_lazy_with_meta: outside of a metadata node" ) ,
@@ -434,8 +342,21 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
434342 }
435343 LazyState :: Previous ( last_pos) => last_pos. get ( ) + distance,
436344 } ;
437- self . lazy_state = LazyState :: Previous ( NonZeroUsize :: new ( position) . unwrap ( ) ) ;
438- Lazy :: from_position_and_meta ( NonZeroUsize :: new ( position) . unwrap ( ) , meta)
345+ let position = NonZeroUsize :: new ( position) . unwrap ( ) ;
346+ self . lazy_state = LazyState :: Previous ( position) ;
347+ f ( position)
348+ }
349+
350+ fn read_lazy < T > ( & mut self ) -> LazyValue < T > {
351+ self . read_lazy_offset_then ( |pos| LazyValue :: from_position ( pos) )
352+ }
353+
354+ fn read_lazy_array < T > ( & mut self , len : usize ) -> LazyArray < T > {
355+ self . read_lazy_offset_then ( |pos| LazyArray :: from_position_and_num_elems ( pos, len) )
356+ }
357+
358+ fn read_lazy_table < I , T > ( & mut self , len : usize ) -> LazyTable < I , T > {
359+ self . read_lazy_offset_then ( |pos| LazyTable :: from_position_and_encoded_size ( pos, len) )
439360 }
440361
441362 #[ inline]
@@ -714,36 +635,29 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx
714635 }
715636}
716637
717- impl < ' a , ' tcx , T : Decodable < DecodeContext < ' a , ' tcx > > > Decodable < DecodeContext < ' a , ' tcx > >
718- for Lazy < T >
719- {
638+ impl < ' a , ' tcx , T > Decodable < DecodeContext < ' a , ' tcx > > for LazyValue < T > {
720639 fn decode ( decoder : & mut DecodeContext < ' a , ' tcx > ) -> Self {
721- decoder. read_lazy_with_meta ( ( ) )
640+ decoder. read_lazy ( )
722641 }
723642}
724643
725- impl < ' a , ' tcx , T : Decodable < DecodeContext < ' a , ' tcx > > > Decodable < DecodeContext < ' a , ' tcx > >
726- for Lazy < [ T ] >
727- {
644+ impl < ' a , ' tcx , T > Decodable < DecodeContext < ' a , ' tcx > > for LazyArray < T > {
728645 fn decode ( decoder : & mut DecodeContext < ' a , ' tcx > ) -> Self {
729646 let len = decoder. read_usize ( ) ;
730- if len == 0 { Lazy :: empty ( ) } else { decoder. read_lazy_with_meta ( len) }
647+ if len == 0 { LazyArray :: empty ( ) } else { decoder. read_lazy_array ( len) }
731648 }
732649}
733650
734- impl < ' a , ' tcx , I : Idx , T > Decodable < DecodeContext < ' a , ' tcx > > for Lazy < Table < I , T > >
735- where
736- Option < T > : FixedSizeEncoding ,
737- {
651+ impl < ' a , ' tcx , I : Idx , T > Decodable < DecodeContext < ' a , ' tcx > > for LazyTable < I , T > {
738652 fn decode ( decoder : & mut DecodeContext < ' a , ' tcx > ) -> Self {
739653 let len = decoder. read_usize ( ) ;
740- decoder. read_lazy_with_meta ( len)
654+ decoder. read_lazy_table ( len)
741655 }
742656}
743657
744658implement_ty_decoder ! ( DecodeContext <' a, ' tcx>) ;
745659
746- impl < ' tcx > MetadataBlob {
660+ impl MetadataBlob {
747661 pub ( crate ) fn new ( metadata_ref : MetadataRef ) -> MetadataBlob {
748662 MetadataBlob ( Lrc :: new ( metadata_ref) )
749663 }
@@ -753,18 +667,18 @@ impl<'tcx> MetadataBlob {
753667 }
754668
755669 pub ( crate ) fn get_rustc_version ( & self ) -> String {
756- Lazy :: < String > :: from_position ( NonZeroUsize :: new ( METADATA_HEADER . len ( ) + 4 ) . unwrap ( ) )
670+ LazyValue :: < String > :: from_position ( NonZeroUsize :: new ( METADATA_HEADER . len ( ) + 4 ) . unwrap ( ) )
757671 . decode ( self )
758672 }
759673
760- pub ( crate ) fn get_root ( & self ) -> CrateRoot < ' tcx > {
674+ pub ( crate ) fn get_root < ' tcx > ( & self ) -> CrateRoot < ' tcx > {
761675 let slice = & self . blob ( ) [ ..] ;
762676 let offset = METADATA_HEADER . len ( ) ;
763677 let pos = ( ( ( slice[ offset + 0 ] as u32 ) << 24 )
764678 | ( ( slice[ offset + 1 ] as u32 ) << 16 )
765679 | ( ( slice[ offset + 2 ] as u32 ) << 8 )
766680 | ( ( slice[ offset + 3 ] as u32 ) << 0 ) ) as usize ;
767- Lazy :: < CrateRoot < ' tcx > > :: from_position ( NonZeroUsize :: new ( pos) . unwrap ( ) ) . decode ( self )
681+ LazyValue :: < CrateRoot < ' tcx > > :: from_position ( NonZeroUsize :: new ( pos) . unwrap ( ) ) . decode ( self )
768682 }
769683
770684 pub ( crate ) fn list_crate_metadata ( & self , out : & mut dyn io:: Write ) -> io:: Result < ( ) > {
@@ -963,7 +877,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
963877 . tables
964878 . children
965879 . get ( self , index)
966- . unwrap_or_else ( Lazy :: empty)
880+ . unwrap_or_else ( LazyArray :: empty)
967881 . decode ( self )
968882 . map ( |index| ty:: FieldDef {
969883 did : self . local_def_id ( index) ,
@@ -996,7 +910,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
996910 . tables
997911 . children
998912 . get ( self , item_id)
999- . unwrap_or_else ( Lazy :: empty)
913+ . unwrap_or_else ( LazyArray :: empty)
1000914 . decode ( self )
1001915 . map ( |index| self . get_variant ( & self . kind ( index) , index, did) )
1002916 . collect ( )
@@ -1016,7 +930,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1016930 }
1017931
1018932 fn get_trait_item_def_id ( self , id : DefIndex ) -> Option < DefId > {
1019- self . root . tables . trait_item_def_id . get ( self , id) . map ( |d| d. decode ( self ) )
933+ self . root . tables . trait_item_def_id . get ( self , id) . map ( |d| d. decode_from_cdata ( self ) )
1020934 }
1021935
1022936 fn get_expn_that_defined ( self , id : DefIndex , sess : & Session ) -> ExpnId {
@@ -1202,7 +1116,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12021116 . tables
12031117 . children
12041118 . get ( self , id)
1205- . unwrap_or_else ( Lazy :: empty)
1119+ . unwrap_or_else ( LazyArray :: empty)
12061120 . decode ( ( self , sess) )
12071121 . map ( move |child_index| self . local_def_id ( child_index) )
12081122 }
@@ -1278,7 +1192,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12781192 . tables
12791193 . children
12801194 . get ( self , id)
1281- . unwrap_or_else ( Lazy :: empty)
1195+ . unwrap_or_else ( LazyArray :: empty)
12821196 . decode ( self )
12831197 . map ( move |index| respan ( self . get_span ( index, sess) , self . item_name ( index) ) )
12841198 }
@@ -1288,7 +1202,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12881202 . tables
12891203 . children
12901204 . get ( self , id)
1291- . unwrap_or_else ( Lazy :: empty)
1205+ . unwrap_or_else ( LazyArray :: empty)
12921206 . decode ( self )
12931207 . map ( move |field_index| self . get_visibility ( field_index) )
12941208 }
@@ -1303,7 +1217,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13031217 . tables
13041218 . inherent_impls
13051219 . get ( self , id)
1306- . unwrap_or_else ( Lazy :: empty)
1220+ . unwrap_or_else ( LazyArray :: empty)
13071221 . decode ( self )
13081222 . map ( |index| self . local_def_id ( index) ) ,
13091223 )
@@ -1318,7 +1232,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13181232 . tables
13191233 . inherent_impls
13201234 . get ( self , ty_index)
1321- . unwrap_or_else ( Lazy :: empty)
1235+ . unwrap_or_else ( LazyArray :: empty)
13221236 . decode ( self )
13231237 . map ( move |impl_index| ( ty_def_id, self . local_def_id ( impl_index) ) )
13241238 } )
0 commit comments