Skip to content

Commit ca5e60b

Browse files
split out the various responsibilities of Lazy
1 parent ee160f2 commit ca5e60b

File tree

5 files changed

+370
-420
lines changed

5 files changed

+370
-420
lines changed

compiler/rustc_metadata/src/rmeta/decoder.rs

+54-150
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
// Decoding metadata from a single crate's metadata
22

33
use crate::creader::{CStore, CrateMetadataRef};
4-
use crate::rmeta::table::{FixedSizeEncoding, Table};
54
use crate::rmeta::*;
65

76
use rustc_ast as ast;
87
use rustc_ast::ptr::P;
9-
use rustc_attr as attr;
108
use rustc_data_structures::captures::Captures;
119
use rustc_data_structures::fx::FxHashMap;
1210
use rustc_data_structures::svh::Svh;
@@ -20,10 +18,8 @@ use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
2018
use rustc_hir::diagnostic_items::DiagnosticItems;
2119
use rustc_hir::lang_items;
2220
use rustc_index::vec::{Idx, IndexVec};
23-
use rustc_middle::arena::ArenaAllocatable;
2421
use rustc_middle::metadata::ModChild;
2522
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
26-
use rustc_middle::middle::stability::DeprecationEntry;
2723
use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
2824
use rustc_middle::thir;
2925
use rustc_middle::ty::codec::TyDecoder;
@@ -85,7 +81,6 @@ pub(crate) struct CrateMetadata {
8581
blob: MetadataBlob,
8682

8783
// --- Some data pre-decoded from the metadata blob, usually for performance ---
88-
/// Properties of the whole crate.
8984
/// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
9085
/// lifetime is only used behind `Lazy`, and therefore acts like a
9186
/// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
@@ -94,12 +89,12 @@ pub(crate) struct CrateMetadata {
9489
/// Trait impl data.
9590
/// FIXME: Used only from queries and can use query cache,
9691
/// so pre-decoding can probably be avoided.
97-
trait_impls: FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<SimplifiedType>)]>>,
92+
trait_impls: FxHashMap<(u32, DefIndex), LazyArray<(DefIndex, Option<SimplifiedType>)>>,
9893
/// Inherent impls which do not follow the normal coherence rules.
9994
///
10095
/// These can be introduced using either `#![rustc_coherence_is_core]`
10196
/// or `#[rustc_allow_incoherent_impl]`.
102-
incoherent_impls: FxHashMap<SimplifiedType, Lazy<[DefIndex]>>,
97+
incoherent_impls: FxHashMap<SimplifiedType, LazyArray<DefIndex>>,
10398
/// Proc macro descriptions for this crate, if it's a proc macro crate.
10499
raw_proc_macros: Option<&'static [ProcMacro]>,
105100
/// Source maps for code from the crate.
@@ -265,138 +260,41 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
265260
}
266261
}
267262

268-
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<T> {
263+
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> LazyValue<T> {
269264
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
270265
let mut dcx = metadata.decoder(self.position.get());
271266
dcx.lazy_state = LazyState::NodeStart(self.position);
272267
T::decode(&mut dcx)
273268
}
274269
}
275270

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-
}
271+
struct DecodeIterator<'a, 'tcx, T> {
272+
range: std::ops::Range<usize>,
273+
dcx: DecodeContext<'a, 'tcx>,
274+
_phantom: PhantomData<fn() -> T>,
306275
}
307276

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-
}
277+
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Iterator for DecodeIterator<'a, 'tcx, T> {
278+
type Item = T;
321279

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() }
280+
fn next(&mut self) -> Option<Self::Item> {
281+
self.range.next().map(|_| T::decode(&mut self.dcx))
334282
}
335283
}
336284

337-
impl<'a, 'tcx, T> LazyQueryDecodable<'a, 'tcx, Option<T>> for Option<Lazy<T>>
338-
where
339-
T: Decodable<DecodeContext<'a, 'tcx>>,
285+
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> ExactSizeIterator
286+
for DecodeIterator<'a, 'tcx, T>
340287
{
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)))
288+
fn len(&self) -> usize {
289+
self.range.len()
348290
}
349291
}
350292

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))))
362-
}
363-
}
364-
365-
impl<'a, 'tcx, T> LazyQueryDecodable<'a, 'tcx, &'tcx [T]> for Option<Lazy<[T], usize>>
366-
where
367-
T: Decodable<DecodeContext<'a, 'tcx>> + Copy,
368-
{
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-
}
377-
}
378-
379-
impl<'a, 'tcx> LazyQueryDecodable<'a, 'tcx, Option<DeprecationEntry>>
380-
for Option<Lazy<attr::Deprecation>>
381-
{
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-
}
390-
}
391-
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))
293+
impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> LazyArray<T> {
294+
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> DecodeIterator<'a, 'tcx, T> {
295+
let mut dcx = metadata.decoder(self.position.get());
296+
dcx.lazy_state = LazyState::NodeStart(self.position);
297+
DecodeIterator { range: (0..self.len), dcx, _phantom: PhantomData }
400298
}
401299
}
402300

@@ -423,7 +321,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
423321
self.cdata().map_encoded_cnum_to_current(cnum)
424322
}
425323

426-
fn read_lazy_with_meta<T: ?Sized + LazyMeta>(&mut self, meta: T::Meta) -> Lazy<T> {
324+
fn read_lazy_offset_then<T>(&mut self, f: impl Fn(NonZeroUsize) -> T) -> T {
427325
let distance = self.read_usize();
428326
let position = match self.lazy_state {
429327
LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
@@ -434,8 +332,21 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
434332
}
435333
LazyState::Previous(last_pos) => last_pos.get() + distance,
436334
};
437-
self.lazy_state = LazyState::Previous(NonZeroUsize::new(position).unwrap());
438-
Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta)
335+
let position = NonZeroUsize::new(position).unwrap();
336+
self.lazy_state = LazyState::Previous(position);
337+
f(position)
338+
}
339+
340+
fn read_lazy<T>(&mut self) -> LazyValue<T> {
341+
self.read_lazy_offset_then(|pos| LazyValue::from_position(pos))
342+
}
343+
344+
fn read_lazy_array<T>(&mut self, len: usize) -> LazyArray<T> {
345+
self.read_lazy_offset_then(|pos| LazyArray::from_position_and_len(pos, len))
346+
}
347+
348+
fn read_lazy_table<I, T>(&mut self, len: usize) -> LazyTable<I, T> {
349+
self.read_lazy_offset_then(|pos| LazyTable::from_position_and_len(pos, len))
439350
}
440351

441352
#[inline]
@@ -714,36 +625,29 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx
714625
}
715626
}
716627

717-
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
718-
for Lazy<T>
719-
{
628+
impl<'a, 'tcx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyValue<T> {
720629
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
721-
decoder.read_lazy_with_meta(())
630+
decoder.read_lazy()
722631
}
723632
}
724633

725-
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
726-
for Lazy<[T]>
727-
{
634+
impl<'a, 'tcx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyArray<T> {
728635
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
729636
let len = decoder.read_usize();
730-
if len == 0 { Lazy::empty() } else { decoder.read_lazy_with_meta(len) }
637+
if len == 0 { LazyArray::empty() } else { decoder.read_lazy_array(len) }
731638
}
732639
}
733640

734-
impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for Lazy<Table<I, T>>
735-
where
736-
Option<T>: FixedSizeEncoding,
737-
{
641+
impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyTable<I, T> {
738642
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
739643
let len = decoder.read_usize();
740-
decoder.read_lazy_with_meta(len)
644+
decoder.read_lazy_table(len)
741645
}
742646
}
743647

744648
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
745649

746-
impl<'tcx> MetadataBlob {
650+
impl MetadataBlob {
747651
pub(crate) fn new(metadata_ref: MetadataRef) -> MetadataBlob {
748652
MetadataBlob(Lrc::new(metadata_ref))
749653
}
@@ -753,18 +657,18 @@ impl<'tcx> MetadataBlob {
753657
}
754658

755659
pub(crate) fn get_rustc_version(&self) -> String {
756-
Lazy::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap())
660+
LazyValue::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap())
757661
.decode(self)
758662
}
759663

760-
pub(crate) fn get_root(&self) -> CrateRoot<'tcx> {
664+
pub(crate) fn get_root<'tcx>(&self) -> CrateRoot<'tcx> {
761665
let slice = &self.blob()[..];
762666
let offset = METADATA_HEADER.len();
763667
let pos = (((slice[offset + 0] as u32) << 24)
764668
| ((slice[offset + 1] as u32) << 16)
765669
| ((slice[offset + 2] as u32) << 8)
766670
| ((slice[offset + 3] as u32) << 0)) as usize;
767-
Lazy::<CrateRoot<'tcx>>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
671+
LazyValue::<CrateRoot<'tcx>>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
768672
}
769673

770674
pub(crate) fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
@@ -963,7 +867,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
963867
.tables
964868
.children
965869
.get(self, index)
966-
.unwrap_or_else(Lazy::empty)
870+
.unwrap_or_else(LazyArray::empty)
967871
.decode(self)
968872
.map(|index| ty::FieldDef {
969873
did: self.local_def_id(index),
@@ -996,7 +900,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
996900
.tables
997901
.children
998902
.get(self, item_id)
999-
.unwrap_or_else(Lazy::empty)
903+
.unwrap_or_else(LazyArray::empty)
1000904
.decode(self)
1001905
.map(|index| self.get_variant(&self.kind(index), index, did))
1002906
.collect()
@@ -1016,7 +920,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1016920
}
1017921

1018922
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))
923+
self.root.tables.trait_item_def_id.get(self, id).map(|d| d.decode_from_cdata(self))
1020924
}
1021925

1022926
fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId {
@@ -1202,7 +1106,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12021106
.tables
12031107
.children
12041108
.get(self, id)
1205-
.unwrap_or_else(Lazy::empty)
1109+
.unwrap_or_else(LazyArray::empty)
12061110
.decode((self, sess))
12071111
.map(move |child_index| self.local_def_id(child_index))
12081112
}
@@ -1278,7 +1182,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12781182
.tables
12791183
.children
12801184
.get(self, id)
1281-
.unwrap_or_else(Lazy::empty)
1185+
.unwrap_or_else(LazyArray::empty)
12821186
.decode(self)
12831187
.map(move |index| respan(self.get_span(index, sess), self.item_name(index)))
12841188
}
@@ -1288,7 +1192,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
12881192
.tables
12891193
.children
12901194
.get(self, id)
1291-
.unwrap_or_else(Lazy::empty)
1195+
.unwrap_or_else(LazyArray::empty)
12921196
.decode(self)
12931197
.map(move |field_index| self.get_visibility(field_index))
12941198
}
@@ -1303,7 +1207,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13031207
.tables
13041208
.inherent_impls
13051209
.get(self, id)
1306-
.unwrap_or_else(Lazy::empty)
1210+
.unwrap_or_else(LazyArray::empty)
13071211
.decode(self)
13081212
.map(|index| self.local_def_id(index)),
13091213
)
@@ -1318,7 +1222,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
13181222
.tables
13191223
.inherent_impls
13201224
.get(self, ty_index)
1321-
.unwrap_or_else(Lazy::empty)
1225+
.unwrap_or_else(LazyArray::empty)
13221226
.decode(self)
13231227
.map(move |impl_index| (ty_def_id, self.local_def_id(impl_index)))
13241228
})

0 commit comments

Comments
 (0)