about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs22
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs7
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs30
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs28
4 files changed, 77 insertions, 10 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 7b500f1565d..3933a0d19a4 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -388,6 +388,17 @@ impl<'a, 'tcx> LazyQueryDecodable<'a, 'tcx, Option<DeprecationEntry>>
     }
 }
 
+impl<'a, 'tcx> LazyQueryDecodable<'a, 'tcx, Option<DefId>> for Option<RawDefId> {
+    fn decode_query(
+        self,
+        cdata: CrateMetadataRef<'a>,
+        _: TyCtxt<'tcx>,
+        _: impl FnOnce() -> !,
+    ) -> Option<DefId> {
+        self.map(|raw_def_id| raw_def_id.decode(cdata))
+    }
+}
+
 impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
     #[inline]
     fn tcx(&self) -> TyCtxt<'tcx> {
@@ -406,8 +417,9 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
         self.cdata.unwrap()
     }
 
+    #[inline]
     fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
-        if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] }
+        self.cdata().map_encoded_cnum_to_current(cnum)
     }
 
     fn read_lazy_with_meta<T: ?Sized + LazyMeta>(&mut self, meta: T::Meta) -> Lazy<T> {
@@ -718,8 +730,7 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a
     }
 }
 
-impl<'a, 'tcx, I: Idx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
-    for Lazy<Table<I, T>>
+impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for Lazy<Table<I, T>>
 where
     Option<T>: FixedSizeEncoding,
 {
@@ -856,6 +867,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
     }
 
+    #[inline]
+    pub(super) fn map_encoded_cnum_to_current(self, cnum: CrateNum) -> CrateNum {
+        if cnum == LOCAL_CRATE { self.cnum } else { self.cnum_map[cnum] }
+    }
+
     fn kind(self, item_id: DefIndex) -> EntryKind {
         self.maybe_kind(item_id).unwrap_or_else(|| {
             bug!(
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index be10ad490e1..e967750aebb 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -147,8 +147,7 @@ impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a
     }
 }
 
-impl<'a, 'tcx, I: Idx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
-    for Lazy<Table<I, T>>
+impl<'a, 'tcx, I: Idx, T> Encodable<EncodeContext<'a, 'tcx>> for Lazy<Table<I, T>>
 where
     Option<T>: FixedSizeEncoding,
 {
@@ -1285,7 +1284,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.encode_ident_span(def_id, impl_item.ident(self.tcx));
         self.encode_item_type(def_id);
         if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
-            record!(self.tables.trait_item_def_id[def_id] <- trait_item_def_id);
+            self.tables.trait_item_def_id.set(def_id.index, trait_item_def_id.into());
         }
         if impl_item.kind == ty::AssocKind::Fn {
             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
@@ -1457,7 +1456,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     let trait_def = self.tcx.trait_def(trait_ref.def_id);
                     if let Some(mut an) = trait_def.ancestors(self.tcx, def_id).ok() {
                         if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) {
-                            record!(self.tables.impl_parent[def_id] <- parent);
+                            self.tables.impl_parent.set(def_id.index, parent.into());
                         }
                     }
 
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 37340ee3268..43ccfc64e05 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -1,3 +1,4 @@
+use crate::creader::CrateMetadataRef;
 use decoder::Metadata;
 use def_path_hash_map::DefPathHashMapRef;
 use table::{Table, TableBuilder};
@@ -8,7 +9,7 @@ use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::MetadataRef;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
-use rustc_hir::def_id::{DefId, DefIndex, DefPathHash, StableCrateId};
+use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
 use rustc_hir::definitions::DefKey;
 use rustc_hir::lang_items;
 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
@@ -237,6 +238,29 @@ crate struct CrateRoot<'tcx> {
     symbol_mangling_version: SymbolManglingVersion,
 }
 
+/// On-disk representation of `DefId`.
+/// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk
+/// representation and the compilation session.
+#[derive(Copy, Clone)]
+crate struct RawDefId {
+    krate: u32,
+    index: u32,
+}
+
+impl Into<RawDefId> for DefId {
+    fn into(self) -> RawDefId {
+        RawDefId { krate: self.krate.as_u32(), index: self.index.as_u32() }
+    }
+}
+
+impl RawDefId {
+    fn decode(self, cdata: CrateMetadataRef<'_>) -> DefId {
+        let krate = CrateNum::from_u32(self.krate);
+        let krate = cdata.map_encoded_cnum_to_current(krate);
+        DefId { krate, index: DefIndex::from_u32(self.index) }
+    }
+}
+
 #[derive(Encodable, Decodable)]
 crate struct CrateDep {
     pub name: Symbol,
@@ -309,7 +333,7 @@ define_tables! {
     mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
     promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
     thir_abstract_const: Table<DefIndex, Lazy!(&'tcx [thir::abstract_const::Node<'tcx>])>,
-    impl_parent: Table<DefIndex, Lazy!(DefId)>,
+    impl_parent: Table<DefIndex, RawDefId>,
     impl_polarity: Table<DefIndex, ty::ImplPolarity>,
     impl_constness: Table<DefIndex, hir::Constness>,
     impl_defaultness: Table<DefIndex, hir::Defaultness>,
@@ -322,7 +346,7 @@ define_tables! {
     generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>,
     trait_def: Table<DefIndex, Lazy!(ty::TraitDef)>,
 
-    trait_item_def_id: Table<DefIndex, Lazy<DefId>>,
+    trait_item_def_id: Table<DefIndex, RawDefId>,
     inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
     expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
     unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 3e0aa0728df..b336649d366 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -200,6 +200,34 @@ impl FixedSizeEncoding for Option<DefPathHash> {
     }
 }
 
+// We directly encode RawDefId because using a `Lazy` would incur a 50% overhead in the worst case.
+impl FixedSizeEncoding for Option<RawDefId> {
+    fixed_size_encoding_byte_len_and_defaults!(2 * u32::BYTE_LEN);
+
+    #[inline]
+    fn from_bytes(b: &[u8]) -> Self {
+        let krate = u32::from_bytes(&b[0..4]);
+        let index = u32::from_bytes(&b[4..8]);
+        if krate == 0 {
+            return None;
+        }
+        Some(RawDefId { krate: krate - 1, index })
+    }
+
+    #[inline]
+    fn write_to_bytes(self, b: &mut [u8]) {
+        match self {
+            None => 0u32.write_to_bytes(b),
+            Some(RawDefId { krate, index }) => {
+                // CrateNum is less than `CrateNum::MAX_AS_U32`.
+                debug_assert!(krate < u32::MAX);
+                (1 + krate).write_to_bytes(&mut b[0..4]);
+                index.write_to_bytes(&mut b[4..8]);
+            }
+        }
+    }
+}
+
 // NOTE(eddyb) there could be an impl for `usize`, which would enable a more
 // generic `Lazy<T>` impl, but in the general case we might not need / want to
 // fit every `usize` in `u32`.