]> git.proxmox.com Git - rustc.git/blame - src/librustc/dep_graph/dep_node.rs
New upstream version 1.39.0+dfsg1
[rustc.git] / src / librustc / dep_graph / dep_node.rs
CommitLineData
041b39d2
XL
1//! This module defines the `DepNode` type which the compiler uses to represent
2//! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which
3//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
4//! and a `Fingerprint`, a 128 bit hash value the exact meaning of which
5//! depends on the node's `DepKind`. Together, the kind and the fingerprint
6//! fully identify a dependency node, even across multiple compilation sessions.
7//! In other words, the value of the fingerprint does not depend on anything
8//! that is specific to a given compilation session, like an unpredictable
0731742a 9//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a
041b39d2
XL
10//! pointer. The concept behind this could be compared to how git commit hashes
11//! uniquely identify a given commit and has a few advantages:
12//!
13//! * A `DepNode` can simply be serialized to disk and loaded in another session
14//! without the need to do any "rebasing (like we have to do for Spans and
15//! NodeIds) or "retracing" like we had to do for `DefId` in earlier
16//! implementations of the dependency graph.
17//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
18//! implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
19//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
0731742a 20//! memory without any post-processing (e.g., "abomination-style" pointer
041b39d2
XL
21//! reconstruction).
22//! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
23//! refer to things that do not exist anymore. In previous implementations
24//! `DepNode` contained a `DefId`. A `DepNode` referring to something that
25//! had been removed between the previous and the current compilation session
26//! could not be instantiated because the current compilation session
27//! contained no `DefId` for thing that had been removed.
28//!
29//! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro
30//! defines the `DepKind` enum and a corresponding `DepConstructor` enum. The
31//! `DepConstructor` enum links a `DepKind` to the parameters that are needed at
32//! runtime in order to construct a valid `DepNode` fingerprint.
33//!
34//! Because the macro sees what parameters a given `DepKind` requires, it can
35//! "infer" some properties for each kind of `DepNode`:
36//!
37//! * Whether a `DepNode` of a given kind has any parameters at all. Some
38//! `DepNode`s, like `Krate`, represent global concepts with only one value.
39//! * Whether it is possible, in principle, to reconstruct a query key from a
40//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
41//! in which case it is possible to map the node's fingerprint back to the
42//! `DefId` it was computed from. In other cases, too much information gets
43//! lost during fingerprint computation.
44//!
45//! The `DepConstructor` enum, together with `DepNode::new()` ensures that only
46//! valid `DepNode` instances can be constructed. For example, the API does not
47//! allow for constructing parameterless `DepNode`s with anything other
48//! than a zeroed out fingerprint. More generally speaking, it relieves the
49//! user of the `DepNode` API of having to know how to compute the expected
50//! fingerprint for a given set of node parameters.
51
dc9dc135 52use crate::mir;
9fa01778
XL
53use crate::mir::interpret::GlobalId;
54use crate::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
55use crate::hir::map::DefPathHash;
56use crate::hir::HirId;
041b39d2 57
9fa01778 58use crate::ich::{Fingerprint, StableHashingContext};
041b39d2 59use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
041b39d2
XL
60use std::fmt;
61use std::hash::Hash;
ea8adc8c 62use syntax_pos::symbol::InternedString;
9fa01778
XL
63use crate::traits;
64use crate::traits::query::{
0bf4aa26
XL
65 CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal,
66 CanonicalTypeOpEqGoal, CanonicalTypeOpSubtypeGoal, CanonicalPredicateGoal,
67 CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal,
8faf50e0 68};
532ac7d7
XL
69use crate::ty::{self, TyCtxt, ParamEnvAnd, Ty};
70use crate::ty::subst::SubstsRef;
041b39d2
XL
71
72// erase!() just makes tokens go away. It's used to specify which macro argument
0731742a 73// is repeated (i.e., which sub-expression of the macro we are in) but don't need
041b39d2
XL
74// to actually use any of the arguments.
75macro_rules! erase {
76 ($x:tt) => ({})
77}
78
0531ce1d
XL
79macro_rules! replace {
80 ($x:tt with $($y:tt)*) => ($($y)*)
81}
82
ea8adc8c
XL
83macro_rules! is_anon_attr {
84 (anon) => (true);
85 ($attr:ident) => (false);
86}
87
abe05a73
XL
88macro_rules! is_eval_always_attr {
89 (eval_always) => (true);
90 ($attr:ident) => (false);
91}
92
ea8adc8c
XL
93macro_rules! contains_anon_attr {
94 ($($attr:ident),*) => ({$(is_anon_attr!($attr) | )* false});
95}
96
abe05a73
XL
97macro_rules! contains_eval_always_attr {
98 ($($attr:ident),*) => ({$(is_eval_always_attr!($attr) | )* false});
99}
100
041b39d2
XL
101macro_rules! define_dep_nodes {
102 (<$tcx:tt>
103 $(
ea8adc8c 104 [$($attr:ident),* ]
9fa01778 105 $variant:ident $(( $tuple_arg_ty:ty $(,)? ))*
041b39d2
XL
106 $({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })*
107 ,)*
108 ) => (
109 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
110 RustcEncodable, RustcDecodable)]
111 pub enum DepKind {
112 $($variant),*
113 }
114
115 impl DepKind {
116 #[allow(unreachable_code)]
117 #[inline]
118 pub fn can_reconstruct_query_key<$tcx>(&self) -> bool {
119 match *self {
120 $(
121 DepKind :: $variant => {
ea8adc8c
XL
122 if contains_anon_attr!($($attr),*) {
123 return false;
124 }
3b2f2976 125
041b39d2
XL
126 // tuple args
127 $({
0531ce1d 128 return <$tuple_arg_ty as DepNodeParams>
041b39d2
XL
129 ::CAN_RECONSTRUCT_QUERY_KEY;
130 })*
131
132 // struct args
133 $({
3b2f2976 134
041b39d2
XL
135 return <( $($struct_arg_ty,)* ) as DepNodeParams>
136 ::CAN_RECONSTRUCT_QUERY_KEY;
137 })*
138
139 true
140 }
141 )*
142 }
143 }
144
ea8adc8c 145 pub fn is_anon(&self) -> bool {
041b39d2
XL
146 match *self {
147 $(
ea8adc8c
XL
148 DepKind :: $variant => { contains_anon_attr!($($attr),*) }
149 )*
150 }
151 }
152
0731742a 153 #[inline(always)]
abe05a73
XL
154 pub fn is_eval_always(&self) -> bool {
155 match *self {
156 $(
157 DepKind :: $variant => { contains_eval_always_attr!($($attr), *) }
158 )*
159 }
160 }
161
041b39d2 162 #[allow(unreachable_code)]
041b39d2
XL
163 pub fn has_params(&self) -> bool {
164 match *self {
165 $(
166 DepKind :: $variant => {
167 // tuple args
168 $({
0531ce1d 169 erase!($tuple_arg_ty);
041b39d2
XL
170 return true;
171 })*
172
173 // struct args
174 $({
175 $(erase!($struct_arg_name);)*
176 return true;
177 })*
178
179 false
180 }
181 )*
182 }
183 }
184 }
185
186 pub enum DepConstructor<$tcx> {
187 $(
0531ce1d 188 $variant $(( $tuple_arg_ty ))*
041b39d2
XL
189 $({ $($struct_arg_name : $struct_arg_ty),* })*
190 ),*
191 }
192
193 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
194 RustcEncodable, RustcDecodable)]
195 pub struct DepNode {
196 pub kind: DepKind,
197 pub hash: Fingerprint,
3157f602 198 }
041b39d2
XL
199
200 impl DepNode {
201 #[allow(unreachable_code, non_snake_case)]
0731742a 202 #[inline(always)]
dc9dc135
XL
203 pub fn new<'tcx>(tcx: TyCtxt<'tcx>,
204 dep: DepConstructor<'tcx>)
041b39d2 205 -> DepNode
041b39d2
XL
206 {
207 match dep {
208 $(
0531ce1d 209 DepConstructor :: $variant $(( replace!(($tuple_arg_ty) with arg) ))*
041b39d2
XL
210 $({ $($struct_arg_name),* })*
211 =>
212 {
213 // tuple args
214 $({
0531ce1d
XL
215 erase!($tuple_arg_ty);
216 let hash = DepNodeParams::to_fingerprint(&arg, tcx);
041b39d2
XL
217 let dep_node = DepNode {
218 kind: DepKind::$variant,
219 hash
220 };
221
222 if cfg!(debug_assertions) &&
223 !dep_node.kind.can_reconstruct_query_key() &&
224 (tcx.sess.opts.debugging_opts.incremental_info ||
225 tcx.sess.opts.debugging_opts.query_dep_graph)
226 {
227 tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
0531ce1d 228 arg.to_debug_str(tcx)
041b39d2
XL
229 });
230 }
231
232 return dep_node;
233 })*
234
235 // struct args
236 $({
237 let tupled_args = ( $($struct_arg_name,)* );
238 let hash = DepNodeParams::to_fingerprint(&tupled_args,
239 tcx);
240 let dep_node = DepNode {
241 kind: DepKind::$variant,
242 hash
243 };
244
245 if cfg!(debug_assertions) &&
246 !dep_node.kind.can_reconstruct_query_key() &&
247 (tcx.sess.opts.debugging_opts.incremental_info ||
248 tcx.sess.opts.debugging_opts.query_dep_graph)
249 {
250 tcx.dep_graph.register_dep_node_debug_str(dep_node, || {
251 tupled_args.to_debug_str(tcx)
252 });
253 }
254
255 return dep_node;
256 })*
257
258 DepNode {
259 kind: DepKind::$variant,
ff7c6d11 260 hash: Fingerprint::ZERO,
041b39d2
XL
261 }
262 }
263 )*
264 }
265 }
266
267 /// Construct a DepNode from the given DepKind and DefPathHash. This
268 /// method will assert that the given DepKind actually requires a
269 /// single DefId/DefPathHash parameter.
0731742a 270 #[inline(always)]
041b39d2
XL
271 pub fn from_def_path_hash(kind: DepKind,
272 def_path_hash: DefPathHash)
273 -> DepNode {
0731742a 274 debug_assert!(kind.can_reconstruct_query_key() && kind.has_params());
041b39d2
XL
275 DepNode {
276 kind,
277 hash: def_path_hash.0,
278 }
279 }
280
9fa01778 281 /// Creates a new, parameterless DepNode. This method will assert
041b39d2
XL
282 /// that the DepNode corresponding to the given DepKind actually
283 /// does not require any parameters.
0731742a 284 #[inline(always)]
041b39d2 285 pub fn new_no_params(kind: DepKind) -> DepNode {
0731742a 286 debug_assert!(!kind.has_params());
041b39d2
XL
287 DepNode {
288 kind,
ff7c6d11 289 hash: Fingerprint::ZERO,
041b39d2
XL
290 }
291 }
292
9fa01778 293 /// Extracts the DefId corresponding to this DepNode. This will work
041b39d2
XL
294 /// if two conditions are met:
295 ///
296 /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
297 /// 2. the item that the DefPath refers to exists in the current tcx.
298 ///
299 /// Condition (1) is determined by the DepKind variant of the
300 /// DepNode. Condition (2) might not be fulfilled if a DepNode
301 /// refers to something from the previous compilation session that
302 /// has been removed.
303 #[inline]
dc9dc135 304 pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
041b39d2
XL
305 if self.kind.can_reconstruct_query_key() {
306 let def_path_hash = DefPathHash(self.hash);
8faf50e0
XL
307 tcx.def_path_hash_to_def_id.as_ref()?
308 .get(&def_path_hash).cloned()
041b39d2
XL
309 } else {
310 None
311 }
312 }
313
314 /// Used in testing
315 pub fn from_label_string(label: &str,
316 def_path_hash: DefPathHash)
317 -> Result<DepNode, ()> {
318 let kind = match label {
319 $(
320 stringify!($variant) => DepKind::$variant,
321 )*
322 _ => return Err(()),
323 };
324
325 if !kind.can_reconstruct_query_key() {
326 return Err(());
327 }
328
329 if kind.has_params() {
330 Ok(def_path_hash.to_dep_node(kind))
331 } else {
332 Ok(DepNode::new_no_params(kind))
333 }
334 }
ea8adc8c
XL
335
336 /// Used in testing
337 pub fn has_label_string(label: &str) -> bool {
338 match label {
339 $(
340 stringify!($variant) => true,
341 )*
342 _ => false,
343 }
344 }
345 }
346
347 /// Contains variant => str representations for constructing
348 /// DepNode groups for tests.
349 #[allow(dead_code, non_upper_case_globals)]
350 pub mod label_strs {
351 $(
0731742a 352 pub const $variant: &str = stringify!($variant);
ea8adc8c 353 )*
041b39d2
XL
354 }
355 );
356}
357
358impl fmt::Debug for DepNode {
0bf4aa26 359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
041b39d2
XL
360 write!(f, "{:?}", self.kind)?;
361
ea8adc8c 362 if !self.kind.has_params() && !self.kind.is_anon() {
041b39d2
XL
363 return Ok(());
364 }
365
366 write!(f, "(")?;
367
9fa01778 368 crate::ty::tls::with_opt(|opt_tcx| {
041b39d2
XL
369 if let Some(tcx) = opt_tcx {
370 if let Some(def_id) = self.extract_def_id(tcx) {
ea8adc8c 371 write!(f, "{}", tcx.def_path_debug_str(def_id))?;
041b39d2
XL
372 } else if let Some(ref s) = tcx.dep_graph.dep_node_debug_str(*self) {
373 write!(f, "{}", s)?;
374 } else {
ea8adc8c 375 write!(f, "{}", self.hash)?;
041b39d2
XL
376 }
377 } else {
ea8adc8c 378 write!(f, "{}", self.hash)?;
041b39d2
XL
379 }
380 Ok(())
381 })?;
382
383 write!(f, ")")
384 }
385}
386
387
388impl DefPathHash {
0731742a 389 #[inline(always)]
041b39d2
XL
390 pub fn to_dep_node(self, kind: DepKind) -> DepNode {
391 DepNode::from_def_path_hash(kind, self)
392 }
393}
394
395impl DefId {
0731742a 396 #[inline(always)]
dc9dc135 397 pub fn to_dep_node(self, tcx: TyCtxt<'_>, kind: DepKind) -> DepNode {
041b39d2
XL
398 DepNode::from_def_path_hash(kind, tcx.def_path_hash(self))
399 }
3157f602
XL
400}
401
532ac7d7 402rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
0531ce1d
XL
403 // We use this for most things when incr. comp. is turned off.
404 [] Null,
405
041b39d2
XL
406 // Represents the `Krate` as a whole (the `hir::Krate` value) (as
407 // distinct from the krate module). This is basically a hash of
408 // the entire krate, so if you read from `Krate` (e.g., by calling
0731742a 409 // `tcx.hir().krate()`), we will have to assume that any change
041b39d2
XL
410 // means that you need to be recompiled. This is because the
411 // `Krate` value gives you access to all other items. To avoid
0731742a 412 // this fate, do not call `tcx.hir().krate()`; instead, prefer
041b39d2
XL
413 // wrappers like `tcx.visit_all_items_in_krate()`. If there is no
414 // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
415 // access to the krate, but you must remember to add suitable
416 // edges yourself for the individual items that you read.
532ac7d7 417 [eval_always] Krate,
041b39d2
XL
418
419 // Represents the body of a function or method. The def-id is that of the
420 // function/method.
532ac7d7 421 [eval_always] HirBody(DefId),
041b39d2 422
ea8adc8c 423 // Represents the HIR node with the given node-id
532ac7d7 424 [eval_always] Hir(DefId),
ea8adc8c
XL
425
426 // Represents metadata from an extern crate.
532ac7d7
XL
427 [eval_always] CrateMetadata(CrateNum),
428
429 [eval_always] AllLocalTraitImpls,
abe05a73 430
3b2f2976 431 [anon] TraitSelect,
041b39d2 432
ea8adc8c 433 [] CompileCodegenUnit(InternedString),
532ac7d7
XL
434
435 [eval_always] Analysis(CrateNum),
436]);
437
438pub trait RecoverKey<'tcx>: Sized {
dc9dc135 439 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
532ac7d7
XL
440}
441
442impl RecoverKey<'tcx> for CrateNum {
dc9dc135 443 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
532ac7d7
XL
444 dep_node.extract_def_id(tcx).map(|id| id.krate)
445 }
446}
447
448impl RecoverKey<'tcx> for DefId {
dc9dc135 449 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
532ac7d7
XL
450 dep_node.extract_def_id(tcx)
451 }
452}
453
454impl RecoverKey<'tcx> for DefIndex {
dc9dc135 455 fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
532ac7d7
XL
456 dep_node.extract_def_id(tcx).map(|id| id.index)
457 }
458}
041b39d2 459
dc9dc135 460trait DepNodeParams<'tcx>: fmt::Debug {
041b39d2
XL
461 const CAN_RECONSTRUCT_QUERY_KEY: bool;
462
463 /// This method turns the parameters of a DepNodeConstructor into an opaque
464 /// Fingerprint to be used in DepNode.
465 /// Not all DepNodeParams support being turned into a Fingerprint (they
466 /// don't need to if the corresponding DepNode is anonymous).
dc9dc135 467 fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
041b39d2
XL
468 panic!("Not implemented. Accidentally called on anonymous node?")
469 }
470
dc9dc135 471 fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
041b39d2
XL
472 format!("{:?}", self)
473 }
54a0048b
SL
474}
475
dc9dc135
XL
476impl<'tcx, T> DepNodeParams<'tcx> for T
477where
478 T: HashStable<StableHashingContext<'tcx>> + fmt::Debug,
041b39d2
XL
479{
480 default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
54a0048b 481
dc9dc135 482 default fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
ea8adc8c 483 let mut hcx = tcx.create_stable_hashing_context();
041b39d2
XL
484 let mut hasher = StableHasher::new();
485
486 self.hash_stable(&mut hcx, &mut hasher);
487
488 hasher.finish()
489 }
490
dc9dc135 491 default fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
041b39d2
XL
492 format!("{:?}", *self)
493 }
494}
495
dc9dc135 496impl<'tcx> DepNodeParams<'tcx> for DefId {
041b39d2
XL
497 const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
498
dc9dc135 499 fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
0531ce1d 500 tcx.def_path_hash(*self).0
041b39d2
XL
501 }
502
dc9dc135 503 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
532ac7d7 504 tcx.def_path_str(*self)
041b39d2
XL
505 }
506}
9e0c209e 507
dc9dc135 508impl<'tcx> DepNodeParams<'tcx> for DefIndex {
ea8adc8c
XL
509 const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
510
dc9dc135 511 fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
0731742a 512 tcx.hir().definitions().def_path_hash(*self).0
ea8adc8c
XL
513 }
514
dc9dc135 515 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
532ac7d7 516 tcx.def_path_str(DefId::local(*self))
ea8adc8c
XL
517 }
518}
519
dc9dc135 520impl<'tcx> DepNodeParams<'tcx> for CrateNum {
ea8adc8c
XL
521 const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
522
dc9dc135 523 fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
ea8adc8c 524 let def_id = DefId {
0531ce1d 525 krate: *self,
ea8adc8c
XL
526 index: CRATE_DEF_INDEX,
527 };
528 tcx.def_path_hash(def_id).0
529 }
530
dc9dc135 531 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
0531ce1d 532 tcx.crate_name(*self).as_str().to_string()
ea8adc8c
XL
533 }
534}
535
dc9dc135 536impl<'tcx> DepNodeParams<'tcx> for (DefId, DefId) {
041b39d2
XL
537 const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
538
539 // We actually would not need to specialize the implementation of this
540 // method but it's faster to combine the hashes than to instantiate a full
541 // hashing context and stable-hashing state.
dc9dc135 542 fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
041b39d2
XL
543 let (def_id_0, def_id_1) = *self;
544
545 let def_path_hash_0 = tcx.def_path_hash(def_id_0);
546 let def_path_hash_1 = tcx.def_path_hash(def_id_1);
547
548 def_path_hash_0.0.combine(def_path_hash_1.0)
549 }
550
dc9dc135 551 fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
041b39d2
XL
552 let (def_id_0, def_id_1) = *self;
553
554 format!("({}, {})",
ea8adc8c
XL
555 tcx.def_path_debug_str(def_id_0),
556 tcx.def_path_debug_str(def_id_1))
041b39d2
XL
557 }
558}
559
dc9dc135 560impl<'tcx> DepNodeParams<'tcx> for HirId {
041b39d2
XL
561 const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
562
563 // We actually would not need to specialize the implementation of this
564 // method but it's faster to combine the hashes than to instantiate a full
565 // hashing context and stable-hashing state.
dc9dc135 566 fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
0531ce1d 567 let HirId {
ea8adc8c 568 owner,
a1dfa0c6 569 local_id,
0531ce1d 570 } = *self;
041b39d2 571
ea8adc8c 572 let def_path_hash = tcx.def_path_hash(DefId::local(owner));
a1dfa0c6 573 let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into());
041b39d2 574
ea8adc8c 575 def_path_hash.0.combine(local_id)
54a0048b
SL
576 }
577}
5bcae85e
SL
578
579/// A "work product" corresponds to a `.o` (or other) file that we
9fa01778 580/// save in between runs. These IDs do not have a `DefId` but rather
5bcae85e
SL
581/// some independent path or string that persists between runs without
582/// the need to be mapped or unmapped. (This ensures we can serialize
583/// them even in the absence of a tcx.)
041b39d2
XL
584#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash,
585 RustcEncodable, RustcDecodable)]
586pub struct WorkProductId {
587 hash: Fingerprint
588}
589
590impl WorkProductId {
591 pub fn from_cgu_name(cgu_name: &str) -> WorkProductId {
592 let mut hasher = StableHasher::new();
593 cgu_name.len().hash(&mut hasher);
594 cgu_name.hash(&mut hasher);
595 WorkProductId {
596 hash: hasher.finish()
597 }
598 }
599
600 pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId {
601 WorkProductId {
602 hash: fingerprint
603 }
604 }
7cac9316 605}
041b39d2 606
9fa01778 607impl_stable_hash_for!(struct crate::dep_graph::WorkProductId {
041b39d2
XL
608 hash
609});