diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2019-11-27 15:28:34 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-27 15:28:34 -0600 |
| commit | 5139b538367eb094d48fd150cd2d719a2885b56c (patch) | |
| tree | 7a39b0d42046e8c531b96eb96d4cf1d7084e133b | |
| parent | 2f1a4b3748d4632b0519097ee993136c3d5dc6ed (diff) | |
| parent | a0556b3b79328c598a4f1539bbe81ceebc4a5b59 (diff) | |
| download | rust-5139b538367eb094d48fd150cd2d719a2885b56c.tar.gz rust-5139b538367eb094d48fd150cd2d719a2885b56c.zip | |
Rollup merge of #66399 - eddyb:rmeta-table-cleanup, r=Mark-Simulacrum
rustc_metadata: simplify the interactions between Lazy and Table. These are small post-#59953 cleanups (including undoing some contrivances from that PR). r? @michaelwoerister
| -rw-r--r-- | src/librustc_metadata/rmeta/decoder.rs | 18 | ||||
| -rw-r--r-- | src/librustc_metadata/rmeta/encoder.rs | 67 | ||||
| -rw-r--r-- | src/librustc_metadata/rmeta/mod.rs | 77 | ||||
| -rw-r--r-- | src/librustc_metadata/rmeta/table.rs | 96 |
4 files changed, 98 insertions, 160 deletions
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 7b0cf451ff9..e6ccbf5c38b 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; @@ -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<T> { +impl<'a, 'tcx, T: Decodable> Lazy<T> { fn decode<M: Metadata<'a, 'tcx>>(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<T> { } } -impl<'a: 'x, 'tcx: 'x, 'x, T: Encodable + Decodable> Lazy<[T]> { +impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> { fn decode<M: Metadata<'a, 'tcx>>( self, metadata: M, @@ -324,13 +324,13 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { } } -impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> { +impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> { self.read_lazy_with_meta(()) } } -impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> { +impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> { let len = self.read_usize()?; if len == 0 { @@ -341,10 +341,10 @@ impl<'a, 'tcx, T: Encodable> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, } } -impl<'a, 'tcx, T> SpecializedDecoder<Lazy<PerDefTable<T>>> for DecodeContext<'a, 'tcx> +impl<'a, 'tcx, I: Idx, T> SpecializedDecoder<Lazy<Table<I, T>>> for DecodeContext<'a, 'tcx> where Option<T>: FixedSizeEncoding, { - fn specialized_decode(&mut self) -> Result<Lazy<PerDefTable<T>>, Self::Error> { + fn specialized_decode(&mut self) -> Result<Lazy<Table<I, T>>, 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 483915f654d..8074bde6123 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; 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; use rustc::middle::dependency_format::Linkage; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel, metadata_symbol_name}; @@ -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<Ty<'tcx>, usize>, @@ -60,30 +60,6 @@ struct EncodeContext<'tcx> { source_file_cache: Lrc<SourceFile>, } -#[derive(Default)] -struct PerDefTables<'tcx> { - kind: PerDefTable<Lazy<EntryKind<'tcx>>>, - visibility: PerDefTable<Lazy<ty::Visibility>>, - span: PerDefTable<Lazy<Span>>, - attributes: PerDefTable<Lazy<[ast::Attribute]>>, - children: PerDefTable<Lazy<[DefIndex]>>, - stability: PerDefTable<Lazy<attr::Stability>>, - deprecation: PerDefTable<Lazy<attr::Deprecation>>, - - ty: PerDefTable<Lazy<Ty<'tcx>>>, - fn_sig: PerDefTable<Lazy<ty::PolyFnSig<'tcx>>>, - impl_trait_ref: PerDefTable<Lazy<ty::TraitRef<'tcx>>>, - inherent_impls: PerDefTable<Lazy<[DefIndex]>>, - variances: PerDefTable<Lazy<[ty::Variance]>>, - generics: PerDefTable<Lazy<ty::Generics>>, - explicit_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>, - inferred_outlives: PerDefTable<Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>, - super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>, - - mir: PerDefTable<Lazy<mir::Body<'tcx>>>, - promoted_mir: PerDefTable<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>, -} - macro_rules! encoder_methods { ($($name:ident($ty:ty);)*) => { $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> { @@ -122,13 +98,13 @@ impl<'tcx> Encoder for EncodeContext<'tcx> { } } -impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> { +impl<'tcx, T> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> { fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> { self.emit_lazy_distance(*lazy) } } -impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> { +impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> { fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> { self.emit_usize(lazy.meta)?; if lazy.meta == 0 { @@ -138,10 +114,10 @@ impl<'tcx, T: Encodable> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> { } } -impl<'tcx, T> SpecializedEncoder<Lazy<PerDefTable<T>>> for EncodeContext<'tcx> +impl<'tcx, I: Idx, T> SpecializedEncoder<Lazy<Table<I, T>>> for EncodeContext<'tcx> where Option<T>: FixedSizeEncoding, { - fn specialized_encode(&mut self, lazy: &Lazy<PerDefTable<T>>) -> Result<(), Self::Error> { + fn specialized_encode(&mut self, lazy: &Lazy<Table<I, T>>) -> Result<(), Self::Error> { self.emit_usize(lazy.meta)?; self.emit_lazy_distance(*lazy) } @@ -307,14 +283,14 @@ impl<I, T: Encodable> 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); } }} } @@ -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 23c0204ee25..1bca2836a3a 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, TableBuilder}; use rustc::hir; use rustc::hir::def::{self, CtorKind}; @@ -15,7 +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::Encodable; +use rustc_serialize::opaque::Encoder; use syntax::{ast, attr}; use syntax::edition::Edition; use syntax::symbol::Symbol; @@ -59,7 +59,7 @@ trait LazyMeta { fn min_size(meta: Self::Meta) -> usize; } -impl<T: Encodable> LazyMeta for T { +impl<T> LazyMeta for T { type Meta = (); fn min_size(_: ()) -> usize { @@ -68,7 +68,7 @@ impl<T: Encodable> LazyMeta for T { } } -impl<T: Encodable> LazyMeta for [T] { +impl<T> LazyMeta for [T] { type Meta = usize; fn min_size(len: usize) -> usize { @@ -124,13 +124,13 @@ impl<T: ?Sized + LazyMeta> Lazy<T> { } } -impl<T: Encodable> Lazy<T> { +impl<T> Lazy<T> { fn from_position(position: NonZeroUsize) -> Lazy<T> { Lazy::from_position_and_meta(position, ()) } } -impl<T: Encodable> Lazy<[T]> { +impl<T> Lazy<[T]> { fn empty() -> Lazy<[T]> { Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0) } @@ -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<Table<$T>, usize>}; - (PerDefTable<$T:ty>) => {Lazy<PerDefTable<$T>, usize>}; + (Table<$I:ty, $T:ty>) => {Lazy<Table<$I, $T>, usize>}; ([$T:ty]) => {Lazy<[$T], usize>}; ($T:ty) => {Lazy<$T, ()>}; } @@ -232,31 +231,53 @@ crate struct TraitImpls { impls: Lazy<[DefIndex]>, } -#[derive(RustcEncodable, RustcDecodable)] -crate struct LazyPerDefTables<'tcx> { - kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>), - visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>), - span: Lazy!(PerDefTable<Lazy<Span>>), - attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>), - children: Lazy!(PerDefTable<Lazy<[DefIndex]>>), - stability: Lazy!(PerDefTable<Lazy<attr::Stability>>), - deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>), - ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>), - fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>), - impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>), - inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>), - variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>), - generics: Lazy!(PerDefTable<Lazy<ty::Generics>>), - explicit_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>), +/// Define `LazyPerDefTables` and `PerDefTableBuilders` at the same time. +macro_rules! define_per_def_tables { + ($($name:ident: Table<DefIndex, $T:ty>),+ $(,)?) => { + #[derive(RustcEncodable, RustcDecodable)] + crate struct LazyPerDefTables<'tcx> { + $($name: Lazy!(Table<DefIndex, $T>)),+ + } + + #[derive(Default)] + struct PerDefTableBuilders<'tcx> { + $($name: TableBuilder<DefIndex, $T>),+ + } + + impl PerDefTableBuilders<'tcx> { + fn encode(&self, buf: &mut Encoder) -> LazyPerDefTables<'tcx> { + LazyPerDefTables { + $($name: self.$name.encode(buf)),+ + } + } + } + } +} + +define_per_def_tables! { + kind: Table<DefIndex, Lazy!(EntryKind<'tcx>)>, + visibility: Table<DefIndex, Lazy<ty::Visibility>>, + span: Table<DefIndex, Lazy<Span>>, + attributes: Table<DefIndex, Lazy<[ast::Attribute]>>, + children: Table<DefIndex, Lazy<[DefIndex]>>, + stability: Table<DefIndex, Lazy<attr::Stability>>, + deprecation: Table<DefIndex, Lazy<attr::Deprecation>>, + ty: Table<DefIndex, Lazy!(Ty<'tcx>)>, + fn_sig: Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>, + impl_trait_ref: Table<DefIndex, Lazy!(ty::TraitRef<'tcx>)>, + inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>, + variances: Table<DefIndex, Lazy<[ty::Variance]>>, + generics: Table<DefIndex, Lazy<ty::Generics>>, + explicit_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>, // 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<Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>), - super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>), - mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>), - promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>), + inferred_outlives: Table<DefIndex, Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>, + super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>, + mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>, + promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>, } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] diff --git a/src/librustc_metadata/rmeta/table.rs b/src/librustc_metadata/rmeta/table.rs index 613d92c6d7b..10122fbba1f 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; @@ -117,37 +117,46 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> { } } -/// Random-access table (i.e. offeringconstant-time `get`/`set`), similar to +/// Random-access table (i.e. offering constant-time `get`/`set`), similar to /// `Vec<Option<T>>`, but without requiring encoding or decoding all the values /// eagerly and in-order. /// A total of `(max_idx + 1) * <Option<T> 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<Table<T>>` would be used -// when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it. -// (not sure if that is possible given that the `Vec` is being resized now) -pub(super) struct Table<T> where Option<T>: FixedSizeEncoding { - // FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`, - // once that starts being allowed by the compiler (i.e. lazy normalization). +/// are used for a table, where `max_idx` is the largest index passed to +/// `TableBuilder::set`. +pub(super) struct Table<I: Idx, T> where Option<T>: 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<I: Idx, T> where Option<T>: FixedSizeEncoding { + // FIXME(eddyb) use `IndexVec<I, [u8; <Option<T>>::BYTE_LEN]>` instead of + // `Vec<u8>`, once that starts working (i.e. lazy normalization). + // 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<u8>, - _marker: PhantomData<T>, + _marker: PhantomData<(fn(&I), T)>, } -impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding { +impl<I: Idx, T> Default for TableBuilder<I, T> where Option<T>: FixedSizeEncoding { fn default() -> Self { - Table { + TableBuilder { bytes: vec![], _marker: PhantomData, } } } -impl<T> Table<T> where Option<T>: FixedSizeEncoding { - fn set(&mut self, i: usize, value: T) { +impl<I: Idx, T> TableBuilder<I, T> where Option<T>: 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) * <Option<T>>::BYTE_LEN; if self.bytes.len() < needed { self.bytes.resize(needed, 0); @@ -156,7 +165,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding { Some(value).write_to_bytes_at(&mut self.bytes, i); } - fn encode(&self, buf: &mut Encoder) -> Lazy<Self> { + pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Table<I, T>> { let pos = buf.position(); buf.emit_raw_bytes(&self.bytes); Lazy::from_position_and_meta( @@ -166,7 +175,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding { } } -impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding { +impl<I: Idx, T> LazyMeta for Table<I, T> where Option<T>: FixedSizeEncoding { type Meta = usize; fn min_size(len: usize) -> usize { @@ -174,65 +183,18 @@ impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding { } } -impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding { +impl<I: Idx, T> Lazy<Table<I, T>> where Option<T>: 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<T> { debug!("Table::lookup: index={:?} len={:?}", i, self.meta); let start = self.position.get(); let bytes = &metadata.raw_bytes()[start..start + self.meta]; - <Option<T>>::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<T>(Table<T>) where Option<T>: FixedSizeEncoding; - -impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding { - fn default() -> Self { - PerDefTable(Table::default()) - } -} - -impl<T> PerDefTable<T> where Option<T>: 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<Self> { - let lazy = self.0.encode(buf); - Lazy::from_position_and_meta(lazy.position, lazy.meta) - } -} - -impl<T> LazyMeta for PerDefTable<T> where Option<T>: FixedSizeEncoding { - type Meta = <Table<T> as LazyMeta>::Meta; - - fn min_size(meta: Self::Meta) -> usize { - Table::<T>::min_size(meta) - } -} - -impl<T> Lazy<PerDefTable<T>> where Option<T>: FixedSizeEncoding { - fn as_table(&self) -> Lazy<Table<T>> { - 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<T> { - self.as_table().get(metadata, def_index.index()) + <Option<T>>::maybe_read_from_bytes_at(bytes, i.index())? } } |
