Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Lazy*<T> types in rustc_metadata not care about lifetimes until decode #97376

Merged
merged 1 commit into from
May 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl<'a> CrateLoader<'a> {
None
}

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

fn verify_no_stable_crate_id_hash_conflicts(
&mut self,
root: &CrateRoot<'_>,
root: &CrateRoot,
cnum: CrateNum,
) -> Result<(), CrateError> {
if let Some(existing) = self.cstore.stable_crate_ids.insert(root.stable_crate_id(), cnum) {
Expand Down Expand Up @@ -623,7 +623,7 @@ impl<'a> CrateLoader<'a> {
fn resolve_crate_deps(
&mut self,
root: &CratePaths,
crate_root: &CrateRoot<'_>,
crate_root: &CrateRoot,
metadata: &MetadataBlob,
krate: CrateNum,
dep_kind: CrateDepKind,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(decl_macro)]
#![feature(drain_filter)]
#![feature(generators)]
#![feature(generic_associated_types)]
#![feature(let_chains)]
#![feature(let_else)]
#![feature(nll)]
Expand Down
34 changes: 23 additions & 11 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_middle::thir;
use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::GeneratorDiagnosticData;
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility};
use rustc_serialize::{opaque, Decodable, Decoder};
use rustc_session::cstore::{
CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib,
Expand Down Expand Up @@ -86,7 +86,7 @@ pub(crate) struct CrateMetadata {
/// lifetime is only used behind `Lazy`, and therefore acts like a
/// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
/// is being used to decode those values.
root: CrateRoot<'static>,
root: CrateRoot,
/// Trait impl data.
/// FIXME: Used only from queries and can use query cache,
/// so pre-decoding can probably be avoided.
Expand Down Expand Up @@ -261,11 +261,14 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
}
}

impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> LazyValue<T> {
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
impl<T: ParameterizedOverTcx> LazyValue<T> {
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx>
where
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
T::decode(&mut dcx)
T::Value::decode(&mut dcx)
}
}

Expand All @@ -292,15 +295,24 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Iterator for DecodeIterato
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> ExactSizeIterator
for DecodeIterator<'a, 'tcx, T>
{
fn len(&self) -> usize {
self.elem_counter.len()
}
}

unsafe impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> TrustedLen
for DecodeIterator<'a, 'tcx, T>
{
}

impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> LazyArray<T> {
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> DecodeIterator<'a, 'tcx, T> {
impl<T: ParameterizedOverTcx> LazyArray<T> {
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(
self,
metadata: M,
) -> DecodeIterator<'a, 'tcx, T::Value<'tcx>>
where
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
DecodeIterator { elem_counter: (0..self.num_elems), dcx, _phantom: PhantomData }
Expand Down Expand Up @@ -671,14 +683,14 @@ impl MetadataBlob {
.decode(self)
}

pub(crate) fn get_root<'tcx>(&self) -> CrateRoot<'tcx> {
pub(crate) fn get_root(&self) -> CrateRoot {
let slice = &self.blob()[..];
let offset = METADATA_HEADER.len();
let pos = (((slice[offset + 0] as u32) << 24)
| ((slice[offset + 1] as u32) << 16)
| ((slice[offset + 2] as u32) << 8)
| ((slice[offset + 3] as u32) << 0)) as usize;
LazyValue::<CrateRoot<'tcx>>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
LazyValue::<CrateRoot>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
}

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

impl CrateRoot<'_> {
impl CrateRoot {
pub(crate) fn is_proc_macro_crate(&self) -> bool {
self.proc_macro_data.is_some()
}
Expand Down Expand Up @@ -1677,7 +1689,7 @@ impl CrateMetadata {
sess: &Session,
cstore: &CStore,
blob: MetadataBlob,
root: CrateRoot<'static>,
root: CrateRoot,
raw_proc_macros: Option<&'static [ProcMacro]>,
cnum: CrateNum,
cnum_map: CrateNumMap,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::rmeta::EncodeContext;
use crate::rmeta::MetadataBlob;
use rustc_data_structures::owning_ref::OwningRef;
use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
use rustc_middle::parameterized_over_tcx;
use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
use rustc_span::def_id::{DefIndex, DefPathHash};

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

parameterized_over_tcx! {
DefPathHashMapRef,
}

impl DefPathHashMapRef<'_> {
#[inline]
pub fn def_path_hash_to_def_index(&self, def_path_hash: &DefPathHash) -> DefIndex {
Expand Down
27 changes: 13 additions & 14 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub(super) struct EncodeContext<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
feat: &'tcx rustc_feature::Features,

tables: TableBuilders<'tcx>,
tables: TableBuilders,

lazy_state: LazyState,
type_shorthands: FxHashMap<Ty<'tcx>, usize>,
Expand Down Expand Up @@ -388,10 +388,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.emit_usize(distance)
}

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

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

fn lazy_array<
T: Encodable<EncodeContext<'a, 'tcx>>,
I: IntoIterator<Item = B>,
B: Borrow<T>,
>(
fn lazy_array<T: ParameterizedOverTcx, I: IntoIterator<Item = B>, B: Borrow<T::Value<'tcx>>>(
&mut self,
values: I,
) -> LazyArray<T> {
) -> LazyArray<T>
where
T::Value<'tcx>: Encodable<EncodeContext<'a, 'tcx>>,
{
let pos = NonZeroUsize::new(self.position()).unwrap();

assert_eq!(self.lazy_state, LazyState::NoNode);
Expand Down Expand Up @@ -456,7 +455,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
}

fn encode_def_path_hash_map(&mut self) -> LazyValue<DefPathHashMapRef<'tcx>> {
fn encode_def_path_hash_map(&mut self) -> LazyValue<DefPathHashMapRef<'static>> {
self.lazy(DefPathHashMapRef::BorrowedFromTcx(
self.tcx.resolutions(()).definitions.def_path_hash_to_def_index_map(),
))
Expand Down Expand Up @@ -535,7 +534,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.lazy_array(adapted.iter().map(|rc| &**rc))
}

fn encode_crate_root(&mut self) -> LazyValue<CrateRoot<'tcx>> {
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
let tcx = self.tcx;
let mut i = self.position();

Expand Down Expand Up @@ -1859,7 +1858,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_exported_symbols(
&mut self,
exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportInfo)],
) -> LazyArray<(ExportedSymbol<'tcx>, SymbolExportInfo)> {
) -> LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)> {
empty_proc_macro!(self);
// The metadata symbol name is special. It should not show up in
// downstream crates.
Expand Down
67 changes: 45 additions & 22 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_middle::thir;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, ReprOptions, Ty};
use rustc_middle::ty::{GeneratorDiagnosticData, TyCtxt};
use rustc_middle::ty::{GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
use rustc_serialize::opaque::Encoder;
use rustc_session::config::SymbolManglingVersion;
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
Expand Down Expand Up @@ -83,6 +83,10 @@ struct LazyValue<T> {
_marker: PhantomData<fn() -> T>,
}

impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyValue<T> {
type Value<'tcx> = LazyValue<T::Value<'tcx>>;
}

impl<T> LazyValue<T> {
fn from_position(position: NonZeroUsize) -> LazyValue<T> {
LazyValue { position, _marker: PhantomData }
Expand All @@ -105,6 +109,10 @@ struct LazyArray<T> {
_marker: PhantomData<fn() -> T>,
}

impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyArray<T> {
type Value<'tcx> = LazyArray<T::Value<'tcx>>;
}

impl<T> LazyArray<T> {
fn from_position_and_num_elems(position: NonZeroUsize, num_elems: usize) -> LazyArray<T> {
LazyArray { position, num_elems, _marker: PhantomData }
Expand All @@ -126,6 +134,10 @@ struct LazyTable<I, T> {
_marker: PhantomData<fn(I) -> T>,
}

impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for LazyTable<I, T> {
type Value<'tcx> = LazyTable<I, T::Value<'tcx>>;
}

impl<I, T> LazyTable<I, T> {
fn from_position_and_encoded_size(
position: NonZeroUsize,
Expand Down Expand Up @@ -199,7 +211,7 @@ pub(crate) struct ProcMacroData {
/// a normal crate, much of what we serialized would be unusable in addition
/// to being unused.
#[derive(MetadataEncodable, MetadataDecodable)]
pub(crate) struct CrateRoot<'tcx> {
pub(crate) struct CrateRoot {
name: Symbol,
triple: TargetTriple,
extra_filename: String,
Expand All @@ -226,16 +238,16 @@ pub(crate) struct CrateRoot<'tcx> {
interpret_alloc_index: LazyArray<u32>,
proc_macro_data: Option<ProcMacroData>,

tables: LazyTables<'tcx>,
tables: LazyTables,
debugger_visualizers: LazyArray<rustc_span::DebuggerVisualizerFile>,

exported_symbols: LazyArray<(ExportedSymbol<'tcx>, SymbolExportInfo)>,
exported_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,

syntax_contexts: SyntaxContextTable,
expn_data: ExpnDataTable,
expn_hashes: ExpnHashTable,

def_path_hash_map: LazyValue<DefPathHashMapRef<'tcx>>,
def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,

source_map: LazyArray<rustc_span::SourceFile>,

Expand Down Expand Up @@ -301,17 +313,17 @@ pub(crate) struct IncoherentImpls {
macro_rules! define_tables {
($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
#[derive(MetadataEncodable, MetadataDecodable)]
pub(crate) struct LazyTables<'tcx> {
pub(crate) struct LazyTables {
$($name: LazyTable<$IDX, $T>),+
}

#[derive(Default)]
struct TableBuilders<'tcx> {
struct TableBuilders {
$($name: TableBuilder<$IDX, $T>),+
}

impl<'tcx> TableBuilders<'tcx> {
fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
impl TableBuilders {
fn encode(&self, buf: &mut Encoder) -> LazyTables {
LazyTables {
$($name: self.$name.encode(buf)),+
}
Expand All @@ -333,23 +345,23 @@ define_tables! {
lookup_const_stability: Table<DefIndex, LazyValue<attr::ConstStability>>,
lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
// As an optimization, a missing entry indicates an empty `&[]`.
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'tcx>, Span)>>,
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'tcx>>>,
explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
// As an optimization, a missing entry indicates an empty `&[]`.
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Predicate<'tcx>, Span)>>,
super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'tcx>>>,
type_of: Table<DefIndex, LazyValue<Ty<'tcx>>>,
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
type_of: Table<DefIndex, LazyValue<Ty<'static>>>,
variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
fn_sig: Table<DefIndex, LazyValue<ty::PolyFnSig<'tcx>>>,
fn_sig: Table<DefIndex, LazyValue<ty::PolyFnSig<'static>>>,
codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'tcx>>>,
const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'tcx>>>,
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'tcx>>>,
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'tcx>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'static>>>,
const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'static>>>,
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
// FIXME(compiler-errors): Why isn't this a LazyArray?
thir_abstract_const: Table<DefIndex, LazyValue<&'tcx [thir::abstract_const::Node<'tcx>]>>,
thir_abstract_const: Table<DefIndex, LazyValue<&'static [thir::abstract_const::Node<'static>]>>,
impl_parent: Table<DefIndex, RawDefId>,
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
impl_constness: Table<DefIndex, hir::Constness>,
Expand All @@ -376,7 +388,7 @@ define_tables! {
def_keys: Table<DefIndex, LazyValue<DefKey>>,
def_path_hashes: Table<DefIndex, DefPathHash>,
proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'tcx>>>,
generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
may_have_doc_links: Table<DefIndex, ()>,
}

Expand Down Expand Up @@ -477,3 +489,14 @@ pub fn provide(providers: &mut Providers) {
encoder::provide(providers);
decoder::provide(providers);
}

trivially_parameterized_over_tcx! {
VariantData,
AssocFnData,
EntryKind,
RawDefId,
TraitImpls,
IncoherentImpls,
CrateRoot,
CrateDep,
}
Loading