From 67421bdfdf278f3737595c27a77d90bacd4215f3 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 13 Nov 2019 22:10:58 +0200 Subject: [PATCH 1/4] rustc_metadata: replace PerDefTable with Table. --- src/librustc_metadata/rmeta/decoder.rs | 8 +-- src/librustc_metadata/rmeta/encoder.rs | 54 +++++++++--------- src/librustc_metadata/rmeta/mod.rs | 41 +++++++------- src/librustc_metadata/rmeta/table.rs | 78 ++++++-------------------- 4 files changed, 68 insertions(+), 113 deletions(-) diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 7b0cf451ff918..47a48c1778666 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1,9 +1,9 @@ // Decoding metadata from a single crate's metadata use crate::rmeta::*; -use crate::rmeta::table::{FixedSizeEncoding, PerDefTable}; +use crate::rmeta::table::{FixedSizeEncoding, Table}; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::sync::{Lrc, Lock, Once, AtomicCell}; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir::map::definitions::DefPathTable; @@ -341,10 +341,10 @@ impl<'a, 'tcx, T: Encodable> SpecializedDecoder> for DecodeContext<'a, } } -impl<'a, 'tcx, T> SpecializedDecoder>> for DecodeContext<'a, 'tcx> +impl<'a, 'tcx, I: Idx, T> SpecializedDecoder>> for DecodeContext<'a, 'tcx> where Option: FixedSizeEncoding, { - fn specialized_decode(&mut self) -> Result>, Self::Error> { + fn specialized_decode(&mut self) -> Result>, Self::Error> { let len = self.read_usize()?; self.read_lazy_with_meta(len) } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 483915f654ddd..5feb54bb8fa2d 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1,5 +1,5 @@ use crate::rmeta::*; -use crate::rmeta::table::{FixedSizeEncoding, PerDefTable}; +use crate::rmeta::table::{FixedSizeEncoding, Table}; use rustc::middle::cstore::{LinkagePreference, NativeLibrary, EncodedMetadata, ForeignModule}; @@ -8,7 +8,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, use rustc::hir::{GenericParamKind, AnonConst}; use rustc::hir::map::definitions::DefPathTable; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{Idx, IndexVec}; use rustc::middle::dependency_format::Linkage; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel, metadata_symbol_name}; @@ -62,26 +62,26 @@ struct EncodeContext<'tcx> { #[derive(Default)] struct PerDefTables<'tcx> { - kind: PerDefTable>>, - visibility: PerDefTable>, - span: PerDefTable>, - attributes: PerDefTable>, - children: PerDefTable>, - stability: PerDefTable>, - deprecation: PerDefTable>, - - ty: PerDefTable>>, - fn_sig: PerDefTable>>, - impl_trait_ref: PerDefTable>>, - inherent_impls: PerDefTable>, - variances: PerDefTable>, - generics: PerDefTable>, - explicit_predicates: PerDefTable>>, - inferred_outlives: PerDefTable, Span)]>>, - super_predicates: PerDefTable>>, - - mir: PerDefTable>>, - promoted_mir: PerDefTable>>>, + kind: Table>>, + visibility: Table>, + span: Table>, + attributes: Table>, + children: Table>, + stability: Table>, + deprecation: Table>, + + ty: Table>>, + fn_sig: Table>>, + impl_trait_ref: Table>>, + inherent_impls: Table>, + variances: Table>, + generics: Table>, + explicit_predicates: Table>>, + inferred_outlives: Table, Span)]>>, + super_predicates: Table>>, + + mir: Table>>, + promoted_mir: Table>>>, } macro_rules! encoder_methods { @@ -138,10 +138,10 @@ impl<'tcx, T: Encodable> SpecializedEncoder> for EncodeContext<'tcx> { } } -impl<'tcx, T> SpecializedEncoder>> for EncodeContext<'tcx> +impl<'tcx, I: Idx, T> SpecializedEncoder>> for EncodeContext<'tcx> where Option: FixedSizeEncoding, { - fn specialized_encode(&mut self, lazy: &Lazy>) -> Result<(), Self::Error> { + fn specialized_encode(&mut self, lazy: &Lazy>) -> Result<(), Self::Error> { self.emit_usize(lazy.meta)?; self.emit_lazy_distance(*lazy) } @@ -307,14 +307,14 @@ impl EncodeContentsForLazy<[T]> for I } } -// Shorthand for `$self.$tables.$table.set($key, $self.lazy($value))`, which would +// Shorthand for `$self.$tables.$table.set($def_id.index, $self.lazy($value))`, which would // normally need extra variables to avoid errors about multiple mutable borrows. macro_rules! record { - ($self:ident.$tables:ident.$table:ident[$key:expr] <- $value:expr) => {{ + ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{ { let value = $value; let lazy = $self.lazy(value); - $self.$tables.$table.set($key, lazy); + $self.$tables.$table.set($def_id.index, lazy); } }} } diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 23c0204ee256b..3b82b287259e8 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -1,5 +1,5 @@ use decoder::Metadata; -use table::PerDefTable; +use table::Table; use rustc::hir; use rustc::hir::def::{self, CtorKind}; @@ -166,8 +166,7 @@ enum LazyState { // manually, instead of relying on the default, to get the correct variance. // Only needed when `T` itself contains a parameter (e.g. `'tcx`). macro_rules! Lazy { - (Table<$T:ty>) => {Lazy, usize>}; - (PerDefTable<$T:ty>) => {Lazy, usize>}; + (Table<$I:ty, $T:ty>) => {Lazy, usize>}; ([$T:ty]) => {Lazy<[$T], usize>}; ($T:ty) => {Lazy<$T, ()>}; } @@ -234,29 +233,29 @@ crate struct TraitImpls { #[derive(RustcEncodable, RustcDecodable)] crate struct LazyPerDefTables<'tcx> { - kind: Lazy!(PerDefTable)>), - visibility: Lazy!(PerDefTable>), - span: Lazy!(PerDefTable>), - attributes: Lazy!(PerDefTable>), - children: Lazy!(PerDefTable>), - stability: Lazy!(PerDefTable>), - deprecation: Lazy!(PerDefTable>), - ty: Lazy!(PerDefTable)>), - fn_sig: Lazy!(PerDefTable)>), - impl_trait_ref: Lazy!(PerDefTable)>), - inherent_impls: Lazy!(PerDefTable>), - variances: Lazy!(PerDefTable>), - generics: Lazy!(PerDefTable>), - explicit_predicates: Lazy!(PerDefTable)>), + kind: Lazy!(Table)>), + visibility: Lazy!(Table>), + span: Lazy!(Table>), + attributes: Lazy!(Table>), + children: Lazy!(Table>), + stability: Lazy!(Table>), + deprecation: Lazy!(Table>), + ty: Lazy!(Table)>), + fn_sig: Lazy!(Table)>), + impl_trait_ref: Lazy!(Table)>), + inherent_impls: Lazy!(Table>), + variances: Lazy!(Table>), + generics: Lazy!(Table>), + explicit_predicates: Lazy!(Table)>), // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate` // doesn't handle shorthands in its own (de)serialization impls, // as it's an `enum` for which we want to derive (de)serialization, // so the `ty::codec` APIs handle the whole `&'tcx [...]` at once. // Also, as an optimization, a missing entry indicates an empty `&[]`. - inferred_outlives: Lazy!(PerDefTable, Span)])>), - super_predicates: Lazy!(PerDefTable)>), - mir: Lazy!(PerDefTable)>), - promoted_mir: Lazy!(PerDefTable>)>), + inferred_outlives: Lazy!(Table, Span)])>), + super_predicates: Lazy!(Table)>), + mir: Lazy!(Table)>), + promoted_mir: Lazy!(Table>)>), } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] diff --git a/src/librustc_metadata/rmeta/table.rs b/src/librustc_metadata/rmeta/table.rs index 613d92c6d7b0b..833d84bfb5d02 100644 --- a/src/librustc_metadata/rmeta/table.rs +++ b/src/librustc_metadata/rmeta/table.rs @@ -1,6 +1,6 @@ use crate::rmeta::*; -use rustc::hir::def_id::{DefId, DefIndex}; +use rustc_index::vec::Idx; use rustc_serialize::{Encodable, opaque::Encoder}; use std::convert::TryInto; use std::marker::PhantomData; @@ -125,14 +125,16 @@ impl FixedSizeEncoding for Option> { // FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box>` would be used // when building it, and `Lazy>` or `&Table` when reading it. // (not sure if that is possible given that the `Vec` is being resized now) -pub(super) struct Table where Option: FixedSizeEncoding { - // FIXME(eddyb) store `[u8; >::BYTE_LEN]` instead of `u8` in `Vec`, - // once that starts being allowed by the compiler (i.e. lazy normalization). +pub(super) struct Table where Option: FixedSizeEncoding { + // FIXME(eddyb) use `IndexVec>::BYTE_LEN]>` instead of + // `Vec`, once that starts working (i.e. lazy normalization). + // Then again, that has the downside of not allowing `Table::encode` to + // obtain a `&[u8]` entirely in safe code, for writing the bytes out. bytes: Vec, - _marker: PhantomData, + _marker: PhantomData<(fn(&I), T)>, } -impl Default for Table where Option: FixedSizeEncoding { +impl Default for Table where Option: FixedSizeEncoding { fn default() -> Self { Table { bytes: vec![], @@ -141,13 +143,14 @@ impl Default for Table where Option: FixedSizeEncoding { } } -impl Table where Option: FixedSizeEncoding { - fn set(&mut self, i: usize, value: T) { +impl Table where Option: FixedSizeEncoding { + pub(super) fn set(&mut self, i: I, value: T) { // FIXME(eddyb) investigate more compact encodings for sparse tables. // On the PR @michaelwoerister mentioned: // > Space requirements could perhaps be optimized by using the HAMT `popcnt` // > trick (i.e. divide things into buckets of 32 or 64 items and then // > store bit-masks of which item in each bucket is actually serialized). + let i = i.index(); let needed = (i + 1) * >::BYTE_LEN; if self.bytes.len() < needed { self.bytes.resize(needed, 0); @@ -156,7 +159,7 @@ impl Table where Option: FixedSizeEncoding { Some(value).write_to_bytes_at(&mut self.bytes, i); } - fn encode(&self, buf: &mut Encoder) -> Lazy { + pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy { let pos = buf.position(); buf.emit_raw_bytes(&self.bytes); Lazy::from_position_and_meta( @@ -166,7 +169,7 @@ impl Table where Option: FixedSizeEncoding { } } -impl LazyMeta for Table where Option: FixedSizeEncoding { +impl LazyMeta for Table where Option: FixedSizeEncoding { type Meta = usize; fn min_size(len: usize) -> usize { @@ -174,65 +177,18 @@ impl LazyMeta for Table where Option: FixedSizeEncoding { } } -impl Lazy> where Option: FixedSizeEncoding { +impl Lazy> where Option: FixedSizeEncoding { /// Given the metadata, extract out the value at a particular index (if any). #[inline(never)] - fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>( + pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>( &self, metadata: M, - i: usize, + i: I, ) -> Option { debug!("Table::lookup: index={:?} len={:?}", i, self.meta); let start = self.position.get(); let bytes = &metadata.raw_bytes()[start..start + self.meta]; - >::maybe_read_from_bytes_at(bytes, i)? - } -} - -/// Like a `Table` but using `DefIndex` instead of `usize` as keys. -// FIXME(eddyb) replace by making `Table` behave like `IndexVec`, -// and by using `newtype_index!` to define `DefIndex`. -pub(super) struct PerDefTable(Table) where Option: FixedSizeEncoding; - -impl Default for PerDefTable where Option: FixedSizeEncoding { - fn default() -> Self { - PerDefTable(Table::default()) - } -} - -impl PerDefTable where Option: FixedSizeEncoding { - pub(super) fn set(&mut self, def_id: DefId, value: T) { - assert!(def_id.is_local()); - self.0.set(def_id.index.index(), value); - } - - pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy { - let lazy = self.0.encode(buf); - Lazy::from_position_and_meta(lazy.position, lazy.meta) - } -} - -impl LazyMeta for PerDefTable where Option: FixedSizeEncoding { - type Meta = as LazyMeta>::Meta; - - fn min_size(meta: Self::Meta) -> usize { - Table::::min_size(meta) - } -} - -impl Lazy> where Option: FixedSizeEncoding { - fn as_table(&self) -> Lazy> { - Lazy::from_position_and_meta(self.position, self.meta) - } - - /// Given the metadata, extract out the value at a particular DefIndex (if any). - #[inline(never)] - pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>( - &self, - metadata: M, - def_index: DefIndex, - ) -> Option { - self.as_table().get(metadata, def_index.index()) + >::maybe_read_from_bytes_at(bytes, i.index())? } } From ee42979eeb4b13bfb71116f330c735bc48fb38bc Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 14 Nov 2019 02:44:24 +0200 Subject: [PATCH 2/4] rustc_metadata: use a separate TableBuilder type to build a Table. --- src/librustc_metadata/rmeta/encoder.rs | 46 +++++++++++++------------- src/librustc_metadata/rmeta/table.rs | 26 +++++++++------ 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 5feb54bb8fa2d..e47047ae83dd9 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1,5 +1,5 @@ use crate::rmeta::*; -use crate::rmeta::table::{FixedSizeEncoding, Table}; +use crate::rmeta::table::{FixedSizeEncoding, TableBuilder}; use rustc::middle::cstore::{LinkagePreference, NativeLibrary, EncodedMetadata, ForeignModule}; @@ -47,7 +47,7 @@ struct EncodeContext<'tcx> { opaque: opaque::Encoder, tcx: TyCtxt<'tcx>, - per_def: PerDefTables<'tcx>, + per_def: PerDefTableBuilders<'tcx>, lazy_state: LazyState, type_shorthands: FxHashMap, usize>, @@ -61,27 +61,27 @@ struct EncodeContext<'tcx> { } #[derive(Default)] -struct PerDefTables<'tcx> { - kind: Table>>, - visibility: Table>, - span: Table>, - attributes: Table>, - children: Table>, - stability: Table>, - deprecation: Table>, - - ty: Table>>, - fn_sig: Table>>, - impl_trait_ref: Table>>, - inherent_impls: Table>, - variances: Table>, - generics: Table>, - explicit_predicates: Table>>, - inferred_outlives: Table, Span)]>>, - super_predicates: Table>>, - - mir: Table>>, - promoted_mir: Table>>>, +struct PerDefTableBuilders<'tcx> { + kind: TableBuilder>>, + visibility: TableBuilder>, + span: TableBuilder>, + attributes: TableBuilder>, + children: TableBuilder>, + stability: TableBuilder>, + deprecation: TableBuilder>, + + ty: TableBuilder>>, + fn_sig: TableBuilder>>, + impl_trait_ref: TableBuilder>>, + inherent_impls: TableBuilder>, + variances: TableBuilder>, + generics: TableBuilder>, + explicit_predicates: TableBuilder>>, + inferred_outlives: TableBuilder, Span)]>>, + super_predicates: TableBuilder>>, + + mir: TableBuilder>>, + promoted_mir: TableBuilder>>>, } macro_rules! encoder_methods { diff --git a/src/librustc_metadata/rmeta/table.rs b/src/librustc_metadata/rmeta/table.rs index 833d84bfb5d02..10122fbba1fd4 100644 --- a/src/librustc_metadata/rmeta/table.rs +++ b/src/librustc_metadata/rmeta/table.rs @@ -117,33 +117,39 @@ impl FixedSizeEncoding for Option> { } } -/// Random-access table (i.e. offeringconstant-time `get`/`set`), similar to +/// Random-access table (i.e. offering constant-time `get`/`set`), similar to /// `Vec>`, but without requiring encoding or decoding all the values /// eagerly and in-order. /// A total of `(max_idx + 1) * as FixedSizeEncoding>::BYTE_LEN` bytes -/// are used for a table, where `max_idx` is the largest index passed to `set`. -// FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box>` would be used -// when building it, and `Lazy>` or `&Table` when reading it. -// (not sure if that is possible given that the `Vec` is being resized now) +/// are used for a table, where `max_idx` is the largest index passed to +/// `TableBuilder::set`. pub(super) struct Table where Option: FixedSizeEncoding { + _marker: PhantomData<(fn(&I), T)>, + // NOTE(eddyb) this makes `Table` not implement `Sized`, but no + // value of `Table` is ever created (it's always behind `Lazy`). + _bytes: [u8], +} + +/// Helper for constructing a table's serialization (also see `Table`). +pub(super) struct TableBuilder where Option: FixedSizeEncoding { // FIXME(eddyb) use `IndexVec>::BYTE_LEN]>` instead of // `Vec`, once that starts working (i.e. lazy normalization). - // Then again, that has the downside of not allowing `Table::encode` to + // Then again, that has the downside of not allowing `TableBuilder::encode` to // obtain a `&[u8]` entirely in safe code, for writing the bytes out. bytes: Vec, _marker: PhantomData<(fn(&I), T)>, } -impl Default for Table where Option: FixedSizeEncoding { +impl Default for TableBuilder where Option: FixedSizeEncoding { fn default() -> Self { - Table { + TableBuilder { bytes: vec![], _marker: PhantomData, } } } -impl Table where Option: FixedSizeEncoding { +impl TableBuilder where Option: FixedSizeEncoding { pub(super) fn set(&mut self, i: I, value: T) { // FIXME(eddyb) investigate more compact encodings for sparse tables. // On the PR @michaelwoerister mentioned: @@ -159,7 +165,7 @@ impl Table where Option: FixedSizeEncoding { Some(value).write_to_bytes_at(&mut self.bytes, i); } - pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy { + pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy> { let pos = buf.position(); buf.emit_raw_bytes(&self.bytes); Lazy::from_position_and_meta( From d7444c122e8833e1791a4fa9e39b8853b803abc0 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 14 Nov 2019 02:52:59 +0200 Subject: [PATCH 3/4] rustc_metadata: remove Encodable requirements from LazyMeta impls. --- src/librustc_metadata/rmeta/decoder.rs | 10 +++++----- src/librustc_metadata/rmeta/encoder.rs | 4 ++-- src/librustc_metadata/rmeta/mod.rs | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 47a48c1778666..e6ccbf5c38bf3 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -32,7 +32,7 @@ use std::mem; use std::num::NonZeroUsize; use std::u32; -use rustc_serialize::{Decodable, Decoder, Encodable, SpecializedDecoder, opaque}; +use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; use syntax::attr; use syntax::ast::{self, Ident}; use syntax::source_map::{self, respan, Spanned}; @@ -217,7 +217,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) { } } -impl<'a, 'tcx, T: Encodable + Decodable> Lazy { +impl<'a, 'tcx, T: Decodable> Lazy { fn decode>(self, metadata: M) -> T { let mut dcx = metadata.decoder(self.position.get()); dcx.lazy_state = LazyState::NodeStart(self.position); @@ -225,7 +225,7 @@ impl<'a, 'tcx, T: Encodable + Decodable> Lazy { } } -impl<'a: 'x, 'tcx: 'x, 'x, T: Encodable + Decodable> Lazy<[T]> { +impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> { fn decode>( self, metadata: M, @@ -324,13 +324,13 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { } } -impl<'a, 'tcx, T: Encodable> SpecializedDecoder> for DecodeContext<'a, 'tcx> { +impl<'a, 'tcx, T> SpecializedDecoder> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result, Self::Error> { self.read_lazy_with_meta(()) } } -impl<'a, 'tcx, T: Encodable> SpecializedDecoder> for DecodeContext<'a, 'tcx> { +impl<'a, 'tcx, T> SpecializedDecoder> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result, Self::Error> { let len = self.read_usize()?; if len == 0 { diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index e47047ae83dd9..9410b19064683 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -122,13 +122,13 @@ impl<'tcx> Encoder for EncodeContext<'tcx> { } } -impl<'tcx, T: Encodable> SpecializedEncoder> for EncodeContext<'tcx> { +impl<'tcx, T> SpecializedEncoder> for EncodeContext<'tcx> { fn specialized_encode(&mut self, lazy: &Lazy) -> Result<(), Self::Error> { self.emit_lazy_distance(*lazy) } } -impl<'tcx, T: Encodable> SpecializedEncoder> for EncodeContext<'tcx> { +impl<'tcx, T> SpecializedEncoder> for EncodeContext<'tcx> { fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> { self.emit_usize(lazy.meta)?; if lazy.meta == 0 { diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 3b82b287259e8..a17809b24c0ff 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -15,7 +15,6 @@ use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_index::vec::IndexVec; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; -use rustc_serialize::Encodable; use syntax::{ast, attr}; use syntax::edition::Edition; use syntax::symbol::Symbol; @@ -59,7 +58,7 @@ trait LazyMeta { fn min_size(meta: Self::Meta) -> usize; } -impl LazyMeta for T { +impl LazyMeta for T { type Meta = (); fn min_size(_: ()) -> usize { @@ -68,7 +67,7 @@ impl LazyMeta for T { } } -impl LazyMeta for [T] { +impl LazyMeta for [T] { type Meta = usize; fn min_size(len: usize) -> usize { @@ -124,13 +123,13 @@ impl Lazy { } } -impl Lazy { +impl Lazy { fn from_position(position: NonZeroUsize) -> Lazy { Lazy::from_position_and_meta(position, ()) } } -impl Lazy<[T]> { +impl Lazy<[T]> { fn empty() -> Lazy<[T]> { Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0) } From a0556b3b79328c598a4f1539bbe81ceebc4a5b59 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 14 Nov 2019 04:42:21 +0200 Subject: [PATCH 4/4] rustc_metadata: use a macro to deduplicate LazyPerDefTables and PerDefTableBuilders. --- src/librustc_metadata/rmeta/encoder.rs | 51 ++------------------ src/librustc_metadata/rmeta/mod.rs | 65 +++++++++++++++++--------- 2 files changed, 47 insertions(+), 69 deletions(-) diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 9410b19064683..8074bde61237d 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1,5 +1,5 @@ use crate::rmeta::*; -use crate::rmeta::table::{FixedSizeEncoding, TableBuilder}; +use crate::rmeta::table::FixedSizeEncoding; use rustc::middle::cstore::{LinkagePreference, NativeLibrary, EncodedMetadata, ForeignModule}; @@ -8,7 +8,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, use rustc::hir::{GenericParamKind, AnonConst}; use rustc::hir::map::definitions::DefPathTable; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::Idx; use rustc::middle::dependency_format::Linkage; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel, metadata_symbol_name}; @@ -60,30 +60,6 @@ struct EncodeContext<'tcx> { source_file_cache: Lrc, } -#[derive(Default)] -struct PerDefTableBuilders<'tcx> { - kind: TableBuilder>>, - visibility: TableBuilder>, - span: TableBuilder>, - attributes: TableBuilder>, - children: TableBuilder>, - stability: TableBuilder>, - deprecation: TableBuilder>, - - ty: TableBuilder>>, - fn_sig: TableBuilder>>, - impl_trait_ref: TableBuilder>>, - inherent_impls: TableBuilder>, - variances: TableBuilder>, - generics: TableBuilder>, - explicit_predicates: TableBuilder>>, - inferred_outlives: TableBuilder, Span)]>>, - super_predicates: TableBuilder>>, - - mir: TableBuilder>>, - promoted_mir: TableBuilder>>>, -} - macro_rules! encoder_methods { ($($name:ident($ty:ty);)*) => { $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> { @@ -509,28 +485,7 @@ impl<'tcx> EncodeContext<'tcx> { i = self.position(); - let per_def = LazyPerDefTables { - kind: self.per_def.kind.encode(&mut self.opaque), - visibility: self.per_def.visibility.encode(&mut self.opaque), - span: self.per_def.span.encode(&mut self.opaque), - attributes: self.per_def.attributes.encode(&mut self.opaque), - children: self.per_def.children.encode(&mut self.opaque), - stability: self.per_def.stability.encode(&mut self.opaque), - deprecation: self.per_def.deprecation.encode(&mut self.opaque), - - ty: self.per_def.ty.encode(&mut self.opaque), - fn_sig: self.per_def.fn_sig.encode(&mut self.opaque), - impl_trait_ref: self.per_def.impl_trait_ref.encode(&mut self.opaque), - inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque), - variances: self.per_def.variances.encode(&mut self.opaque), - generics: self.per_def.generics.encode(&mut self.opaque), - explicit_predicates: self.per_def.explicit_predicates.encode(&mut self.opaque), - inferred_outlives: self.per_def.inferred_outlives.encode(&mut self.opaque), - super_predicates: self.per_def.super_predicates.encode(&mut self.opaque), - - mir: self.per_def.mir.encode(&mut self.opaque), - promoted_mir: self.per_def.promoted_mir.encode(&mut self.opaque), - }; + let per_def = self.per_def.encode(&mut self.opaque); let per_def_bytes = self.position() - i; // Encode the proc macro data diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index a17809b24c0ff..1bca2836a3a07 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -1,5 +1,5 @@ use decoder::Metadata; -use table::Table; +use table::{Table, TableBuilder}; use rustc::hir; use rustc::hir::def::{self, CtorKind}; @@ -15,6 +15,7 @@ use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc_index::vec::IndexVec; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; +use rustc_serialize::opaque::Encoder; use syntax::{ast, attr}; use syntax::edition::Edition; use syntax::symbol::Symbol; @@ -230,31 +231,53 @@ crate struct TraitImpls { impls: Lazy<[DefIndex]>, } -#[derive(RustcEncodable, RustcDecodable)] -crate struct LazyPerDefTables<'tcx> { - kind: Lazy!(Table)>), - visibility: Lazy!(Table>), - span: Lazy!(Table>), - attributes: Lazy!(Table>), - children: Lazy!(Table>), - stability: Lazy!(Table>), - deprecation: Lazy!(Table>), - ty: Lazy!(Table)>), - fn_sig: Lazy!(Table)>), - impl_trait_ref: Lazy!(Table)>), - inherent_impls: Lazy!(Table>), - variances: Lazy!(Table>), - generics: Lazy!(Table>), - explicit_predicates: Lazy!(Table)>), +/// Define `LazyPerDefTables` and `PerDefTableBuilders` at the same time. +macro_rules! define_per_def_tables { + ($($name:ident: Table),+ $(,)?) => { + #[derive(RustcEncodable, RustcDecodable)] + crate struct LazyPerDefTables<'tcx> { + $($name: Lazy!(Table)),+ + } + + #[derive(Default)] + struct PerDefTableBuilders<'tcx> { + $($name: TableBuilder),+ + } + + impl PerDefTableBuilders<'tcx> { + fn encode(&self, buf: &mut Encoder) -> LazyPerDefTables<'tcx> { + LazyPerDefTables { + $($name: self.$name.encode(buf)),+ + } + } + } + } +} + +define_per_def_tables! { + kind: Table)>, + visibility: Table>, + span: Table>, + attributes: Table>, + children: Table>, + stability: Table>, + deprecation: Table>, + ty: Table)>, + fn_sig: Table)>, + impl_trait_ref: Table)>, + inherent_impls: Table>, + variances: Table>, + generics: Table>, + explicit_predicates: Table)>, // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate` // doesn't handle shorthands in its own (de)serialization impls, // as it's an `enum` for which we want to derive (de)serialization, // so the `ty::codec` APIs handle the whole `&'tcx [...]` at once. // Also, as an optimization, a missing entry indicates an empty `&[]`. - inferred_outlives: Lazy!(Table, Span)])>), - super_predicates: Lazy!(Table)>), - mir: Lazy!(Table)>), - promoted_mir: Lazy!(Table>)>), + inferred_outlives: Table, Span)])>, + super_predicates: Table)>, + mir: Table)>, + promoted_mir: Table>)>, } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]