about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2019-11-27 15:28:34 -0600
committerGitHub <noreply@github.com>2019-11-27 15:28:34 -0600
commit5139b538367eb094d48fd150cd2d719a2885b56c (patch)
tree7a39b0d42046e8c531b96eb96d4cf1d7084e133b
parent2f1a4b3748d4632b0519097ee993136c3d5dc6ed (diff)
parenta0556b3b79328c598a4f1539bbe81ceebc4a5b59 (diff)
downloadrust-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.rs18
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs67
-rw-r--r--src/librustc_metadata/rmeta/mod.rs77
-rw-r--r--src/librustc_metadata/rmeta/table.rs96
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())?
     }
 }