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