Skip to main content

rustc_metadata/rmeta/
def_path_hash_map.rs

1use rustc_data_structures::owned_slice::OwnedSlice;
2use rustc_data_structures::sorted_map::SortedMap;
3use rustc_hashes::Hash64;
4use rustc_hir::def_path_hash_map::Config as HashMapConfig;
5use rustc_hir::definitions::DefPathToIndexMap;
6use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
7use rustc_span::def_id::{DefIndex, DefPathHash};
8
9use crate::rmeta::EncodeContext;
10use crate::rmeta::decoder::BlobDecodeContext;
11
12pub(crate) enum DefPathHashMapRef<'tcx> {
13    OwnedFromMetadata(odht::HashTable<HashMapConfig, OwnedSlice>, SortedMap<Hash64, DefIndex>),
14    BorrowedFromTcx(&'tcx DefPathToIndexMap),
15}
16
17impl DefPathHashMapRef<'_> {
18    #[inline]
19    pub(crate) fn def_path_hash_to_def_index(
20        &self,
21        def_path_hash: &DefPathHash,
22    ) -> Option<DefIndex> {
23        match self {
24            DefPathHashMapRef::OwnedFromMetadata(det_map, non_det_map) => {
25                let hash = &def_path_hash.local_hash();
26                det_map.get(hash).or_else(|| non_det_map.get(hash).copied())
27            }
28            DefPathHashMapRef::BorrowedFromTcx(_) => {
29                {
    ::core::panicking::panic_fmt(format_args!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization"));
}panic!("DefPathHashMap::BorrowedFromTcx variant only exists for serialization")
30            }
31        }
32    }
33}
34
35impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefPathHashMapRef<'tcx> {
36    fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) {
37        match *self {
38            DefPathHashMapRef::BorrowedFromTcx(map) => {
39                let bytes = map.before_parallel_alloc.raw_bytes();
40                e.emit_usize(bytes.len());
41                e.emit_raw_bytes(bytes);
42
43                map.after_parallel_alloc
44                    .as_ref()
45                    .expect("must be set before metadata encoding")
46                    .range(..)
47                    .encode(e);
48            }
49            DefPathHashMapRef::OwnedFromMetadata(..) => {
50                {
    ::core::panicking::panic_fmt(format_args!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization"));
}panic!("DefPathHashMap::OwnedFromMetadata variant only exists for deserialization")
51            }
52        }
53    }
54}
55
56impl<'a> Decodable<BlobDecodeContext<'a>> for DefPathHashMapRef<'static> {
57    fn decode(d: &mut BlobDecodeContext<'a>) -> DefPathHashMapRef<'static> {
58        let len = d.read_usize();
59        let pos = d.position();
60        let o = d.blob().bytes().clone().slice(|blob| &blob[pos..pos + len]);
61
62        // Although we already have the data we need via the `OwnedSlice`, we still need
63        // to advance the `DecodeContext`'s position so it's in a valid state after
64        // the method. We use `read_raw_bytes()` for that.
65        let _ = d.read_raw_bytes(len);
66
67        let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| {
68            { ::core::panicking::panic_fmt(format_args!("decode error: {0}", e)); };panic!("decode error: {e}");
69        });
70
71        let elements = Vec::<(Hash64, DefIndex)>::decode(d);
72        let non_det_map = SortedMap::from_presorted_elements(elements);
73
74        DefPathHashMapRef::OwnedFromMetadata(inner, non_det_map)
75    }
76}