Skip to main content

rustc_middle/dep_graph/
dep_node_key.rs

1use rustc_data_structures::fingerprint::Fingerprint;
2use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
3use rustc_hir::definitions::DefPathHash;
4use rustc_hir::{HirId, ItemLocalId, OwnerId};
5
6use crate::dep_graph::{DepContext, DepNode, DepNodeExt, DepNodeKey, FingerprintStyle};
7use crate::ty::TyCtxt;
8
9impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for () {
10    #[inline(always)]
11    fn fingerprint_style() -> FingerprintStyle {
12        FingerprintStyle::Unit
13    }
14
15    #[inline(always)]
16    fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
17        Fingerprint::ZERO
18    }
19
20    #[inline(always)]
21    fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
22        Some(())
23    }
24}
25
26impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for DefId {
27    #[inline(always)]
28    fn fingerprint_style() -> FingerprintStyle {
29        FingerprintStyle::DefPathHash
30    }
31
32    #[inline(always)]
33    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
34        tcx.def_path_hash(*self).0
35    }
36
37    #[inline(always)]
38    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
39        tcx.def_path_str(*self)
40    }
41
42    #[inline(always)]
43    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
44        dep_node.extract_def_id(tcx)
45    }
46}
47
48impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for LocalDefId {
49    #[inline(always)]
50    fn fingerprint_style() -> FingerprintStyle {
51        FingerprintStyle::DefPathHash
52    }
53
54    #[inline(always)]
55    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
56        self.to_def_id().to_fingerprint(tcx)
57    }
58
59    #[inline(always)]
60    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
61        self.to_def_id().to_debug_str(tcx)
62    }
63
64    #[inline(always)]
65    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
66        dep_node.extract_def_id(tcx).map(|id| id.expect_local())
67    }
68}
69
70impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for OwnerId {
71    #[inline(always)]
72    fn fingerprint_style() -> FingerprintStyle {
73        FingerprintStyle::DefPathHash
74    }
75
76    #[inline(always)]
77    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
78        self.to_def_id().to_fingerprint(tcx)
79    }
80
81    #[inline(always)]
82    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
83        self.to_def_id().to_debug_str(tcx)
84    }
85
86    #[inline(always)]
87    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
88        dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() })
89    }
90}
91
92impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for CrateNum {
93    #[inline(always)]
94    fn fingerprint_style() -> FingerprintStyle {
95        FingerprintStyle::DefPathHash
96    }
97
98    #[inline(always)]
99    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
100        let def_id = self.as_def_id();
101        def_id.to_fingerprint(tcx)
102    }
103
104    #[inline(always)]
105    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
106        tcx.crate_name(*self).to_string()
107    }
108
109    #[inline(always)]
110    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
111        dep_node.extract_def_id(tcx).map(|id| id.krate)
112    }
113}
114
115impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for (DefId, DefId) {
116    #[inline(always)]
117    fn fingerprint_style() -> FingerprintStyle {
118        FingerprintStyle::Opaque
119    }
120
121    // We actually would not need to specialize the implementation of this
122    // method but it's faster to combine the hashes than to instantiate a full
123    // hashing context and stable-hashing state.
124    #[inline(always)]
125    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
126        let (def_id_0, def_id_1) = *self;
127
128        let def_path_hash_0 = tcx.def_path_hash(def_id_0);
129        let def_path_hash_1 = tcx.def_path_hash(def_id_1);
130
131        def_path_hash_0.0.combine(def_path_hash_1.0)
132    }
133
134    #[inline(always)]
135    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
136        let (def_id_0, def_id_1) = *self;
137
138        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("({0}, {1})",
                tcx.def_path_debug_str(def_id_0),
                tcx.def_path_debug_str(def_id_1)))
    })format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1))
139    }
140}
141
142impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for HirId {
143    #[inline(always)]
144    fn fingerprint_style() -> FingerprintStyle {
145        FingerprintStyle::HirId
146    }
147
148    // We actually would not need to specialize the implementation of this
149    // method but it's faster to combine the hashes than to instantiate a full
150    // hashing context and stable-hashing state.
151    #[inline(always)]
152    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
153        let HirId { owner, local_id } = *self;
154        let def_path_hash = tcx.def_path_hash(owner.to_def_id());
155        Fingerprint::new(
156            // `owner` is local, so is completely defined by the local hash
157            def_path_hash.local_hash(),
158            local_id.as_u32() as u64,
159        )
160    }
161
162    #[inline(always)]
163    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
164        let HirId { owner, local_id } = *self;
165        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}.{1}", tcx.def_path_str(owner),
                local_id.as_u32()))
    })format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32())
166    }
167
168    #[inline(always)]
169    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
170        if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
171            let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
172            let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
173            let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local();
174            let local_id = local_id
175                .as_u64()
176                .try_into()
177                .unwrap_or_else(|_| {
    ::core::panicking::panic_fmt(format_args!("local id should be u32, found {0:?}",
            local_id));
}panic!("local id should be u32, found {local_id:?}"));
178            Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
179        } else {
180            None
181        }
182    }
183}
184
185impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for ModDefId {
186    #[inline(always)]
187    fn fingerprint_style() -> FingerprintStyle {
188        FingerprintStyle::DefPathHash
189    }
190
191    #[inline(always)]
192    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
193        self.to_def_id().to_fingerprint(tcx)
194    }
195
196    #[inline(always)]
197    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
198        self.to_def_id().to_debug_str(tcx)
199    }
200
201    #[inline(always)]
202    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
203        DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
204    }
205}
206
207impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for LocalModDefId {
208    #[inline(always)]
209    fn fingerprint_style() -> FingerprintStyle {
210        FingerprintStyle::DefPathHash
211    }
212
213    #[inline(always)]
214    fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
215        self.to_def_id().to_fingerprint(tcx)
216    }
217
218    #[inline(always)]
219    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
220        self.to_def_id().to_debug_str(tcx)
221    }
222
223    #[inline(always)]
224    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
225        LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
226    }
227}