Skip to content

Commit 9fadabc

Browse files
committed
Auto merge of #97376 - compiler-errors:lazy-polymorphic, r=jackh726
Make `Lazy*<T>` types in `rustc_metadata` not care about lifetimes until decode This allows us to remove the `'tcx` lifetime from `CrateRoot`. This is necessary because of #97287, which makes the `'tcx` lifetime on `Ty` invariant instead of covariant, so [this hack](https://github.com/rust-lang/rust/blob/0a437b2ca081bc12425a3318cb66aade9824cbae/compiler/rustc_metadata/src/rmeta/decoder.rs#L89-92) no longer holds under that PR. Introduces a trait called `ParameterizedOverTcx` which has a generic associated type that allows a type to be parameterized over that lifetime. This means we can decode, for example, `Lazy<Ty<'static>>` into any `Ty<'tcx>` depending on the `TyCtxt<'tcx>` we pass into the decode function.
2 parents 6ac8ada + d1a9a95 commit 9fadabc

File tree

10 files changed

+217
-54
lines changed

10 files changed

+217
-54
lines changed

compiler/rustc_metadata/src/creader.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl<'a> CrateLoader<'a> {
323323
None
324324
}
325325

326-
fn verify_no_symbol_conflicts(&self, root: &CrateRoot<'_>) -> Result<(), CrateError> {
326+
fn verify_no_symbol_conflicts(&self, root: &CrateRoot) -> Result<(), CrateError> {
327327
// Check for (potential) conflicts with the local crate
328328
if self.sess.local_stable_crate_id() == root.stable_crate_id() {
329329
return Err(CrateError::SymbolConflictsCurrent(root.name()));
@@ -342,7 +342,7 @@ impl<'a> CrateLoader<'a> {
342342

343343
fn verify_no_stable_crate_id_hash_conflicts(
344344
&mut self,
345-
root: &CrateRoot<'_>,
345+
root: &CrateRoot,
346346
cnum: CrateNum,
347347
) -> Result<(), CrateError> {
348348
if let Some(existing) = self.cstore.stable_crate_ids.insert(root.stable_crate_id(), cnum) {
@@ -623,7 +623,7 @@ impl<'a> CrateLoader<'a> {
623623
fn resolve_crate_deps(
624624
&mut self,
625625
root: &CratePaths,
626-
crate_root: &CrateRoot<'_>,
626+
crate_root: &CrateRoot,
627627
metadata: &MetadataBlob,
628628
krate: CrateNum,
629629
dep_kind: CrateDepKind,

compiler/rustc_metadata/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![feature(decl_macro)]
33
#![feature(drain_filter)]
44
#![feature(generators)]
5+
#![feature(generic_associated_types)]
56
#![feature(let_chains)]
67
#![feature(let_else)]
78
#![feature(nll)]

compiler/rustc_metadata/src/rmeta/decoder.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_middle::thir;
2525
use rustc_middle::ty::codec::TyDecoder;
2626
use rustc_middle::ty::fast_reject::SimplifiedType;
2727
use rustc_middle::ty::GeneratorDiagnosticData;
28-
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
28+
use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility};
2929
use rustc_serialize::{opaque, Decodable, Decoder};
3030
use rustc_session::cstore::{
3131
CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib,
@@ -86,7 +86,7 @@ pub(crate) struct CrateMetadata {
8686
/// lifetime is only used behind `Lazy`, and therefore acts like a
8787
/// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
8888
/// is being used to decode those values.
89-
root: CrateRoot<'static>,
89+
root: CrateRoot,
9090
/// Trait impl data.
9191
/// FIXME: Used only from queries and can use query cache,
9292
/// so pre-decoding can probably be avoided.
@@ -261,11 +261,14 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
261261
}
262262
}
263263

264-
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> LazyValue<T> {
265-
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
264+
impl<T: ParameterizedOverTcx> LazyValue<T> {
265+
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx>
266+
where
267+
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
268+
{
266269
let mut dcx = metadata.decoder(self.position.get());
267270
dcx.lazy_state = LazyState::NodeStart(self.position);
268-
T::decode(&mut dcx)
271+
T::Value::decode(&mut dcx)
269272
}
270273
}
271274

@@ -292,15 +295,24 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Iterator for DecodeIterato
292295
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> ExactSizeIterator
293296
for DecodeIterator<'a, 'tcx, T>
294297
{
298+
fn len(&self) -> usize {
299+
self.elem_counter.len()
300+
}
295301
}
296302

297303
unsafe impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> TrustedLen
298304
for DecodeIterator<'a, 'tcx, T>
299305
{
300306
}
301307

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> {
308+
impl<T: ParameterizedOverTcx> LazyArray<T> {
309+
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(
310+
self,
311+
metadata: M,
312+
) -> DecodeIterator<'a, 'tcx, T::Value<'tcx>>
313+
where
314+
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
315+
{
304316
let mut dcx = metadata.decoder(self.position.get());
305317
dcx.lazy_state = LazyState::NodeStart(self.position);
306318
DecodeIterator { elem_counter: (0..self.num_elems), dcx, _phantom: PhantomData }
@@ -671,14 +683,14 @@ impl MetadataBlob {
671683
.decode(self)
672684
}
673685

674-
pub(crate) fn get_root<'tcx>(&self) -> CrateRoot<'tcx> {
686+
pub(crate) fn get_root(&self) -> CrateRoot {
675687
let slice = &self.blob()[..];
676688
let offset = METADATA_HEADER.len();
677689
let pos = (((slice[offset + 0] as u32) << 24)
678690
| ((slice[offset + 1] as u32) << 16)
679691
| ((slice[offset + 2] as u32) << 8)
680692
| ((slice[offset + 3] as u32) << 0)) as usize;
681-
LazyValue::<CrateRoot<'tcx>>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
693+
LazyValue::<CrateRoot>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
682694
}
683695

684696
pub(crate) fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
@@ -705,7 +717,7 @@ impl MetadataBlob {
705717
}
706718
}
707719

708-
impl CrateRoot<'_> {
720+
impl CrateRoot {
709721
pub(crate) fn is_proc_macro_crate(&self) -> bool {
710722
self.proc_macro_data.is_some()
711723
}
@@ -1677,7 +1689,7 @@ impl CrateMetadata {
16771689
sess: &Session,
16781690
cstore: &CStore,
16791691
blob: MetadataBlob,
1680-
root: CrateRoot<'static>,
1692+
root: CrateRoot,
16811693
raw_proc_macros: Option<&'static [ProcMacro]>,
16821694
cnum: CrateNum,
16831695
cnum_map: CrateNumMap,

compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::rmeta::EncodeContext;
33
use crate::rmeta::MetadataBlob;
44
use rustc_data_structures::owning_ref::OwningRef;
55
use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
6+
use rustc_middle::parameterized_over_tcx;
67
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
78
use rustc_span::def_id::{DefIndex, DefPathHash};
89

@@ -11,6 +12,10 @@ pub(crate) enum DefPathHashMapRef<'tcx> {
1112
BorrowedFromTcx(&'tcx DefPathHashMap),
1213
}
1314

15+
parameterized_over_tcx! {
16+
DefPathHashMapRef,
17+
}
18+
1419
impl DefPathHashMapRef<'_> {
1520
#[inline]
1621
pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {

compiler/rustc_metadata/src/rmeta/encoder.rs

+13-14
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub(super) struct EncodeContext<'a, 'tcx> {
4747
tcx: TyCtxt<'tcx>,
4848
feat: &'tcx rustc_feature::Features,
4949

50-
tables: TableBuilders<'tcx>,
50+
tables: TableBuilders,
5151

5252
lazy_state: LazyState,
5353
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
@@ -388,10 +388,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
388388
self.emit_usize(distance)
389389
}
390390

391-
fn lazy<T: Encodable<EncodeContext<'a, 'tcx>>, B: Borrow<T>>(
392-
&mut self,
393-
value: B,
394-
) -> LazyValue<T> {
391+
fn lazy<T: ParameterizedOverTcx, B: Borrow<T::Value<'tcx>>>(&mut self, value: B) -> LazyValue<T>
392+
where
393+
T::Value<'tcx>: Encodable<EncodeContext<'a, 'tcx>>,
394+
{
395395
let pos = NonZeroUsize::new(self.position()).unwrap();
396396

397397
assert_eq!(self.lazy_state, LazyState::NoNode);
@@ -404,14 +404,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
404404
LazyValue::from_position(pos)
405405
}
406406

407-
fn lazy_array<
408-
T: Encodable<EncodeContext<'a, 'tcx>>,
409-
I: IntoIterator<Item = B>,
410-
B: Borrow<T>,
411-
>(
407+
fn lazy_array<T: ParameterizedOverTcx, I: IntoIterator<Item = B>, B: Borrow<T::Value<'tcx>>>(
412408
&mut self,
413409
values: I,
414-
) -> LazyArray<T> {
410+
) -> LazyArray<T>
411+
where
412+
T::Value<'tcx>: Encodable<EncodeContext<'a, 'tcx>>,
413+
{
415414
let pos = NonZeroUsize::new(self.position()).unwrap();
416415

417416
assert_eq!(self.lazy_state, LazyState::NoNode);
@@ -456,7 +455,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
456455
}
457456
}
458457

459-
fn encode_def_path_hash_map(&mut self) -> LazyValue<DefPathHashMapRef<'tcx>> {
458+
fn encode_def_path_hash_map(&mut self) -> LazyValue<DefPathHashMapRef<'static>> {
460459
self.lazy(DefPathHashMapRef::BorrowedFromTcx(
461460
self.tcx.resolutions(()).definitions.def_path_hash_to_def_index_map(),
462461
))
@@ -535,7 +534,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
535534
self.lazy_array(adapted.iter().map(|rc| &**rc))
536535
}
537536

538-
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot<'tcx>> {
537+
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
539538
let tcx = self.tcx;
540539
let mut i = self.position();
541540

@@ -1859,7 +1858,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18591858
fn encode_exported_symbols(
18601859
&mut self,
18611860
exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportInfo)],
1862-
) -> LazyArray<(ExportedSymbol<'tcx>, SymbolExportInfo)> {
1861+
) -> LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)> {
18631862
empty_proc_macro!(self);
18641863
// The metadata symbol name is special. It should not show up in
18651864
// downstream crates.

compiler/rustc_metadata/src/rmeta/mod.rs

+45-22
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_middle::thir;
2121
use rustc_middle::ty::fast_reject::SimplifiedType;
2222
use rustc_middle::ty::query::Providers;
2323
use rustc_middle::ty::{self, ReprOptions, Ty};
24-
use rustc_middle::ty::{GeneratorDiagnosticData, TyCtxt};
24+
use rustc_middle::ty::{GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
2525
use rustc_serialize::opaque::Encoder;
2626
use rustc_session::config::SymbolManglingVersion;
2727
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
@@ -83,6 +83,10 @@ struct LazyValue<T> {
8383
_marker: PhantomData<fn() -> T>,
8484
}
8585

86+
impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyValue<T> {
87+
type Value<'tcx> = LazyValue<T::Value<'tcx>>;
88+
}
89+
8690
impl<T> LazyValue<T> {
8791
fn from_position(position: NonZeroUsize) -> LazyValue<T> {
8892
LazyValue { position, _marker: PhantomData }
@@ -105,6 +109,10 @@ struct LazyArray<T> {
105109
_marker: PhantomData<fn() -> T>,
106110
}
107111

112+
impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyArray<T> {
113+
type Value<'tcx> = LazyArray<T::Value<'tcx>>;
114+
}
115+
108116
impl<T> LazyArray<T> {
109117
fn from_position_and_num_elems(position: NonZeroUsize, num_elems: usize) -> LazyArray<T> {
110118
LazyArray { position, num_elems, _marker: PhantomData }
@@ -126,6 +134,10 @@ struct LazyTable<I, T> {
126134
_marker: PhantomData<fn(I) -> T>,
127135
}
128136

137+
impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for LazyTable<I, T> {
138+
type Value<'tcx> = LazyTable<I, T::Value<'tcx>>;
139+
}
140+
129141
impl<I, T> LazyTable<I, T> {
130142
fn from_position_and_encoded_size(
131143
position: NonZeroUsize,
@@ -199,7 +211,7 @@ pub(crate) struct ProcMacroData {
199211
/// a normal crate, much of what we serialized would be unusable in addition
200212
/// to being unused.
201213
#[derive(MetadataEncodable, MetadataDecodable)]
202-
pub(crate) struct CrateRoot<'tcx> {
214+
pub(crate) struct CrateRoot {
203215
name: Symbol,
204216
triple: TargetTriple,
205217
extra_filename: String,
@@ -226,16 +238,16 @@ pub(crate) struct CrateRoot<'tcx> {
226238
interpret_alloc_index: LazyArray<u32>,
227239
proc_macro_data: Option<ProcMacroData>,
228240

229-
tables: LazyTables<'tcx>,
241+
tables: LazyTables,
230242
debugger_visualizers: LazyArray<rustc_span::DebuggerVisualizerFile>,
231243

232-
exported_symbols: LazyArray<(ExportedSymbol<'tcx>, SymbolExportInfo)>,
244+
exported_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,
233245

234246
syntax_contexts: SyntaxContextTable,
235247
expn_data: ExpnDataTable,
236248
expn_hashes: ExpnHashTable,
237249

238-
def_path_hash_map: LazyValue<DefPathHashMapRef<'tcx>>,
250+
def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,
239251

240252
source_map: LazyArray<rustc_span::SourceFile>,
241253

@@ -301,17 +313,17 @@ pub(crate) struct IncoherentImpls {
301313
macro_rules! define_tables {
302314
($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
303315
#[derive(MetadataEncodable, MetadataDecodable)]
304-
pub(crate) struct LazyTables<'tcx> {
316+
pub(crate) struct LazyTables {
305317
$($name: LazyTable<$IDX, $T>),+
306318
}
307319

308320
#[derive(Default)]
309-
struct TableBuilders<'tcx> {
321+
struct TableBuilders {
310322
$($name: TableBuilder<$IDX, $T>),+
311323
}
312324

313-
impl<'tcx> TableBuilders<'tcx> {
314-
fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
325+
impl TableBuilders {
326+
fn encode(&self, buf: &mut Encoder) -> LazyTables {
315327
LazyTables {
316328
$($name: self.$name.encode(buf)),+
317329
}
@@ -333,23 +345,23 @@ define_tables! {
333345
lookup_const_stability: Table<DefIndex, LazyValue<attr::ConstStability>>,
334346
lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
335347
// As an optimization, a missing entry indicates an empty `&[]`.
336-
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'tcx>, Span)>>,
337-
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'tcx>>>,
348+
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
349+
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
338350
generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
339351
// As an optimization, a missing entry indicates an empty `&[]`.
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>>>,
352+
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
353+
super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
354+
type_of: Table<DefIndex, LazyValue<Ty<'static>>>,
343355
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
344-
fn_sig: Table<DefIndex, LazyValue<ty::PolyFnSig<'tcx>>>,
356+
fn_sig: Table<DefIndex, LazyValue<ty::PolyFnSig<'static>>>,
345357
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>>>>,
358+
impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'static>>>,
359+
const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'static>>>,
360+
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
361+
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
362+
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
351363
// FIXME(compiler-errors): Why isn't this a LazyArray?
352-
thir_abstract_const: Table<DefIndex, LazyValue<&'tcx [thir::abstract_const::Node<'tcx>]>>,
364+
thir_abstract_const: Table<DefIndex, LazyValue<&'static [thir::abstract_const::Node<'static>]>>,
353365
impl_parent: Table<DefIndex, RawDefId>,
354366
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
355367
impl_constness: Table<DefIndex, hir::Constness>,
@@ -376,7 +388,7 @@ define_tables! {
376388
def_keys: Table<DefIndex, LazyValue<DefKey>>,
377389
def_path_hashes: Table<DefIndex, DefPathHash>,
378390
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
379-
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'tcx>>>,
391+
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
380392
may_have_doc_links: Table<DefIndex, ()>,
381393
}
382394

@@ -477,3 +489,14 @@ pub fn provide(providers: &mut Providers) {
477489
encoder::provide(providers);
478490
decoder::provide(providers);
479491
}
492+
493+
trivially_parameterized_over_tcx! {
494+
VariantData,
495+
AssocFnData,
496+
EntryKind,
497+
RawDefId,
498+
TraitImpls,
499+
IncoherentImpls,
500+
CrateRoot,
501+
CrateDep,
502+
}

0 commit comments

Comments
 (0)