Skip to content

Commit ee9726c

Browse files
committed
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

+1
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

+60-146
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
})

0 commit comments

Comments
 (0)