Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ee9726c

Browse files
committedMay 24, 2022
Auto merge of rust-lang#97291 - compiler-errors:lazy-is-actually-3-types-in-a-trenchcoat, r=cjgillot
Split out the various responsibilities of `rustc_metadata::Lazy` `Lazy<T>` actually acts like three different types -- a pointer in the crate metadata to a single value, a pointer to a list/array of values, and an indexable pointer of a list of values (a table). We currently overload `Lazy<T>` to work differently than `Lazy<[T]>` and the same for `Lazy<Table<I, T>>`. All is well with some helper adapter traits such as [`LazyQueryDecodable`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/decoder/trait.LazyQueryDecodable.html) and [`EncodeContentsForLazy`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_metadata/rmeta/encoder/trait.EncodeContentsForLazy.html). Well, changes in rust-lang#97287 that make `Lazy` work with the now invariant lifetime `'tcx` make these adapters fall apart because of coherence reasons. So we split out these three types and rework some of the helper traits so it's both 1. more clear to understand, and 2. compatible with the changes later in that PR. Split out from rust-lang#97287 so it can be reviewed separately, since this PR stands on its own.
2 parents b2eba05 + 2b5e592 commit ee9726c

File tree

6 files changed

+392
-420
lines changed

6 files changed

+392
-420
lines changed
 

‎compiler/rustc_metadata/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#![feature(macro_metavar_expr)]
1111
#![feature(min_specialization)]
1212
#![feature(slice_as_chunks)]
13+
#![feature(trusted_len)]
1314
#![feature(try_blocks)]
1415
#![feature(never_type)]
1516
#![recursion_limit = "256"]

‎compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 60 additions & 146 deletions
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;
@@ -42,6 +38,7 @@ use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
4238

4339
use proc_macro::bridge::client::ProcMacro;
4440
use std::io;
41+
use std::iter::TrustedLen;
4542
use std::mem;
4643
use std::num::NonZeroUsize;
4744
use 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

744658
implement_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
})

‎compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
use super::LazyQueryDecodable;
21
use crate::creader::{CStore, LoadedMacro};
32
use crate::foreign_modules;
43
use crate::native_libs;
54

65
use rustc_ast as ast;
6+
use rustc_attr::Deprecation;
77
use rustc_hir::def::{CtorKind, DefKind, Res};
88
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
99
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
10+
use rustc_middle::arena::ArenaAllocatable;
1011
use rustc_middle::metadata::ModChild;
1112
use rustc_middle::middle::exported_symbols::ExportedSymbol;
13+
use rustc_middle::middle::stability::DeprecationEntry;
1214
use rustc_middle::ty::fast_reject::SimplifiedType;
1315
use rustc_middle::ty::query::{ExternProviders, Providers};
1416
use rustc_middle::ty::{self, TyCtxt, Visibility};
@@ -23,15 +25,80 @@ use rustc_data_structures::sync::Lrc;
2325
use smallvec::SmallVec;
2426
use std::any::Any;
2527

28+
use super::{Decodable, DecodeContext, DecodeIterator};
29+
30+
trait ProcessQueryValue<'tcx, T> {
31+
fn process_decoded(self, _tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> T;
32+
}
33+
34+
impl<T> ProcessQueryValue<'_, Option<T>> for Option<T> {
35+
#[inline(always)]
36+
fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Option<T> {
37+
self
38+
}
39+
}
40+
41+
impl<T> ProcessQueryValue<'_, T> for Option<T> {
42+
#[inline(always)]
43+
fn process_decoded(self, _tcx: TyCtxt<'_>, err: impl Fn() -> !) -> T {
44+
if let Some(value) = self { value } else { err() }
45+
}
46+
}
47+
48+
impl<'tcx, T: ArenaAllocatable<'tcx>> ProcessQueryValue<'tcx, &'tcx T> for Option<T> {
49+
#[inline(always)]
50+
fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx T {
51+
if let Some(value) = self { tcx.arena.alloc(value) } else { err() }
52+
}
53+
}
54+
55+
impl<T, E> ProcessQueryValue<'_, Result<Option<T>, E>> for Option<T> {
56+
#[inline(always)]
57+
fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Result<Option<T>, E> {
58+
Ok(self)
59+
}
60+
}
61+
62+
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>> ProcessQueryValue<'tcx, &'tcx [T]>
63+
for Option<DecodeIterator<'a, 'tcx, T>>
64+
{
65+
#[inline(always)]
66+
fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> &'tcx [T] {
67+
if let Some(iter) = self { tcx.arena.alloc_from_iter(iter) } else { &[] }
68+
}
69+
}
70+
71+
impl ProcessQueryValue<'_, Option<DeprecationEntry>> for Option<Deprecation> {
72+
#[inline(always)]
73+
fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Option<DeprecationEntry> {
74+
self.map(DeprecationEntry::external)
75+
}
76+
}
77+
2678
macro_rules! provide_one {
2779
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table }) => {
2880
provide_one! {
2981
<$lt> $tcx, $def_id, $other, $cdata, $name => {
30-
$cdata.root.tables.$name.get($cdata, $def_id.index).decode_query(
31-
$cdata,
32-
$tcx,
33-
|| panic!("{:?} does not have a {:?}", $def_id, stringify!($name)),
34-
)
82+
$cdata
83+
.root
84+
.tables
85+
.$name
86+
.get($cdata, $def_id.index)
87+
.map(|lazy| lazy.decode(($cdata, $tcx)))
88+
.process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name)))
89+
}
90+
}
91+
};
92+
(<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_direct }) => {
93+
provide_one! {
94+
<$lt> $tcx, $def_id, $other, $cdata, $name => {
95+
// We don't decode `table_direct`, since it's not a Lazy, but an actual value
96+
$cdata
97+
.root
98+
.tables
99+
.$name
100+
.get($cdata, $def_id.index)
101+
.process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name)))
35102
}
36103
}
37104
};
@@ -143,15 +210,15 @@ provide! { <'tcx> tcx, def_id, other, cdata,
143210
lookup_deprecation_entry => { table }
144211
visibility => { table }
145212
unused_generic_params => { table }
146-
opt_def_kind => { table }
213+
opt_def_kind => { table_direct }
147214
impl_parent => { table }
148-
impl_polarity => { table }
149-
impl_defaultness => { table }
150-
impl_constness => { table }
215+
impl_polarity => { table_direct }
216+
impl_defaultness => { table_direct }
217+
impl_constness => { table_direct }
151218
coerce_unsized_info => { table }
152219
mir_const_qualif => { table }
153220
rendered_const => { table }
154-
asyncness => { table }
221+
asyncness => { table_direct }
155222
fn_arg_names => { table }
156223
generator_kind => { table }
157224
trait_def => { table }

‎compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 108 additions & 110 deletions
Large diffs are not rendered by default.

‎compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 129 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::creader::CrateMetadataRef;
22
use decoder::Metadata;
33
use def_path_hash_map::DefPathHashMapRef;
4-
use table::{Table, TableBuilder};
4+
use table::TableBuilder;
55

66
use rustc_ast as ast;
77
use rustc_attr as attr;
@@ -20,8 +20,8 @@ use rustc_middle::mir;
2020
use rustc_middle::thir;
2121
use rustc_middle::ty::fast_reject::SimplifiedType;
2222
use rustc_middle::ty::query::Providers;
23-
use rustc_middle::ty::GeneratorDiagnosticData;
2423
use rustc_middle::ty::{self, ReprOptions, Ty};
24+
use rustc_middle::ty::{GeneratorDiagnosticData, TyCtxt};
2525
use rustc_serialize::opaque::Encoder;
2626
use rustc_session::config::SymbolManglingVersion;
2727
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
@@ -62,20 +62,6 @@ const METADATA_VERSION: u8 = 6;
6262
/// and further followed by the rustc version string.
6363
pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
6464

65-
/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
66-
/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
67-
trait LazyMeta {
68-
type Meta: Copy + 'static;
69-
}
70-
71-
impl<T> LazyMeta for T {
72-
type Meta = ();
73-
}
74-
75-
impl<T> LazyMeta for [T] {
76-
type Meta = usize;
77-
}
78-
7965
/// A value of type T referred to by its absolute position
8066
/// in the metadata, and which can be decoded lazily.
8167
///
@@ -91,8 +77,19 @@ impl<T> LazyMeta for [T] {
9177
/// Distances start at 1, as 0-byte nodes are invalid.
9278
/// Also invalid are nodes being referred in a different
9379
/// order than they were encoded in.
94-
///
95-
/// # Sequences (`Lazy<[T]>`)
80+
#[must_use]
81+
struct LazyValue<T> {
82+
position: NonZeroUsize,
83+
_marker: PhantomData<fn() -> T>,
84+
}
85+
86+
impl<T> LazyValue<T> {
87+
fn from_position(position: NonZeroUsize) -> LazyValue<T> {
88+
LazyValue { position, _marker: PhantomData }
89+
}
90+
}
91+
92+
/// A list of lazily-decoded values.
9693
///
9794
/// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
9895
/// position, not at the position, which means that the length
@@ -102,39 +99,58 @@ impl<T> LazyMeta for [T] {
10299
/// the encoding is that of `Lazy`, with the distinction that
103100
/// the minimal distance the length of the sequence, i.e.
104101
/// it's assumed there's no 0-byte element in the sequence.
105-
#[must_use]
106-
// FIXME(#59875) the `Meta` parameter only exists to dodge
107-
// invariance wrt `T` (coming from the `meta: T::Meta` field).
108-
struct Lazy<T, Meta = <T as LazyMeta>::Meta>
109-
where
110-
T: ?Sized + LazyMeta<Meta = Meta>,
111-
Meta: 'static + Copy,
112-
{
102+
struct LazyArray<T> {
103+
position: NonZeroUsize,
104+
num_elems: usize,
105+
_marker: PhantomData<fn() -> T>,
106+
}
107+
108+
impl<T> LazyArray<T> {
109+
fn from_position_and_num_elems(position: NonZeroUsize, num_elems: usize) -> LazyArray<T> {
110+
LazyArray { position, num_elems, _marker: PhantomData }
111+
}
112+
113+
fn empty() -> LazyArray<T> {
114+
LazyArray::from_position_and_num_elems(NonZeroUsize::new(1).unwrap(), 0)
115+
}
116+
}
117+
118+
/// A list of lazily-decoded values, with the added capability of random access.
119+
///
120+
/// Random-access table (i.e. offering constant-time `get`/`set`), similar to
121+
/// `LazyArray<T>`, but without requiring encoding or decoding all the values
122+
/// eagerly and in-order.
123+
struct LazyTable<I, T> {
113124
position: NonZeroUsize,
114-
meta: Meta,
115-
_marker: PhantomData<T>,
125+
encoded_size: usize,
126+
_marker: PhantomData<fn(I) -> T>,
116127
}
117128

118-
impl<T: ?Sized + LazyMeta> Lazy<T> {
119-
fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy<T> {
120-
Lazy { position, meta, _marker: PhantomData }
129+
impl<I, T> LazyTable<I, T> {
130+
fn from_position_and_encoded_size(
131+
position: NonZeroUsize,
132+
encoded_size: usize,
133+
) -> LazyTable<I, T> {
134+
LazyTable { position, encoded_size, _marker: PhantomData }
121135
}
122136
}
123137

124-
impl<T> Lazy<T> {
125-
fn from_position(position: NonZeroUsize) -> Lazy<T> {
126-
Lazy::from_position_and_meta(position, ())
138+
impl<T> Copy for LazyValue<T> {}
139+
impl<T> Clone for LazyValue<T> {
140+
fn clone(&self) -> Self {
141+
*self
127142
}
128143
}
129144

130-
impl<T> Lazy<[T]> {
131-
fn empty() -> Lazy<[T]> {
132-
Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
145+
impl<T> Copy for LazyArray<T> {}
146+
impl<T> Clone for LazyArray<T> {
147+
fn clone(&self) -> Self {
148+
*self
133149
}
134150
}
135151

136-
impl<T: ?Sized + LazyMeta> Copy for Lazy<T> {}
137-
impl<T: ?Sized + LazyMeta> Clone for Lazy<T> {
152+
impl<I, T> Copy for LazyTable<I, T> {}
153+
impl<I, T> Clone for LazyTable<I, T> {
138154
fn clone(&self) -> Self {
139155
*self
140156
}
@@ -155,29 +171,20 @@ enum LazyState {
155171
Previous(NonZeroUsize),
156172
}
157173

158-
// FIXME(#59875) `Lazy!(T)` replaces `Lazy<T>`, passing the `Meta` parameter
159-
// manually, instead of relying on the default, to get the correct variance.
160-
// Only needed when `T` itself contains a parameter (e.g. `'tcx`).
161-
macro_rules! Lazy {
162-
(Table<$I:ty, $T:ty>) => {Lazy<Table<$I, $T>, usize>};
163-
([$T:ty]) => {Lazy<[$T], usize>};
164-
($T:ty) => {Lazy<$T, ()>};
165-
}
166-
167-
type SyntaxContextTable = Lazy<Table<u32, Lazy<SyntaxContextData>>>;
168-
type ExpnDataTable = Lazy<Table<ExpnIndex, Lazy<ExpnData>>>;
169-
type ExpnHashTable = Lazy<Table<ExpnIndex, Lazy<ExpnHash>>>;
174+
type SyntaxContextTable = LazyTable<u32, LazyValue<SyntaxContextData>>;
175+
type ExpnDataTable = LazyTable<ExpnIndex, LazyValue<ExpnData>>;
176+
type ExpnHashTable = LazyTable<ExpnIndex, LazyValue<ExpnHash>>;
170177

171178
#[derive(MetadataEncodable, MetadataDecodable)]
172179
pub(crate) struct ProcMacroData {
173180
proc_macro_decls_static: DefIndex,
174181
stability: Option<attr::Stability>,
175-
macros: Lazy<[DefIndex]>,
182+
macros: LazyArray<DefIndex>,
176183
}
177184

178185
/// Serialized metadata for a crate.
179186
/// When compiling a proc-macro crate, we encode many of
180-
/// the `Lazy<[T]>` fields as `Lazy::empty()`. This serves two purposes:
187+
/// the `LazyArray<T>` fields as `Lazy::empty()`. This serves two purposes:
181188
///
182189
/// 1. We avoid performing unnecessary work. Proc-macro crates can only
183190
/// export proc-macros functions, which are compiled into a shared library.
@@ -205,32 +212,32 @@ pub(crate) struct CrateRoot<'tcx> {
205212
has_panic_handler: bool,
206213
has_default_lib_allocator: bool,
207214

208-
crate_deps: Lazy<[CrateDep]>,
209-
dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
210-
lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
211-
lang_items: Lazy<[(DefIndex, usize)]>,
212-
lang_items_missing: Lazy<[lang_items::LangItem]>,
213-
diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
214-
native_libraries: Lazy<[NativeLib]>,
215-
foreign_modules: Lazy<[ForeignModule]>,
216-
traits: Lazy<[DefIndex]>,
217-
impls: Lazy<[TraitImpls]>,
218-
incoherent_impls: Lazy<[IncoherentImpls]>,
219-
interpret_alloc_index: Lazy<[u32]>,
215+
crate_deps: LazyArray<CrateDep>,
216+
dylib_dependency_formats: LazyArray<Option<LinkagePreference>>,
217+
lib_features: LazyArray<(Symbol, Option<Symbol>)>,
218+
lang_items: LazyArray<(DefIndex, usize)>,
219+
lang_items_missing: LazyArray<lang_items::LangItem>,
220+
diagnostic_items: LazyArray<(Symbol, DefIndex)>,
221+
native_libraries: LazyArray<NativeLib>,
222+
foreign_modules: LazyArray<ForeignModule>,
223+
traits: LazyArray<DefIndex>,
224+
impls: LazyArray<TraitImpls>,
225+
incoherent_impls: LazyArray<IncoherentImpls>,
226+
interpret_alloc_index: LazyArray<u32>,
220227
proc_macro_data: Option<ProcMacroData>,
221228

222229
tables: LazyTables<'tcx>,
223-
debugger_visualizers: Lazy<[rustc_span::DebuggerVisualizerFile]>,
230+
debugger_visualizers: LazyArray<rustc_span::DebuggerVisualizerFile>,
224231

225-
exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportInfo)]),
232+
exported_symbols: LazyArray<(ExportedSymbol<'tcx>, SymbolExportInfo)>,
226233

227234
syntax_contexts: SyntaxContextTable,
228235
expn_data: ExpnDataTable,
229236
expn_hashes: ExpnHashTable,
230237

231-
def_path_hash_map: Lazy<DefPathHashMapRef<'tcx>>,
238+
def_path_hash_map: LazyValue<DefPathHashMapRef<'tcx>>,
232239

233-
source_map: Lazy<[rustc_span::SourceFile]>,
240+
source_map: LazyArray<rustc_span::SourceFile>,
234241

235242
compiler_builtins: bool,
236243
needs_allocator: bool,
@@ -257,7 +264,12 @@ impl Into<RawDefId> for DefId {
257264
}
258265

259266
impl RawDefId {
260-
fn decode(self, cdata: CrateMetadataRef<'_>) -> DefId {
267+
/// This exists so that `provide_one!` is happy
268+
fn decode(self, meta: (CrateMetadataRef<'_>, TyCtxt<'_>)) -> DefId {
269+
self.decode_from_cdata(meta.0)
270+
}
271+
272+
fn decode_from_cdata(self, cdata: CrateMetadataRef<'_>) -> DefId {
261273
let krate = CrateNum::from_u32(self.krate);
262274
let krate = cdata.map_encoded_cnum_to_current(krate);
263275
DefId { krate, index: DefIndex::from_u32(self.index) }
@@ -276,21 +288,21 @@ pub(crate) struct CrateDep {
276288
#[derive(MetadataEncodable, MetadataDecodable)]
277289
pub(crate) struct TraitImpls {
278290
trait_id: (u32, DefIndex),
279-
impls: Lazy<[(DefIndex, Option<SimplifiedType>)]>,
291+
impls: LazyArray<(DefIndex, Option<SimplifiedType>)>,
280292
}
281293

282294
#[derive(MetadataEncodable, MetadataDecodable)]
283295
pub(crate) struct IncoherentImpls {
284296
self_ty: SimplifiedType,
285-
impls: Lazy<[DefIndex]>,
297+
impls: LazyArray<DefIndex>,
286298
}
287299

288300
/// Define `LazyTables` and `TableBuilders` at the same time.
289301
macro_rules! define_tables {
290302
($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
291303
#[derive(MetadataEncodable, MetadataDecodable)]
292304
pub(crate) struct LazyTables<'tcx> {
293-
$($name: Lazy!(Table<$IDX, $T>)),+
305+
$($name: LazyTable<$IDX, $T>),+
294306
}
295307

296308
#[derive(Default)]
@@ -309,61 +321,62 @@ macro_rules! define_tables {
309321
}
310322

311323
define_tables! {
312-
kind: Table<DefIndex, Lazy<EntryKind>>,
313-
attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
314-
children: Table<DefIndex, Lazy<[DefIndex]>>,
324+
kind: Table<DefIndex, LazyValue<EntryKind>>,
325+
attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
326+
children: Table<DefIndex, LazyArray<DefIndex>>,
315327

316328
opt_def_kind: Table<DefIndex, DefKind>,
317-
visibility: Table<DefIndex, Lazy<ty::Visibility>>,
318-
def_span: Table<DefIndex, Lazy<Span>>,
319-
def_ident_span: Table<DefIndex, Lazy<Span>>,
320-
lookup_stability: Table<DefIndex, Lazy<attr::Stability>>,
321-
lookup_const_stability: Table<DefIndex, Lazy<attr::ConstStability>>,
322-
lookup_deprecation_entry: Table<DefIndex, Lazy<attr::Deprecation>>,
329+
visibility: Table<DefIndex, LazyValue<ty::Visibility>>,
330+
def_span: Table<DefIndex, LazyValue<Span>>,
331+
def_ident_span: Table<DefIndex, LazyValue<Span>>,
332+
lookup_stability: Table<DefIndex, LazyValue<attr::Stability>>,
333+
lookup_const_stability: Table<DefIndex, LazyValue<attr::ConstStability>>,
334+
lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
323335
// As an optimization, a missing entry indicates an empty `&[]`.
324-
explicit_item_bounds: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
325-
explicit_predicates_of: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
326-
generics_of: Table<DefIndex, Lazy<ty::Generics>>,
336+
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'tcx>, Span)>>,
337+
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'tcx>>>,
338+
generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
327339
// As an optimization, a missing entry indicates an empty `&[]`.
328-
inferred_outlives_of: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
329-
super_predicates_of: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
330-
type_of: Table<DefIndex, Lazy!(Ty<'tcx>)>,
331-
variances_of: Table<DefIndex, Lazy<[ty::Variance]>>,
332-
fn_sig: Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>,
333-
codegen_fn_attrs: Table<DefIndex, Lazy!(CodegenFnAttrs)>,
334-
impl_trait_ref: Table<DefIndex, Lazy!(ty::TraitRef<'tcx>)>,
335-
const_param_default: Table<DefIndex, Lazy<rustc_middle::ty::Const<'tcx>>>,
336-
optimized_mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
337-
mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
338-
promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
339-
thir_abstract_const: Table<DefIndex, Lazy!(&'tcx [thir::abstract_const::Node<'tcx>])>,
340+
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Predicate<'tcx>, Span)>>,
341+
super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'tcx>>>,
342+
type_of: Table<DefIndex, LazyValue<Ty<'tcx>>>,
343+
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
344+
fn_sig: Table<DefIndex, LazyValue<ty::PolyFnSig<'tcx>>>,
345+
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
346+
impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'tcx>>>,
347+
const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'tcx>>>,
348+
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'tcx>>>,
349+
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'tcx>>>,
350+
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
351+
// FIXME(compiler-errors): Why isn't this a LazyArray?
352+
thir_abstract_const: Table<DefIndex, LazyValue<&'tcx [thir::abstract_const::Node<'tcx>]>>,
340353
impl_parent: Table<DefIndex, RawDefId>,
341354
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
342355
impl_constness: Table<DefIndex, hir::Constness>,
343356
is_intrinsic: Table<DefIndex, ()>,
344357
impl_defaultness: Table<DefIndex, hir::Defaultness>,
345358
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
346-
coerce_unsized_info: Table<DefIndex, Lazy!(ty::adjustment::CoerceUnsizedInfo)>,
347-
mir_const_qualif: Table<DefIndex, Lazy!(mir::ConstQualifs)>,
348-
rendered_const: Table<DefIndex, Lazy!(String)>,
359+
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
360+
mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,
361+
rendered_const: Table<DefIndex, LazyValue<String>>,
349362
asyncness: Table<DefIndex, hir::IsAsync>,
350-
fn_arg_names: Table<DefIndex, Lazy!([Ident])>,
351-
generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>,
352-
trait_def: Table<DefIndex, Lazy!(ty::TraitDef)>,
363+
fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
364+
generator_kind: Table<DefIndex, LazyValue<hir::GeneratorKind>>,
365+
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
353366

354367
trait_item_def_id: Table<DefIndex, RawDefId>,
355-
inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
356-
expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
357-
unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
358-
repr_options: Table<DefIndex, Lazy<ReprOptions>>,
368+
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
369+
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
370+
unused_generic_params: Table<DefIndex, LazyValue<FiniteBitSet<u32>>>,
371+
repr_options: Table<DefIndex, LazyValue<ReprOptions>>,
359372
// `def_keys` and `def_path_hashes` represent a lazy version of a
360373
// `DefPathTable`. This allows us to avoid deserializing an entire
361374
// `DefPathTable` up front, since we may only ever use a few
362375
// definitions from any given crate.
363-
def_keys: Table<DefIndex, Lazy<DefKey>>,
376+
def_keys: Table<DefIndex, LazyValue<DefKey>>,
364377
def_path_hashes: Table<DefIndex, DefPathHash>,
365-
proc_macro_quoted_spans: Table<usize, Lazy<Span>>,
366-
generator_diagnostic_data: Table<DefIndex, Lazy<GeneratorDiagnosticData<'tcx>>>,
378+
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
379+
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'tcx>>>,
367380
may_have_doc_links: Table<DefIndex, ()>,
368381
}
369382

@@ -382,19 +395,19 @@ enum EntryKind {
382395
OpaqueTy,
383396
Enum,
384397
Field,
385-
Variant(Lazy<VariantData>),
386-
Struct(Lazy<VariantData>),
387-
Union(Lazy<VariantData>),
398+
Variant(LazyValue<VariantData>),
399+
Struct(LazyValue<VariantData>),
400+
Union(LazyValue<VariantData>),
388401
Fn,
389402
ForeignFn,
390-
Mod(Lazy<[ModChild]>),
391-
MacroDef(Lazy<ast::MacArgs>, /*macro_rules*/ bool),
403+
Mod(LazyArray<ModChild>),
404+
MacroDef(LazyValue<ast::MacArgs>, /*macro_rules*/ bool),
392405
ProcMacro(MacroKind),
393406
Closure,
394407
Generator,
395408
Trait,
396409
Impl,
397-
AssocFn(Lazy<AssocFnData>),
410+
AssocFn(LazyValue<AssocFnData>),
398411
AssocType(AssocContainer),
399412
AssocConst(AssocContainer),
400413
TraitAlias,

‎compiler/rustc_metadata/src/rmeta/table.rs

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,15 @@ impl FixedSizeEncoding for Option<()> {
201201
}
202202

203203
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
204-
// generic `Lazy<T>` impl, but in the general case we might not need / want to
205-
// fit every `usize` in `u32`.
206-
impl<T> FixedSizeEncoding for Option<Lazy<T>> {
204+
// generic `LazyValue<T>` impl, but in the general case we might not need / want
205+
// to fit every `usize` in `u32`.
206+
impl<T> FixedSizeEncoding for Option<LazyValue<T>> {
207207
type ByteArray = [u8; 4];
208208

209209
#[inline]
210210
fn from_bytes(b: &[u8; 4]) -> Self {
211211
let position = NonZeroUsize::new(u32::from_bytes(b) as usize)?;
212-
Some(Lazy::from_position(position))
212+
Some(LazyValue::from_position(position))
213213
}
214214

215215
#[inline]
@@ -220,15 +220,15 @@ impl<T> FixedSizeEncoding for Option<Lazy<T>> {
220220
}
221221
}
222222

223-
impl<T> FixedSizeEncoding for Option<Lazy<[T]>> {
223+
impl<T> FixedSizeEncoding for Option<LazyArray<T>> {
224224
type ByteArray = [u8; 8];
225225

226226
#[inline]
227227
fn from_bytes(b: &[u8; 8]) -> Self {
228228
let ([ref position_bytes, ref meta_bytes],[])= b.as_chunks::<4>() else { panic!() };
229229
let position = NonZeroUsize::new(u32::from_bytes(position_bytes) as usize)?;
230230
let len = u32::from_bytes(meta_bytes) as usize;
231-
Some(Lazy::from_position_and_meta(position, len))
231+
Some(LazyArray::from_position_and_num_elems(position, len))
232232
}
233233

234234
#[inline]
@@ -239,28 +239,12 @@ impl<T> FixedSizeEncoding for Option<Lazy<[T]>> {
239239
let position: u32 = position.try_into().unwrap();
240240
position.write_to_bytes(position_bytes);
241241

242-
let len = self.map_or(0, |lazy| lazy.meta);
242+
let len = self.map_or(0, |lazy| lazy.num_elems);
243243
let len: u32 = len.try_into().unwrap();
244244
len.write_to_bytes(meta_bytes);
245245
}
246246
}
247247

248-
/// Random-access table (i.e. offering constant-time `get`/`set`), similar to
249-
/// `Vec<Option<T>>`, but without requiring encoding or decoding all the values
250-
/// eagerly and in-order.
251-
/// A total of `(max_idx + 1)` times `Option<T> as FixedSizeEncoding>::ByteArray`
252-
/// are used for a table, where `max_idx` is the largest index passed to
253-
/// `TableBuilder::set`.
254-
pub(super) struct Table<I: Idx, T>
255-
where
256-
Option<T>: FixedSizeEncoding,
257-
{
258-
_marker: PhantomData<(fn(&I), T)>,
259-
// NOTE(eddyb) this makes `Table` not implement `Sized`, but no
260-
// value of `Table` is ever created (it's always behind `Lazy`).
261-
_bytes: [u8],
262-
}
263-
264248
/// Helper for constructing a table's serialization (also see `Table`).
265249
pub(super) struct TableBuilder<I: Idx, T>
266250
where
@@ -296,7 +280,7 @@ where
296280
Some(value).write_to_bytes(&mut self.blocks[i]);
297281
}
298282

299-
pub(crate) fn encode<const N: usize>(&self, buf: &mut Encoder) -> Lazy<Table<I, T>>
283+
pub(crate) fn encode<const N: usize>(&self, buf: &mut Encoder) -> LazyTable<I, T>
300284
where
301285
Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
302286
{
@@ -305,19 +289,14 @@ where
305289
buf.emit_raw_bytes(block).unwrap();
306290
}
307291
let num_bytes = self.blocks.len() * N;
308-
Lazy::from_position_and_meta(NonZeroUsize::new(pos as usize).unwrap(), num_bytes)
292+
LazyTable::from_position_and_encoded_size(
293+
NonZeroUsize::new(pos as usize).unwrap(),
294+
num_bytes,
295+
)
309296
}
310297
}
311298

312-
impl<I: Idx, T> LazyMeta for Table<I, T>
313-
where
314-
Option<T>: FixedSizeEncoding,
315-
{
316-
/// Number of bytes in the data stream.
317-
type Meta = usize;
318-
}
319-
320-
impl<I: Idx, T> Lazy<Table<I, T>>
299+
impl<I: Idx, T> LazyTable<I, T>
321300
where
322301
Option<T>: FixedSizeEncoding,
323302
{
@@ -331,10 +310,10 @@ where
331310
where
332311
Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
333312
{
334-
debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
313+
debug!("LazyTable::lookup: index={:?} len={:?}", i, self.encoded_size);
335314

336315
let start = self.position.get();
337-
let bytes = &metadata.blob()[start..start + self.meta];
316+
let bytes = &metadata.blob()[start..start + self.encoded_size];
338317
let (bytes, []) = bytes.as_chunks::<N>() else { panic!() };
339318
let bytes = bytes.get(i.index())?;
340319
FixedSizeEncoding::from_bytes(bytes)
@@ -345,6 +324,6 @@ where
345324
where
346325
Option<T>: FixedSizeEncoding<ByteArray = [u8; N]>,
347326
{
348-
self.meta / N
327+
self.encoded_size / N
349328
}
350329
}

0 commit comments

Comments
 (0)
Please sign in to comment.