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