@@ -603,6 +603,49 @@ macro_rules! define_provider_struct {
603603 } ;
604604}
605605
606+
607+ /// The red/green evaluation system will try to mark a specific DepNode in the
608+ /// dependency graph as green by recursively trying to mark the dependencies of
609+ /// that DepNode as green. While doing so, it will sometimes encounter a DepNode
610+ /// where we don't know if it is red or green and we therefore actually have
611+ /// to recompute its value in order to find out. Since the only piece of
612+ /// information that we have at that point is the DepNode we are trying to
613+ /// re-evaluate, we need some way to re-run a query from just that. This is what
614+ /// `force_from_dep_node()` implements.
615+ ///
616+ /// In the general case, a DepNode consists of a DepKind and an opaque
617+ /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
618+ /// is usually constructed by computing a stable hash of the query-key that the
619+ /// DepNode corresponds to. Consequently, it is not in general possible to go
620+ /// back from hash to query-key (since hash functions are not reversible). For
621+ /// this reason `force_from_dep_node()` is expected to fail from time to time
622+ /// because we just cannot find out, from the DepNode alone, what the
623+ /// corresponding query-key is and therefore cannot re-run the query.
624+ ///
625+ /// The system deals with this case letting `try_mark_green` fail which forces
626+ /// the root query to be re-evaluated.
627+ ///
628+ /// Now, if force_from_dep_node() would always fail, it would be pretty useless.
629+ /// Fortunately, we can use some contextual information that will allow us to
630+ /// reconstruct query-keys for certain kinds of DepNodes. In particular, we
631+ /// enforce by construction that the GUID/fingerprint of certain DepNodes is a
632+ /// valid DefPathHash. Since we also always build a huge table that maps every
633+ /// DefPathHash in the current codebase to the corresponding DefId, we have
634+ /// everything we need to re-run the query.
635+ ///
636+ /// Take the `mir_validated` query as an example. Like many other queries, it
637+ /// just has a single parameter: the DefId of the item it will compute the
638+ /// validated MIR for. Now, when we call `force_from_dep_node()` on a dep-node
639+ /// with kind `MirValidated`, we know that the GUID/fingerprint of the dep-node
640+ /// is actually a DefPathHash, and can therefore just look up the corresponding
641+ /// DefId in `tcx.def_path_hash_to_def_id`.
642+ ///
643+ /// When you implement a new query, it will likely have a corresponding new
644+ /// DepKind, and you'll have to support it here in `force_from_dep_node()`. As
645+ /// a rule of thumb, if your query takes a DefId or DefIndex as sole parameter,
646+ /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
647+ /// add it to the "We don't have enough information to reconstruct..." group in
648+ /// the match below.
606649pub fn force_from_dep_node < ' a , ' gcx , ' lcx > ( tcx : TyCtxt < ' a , ' gcx , ' lcx > ,
607650 dep_node : & DepNode )
608651 -> bool {
@@ -687,16 +730,16 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
687730 DepKind :: Hir |
688731
689732 // This are anonymous nodes
733+ DepKind :: TraitSelect |
734+
735+ // We don't have enough information to reconstruct the query key of
736+ // these
690737 DepKind :: IsCopy |
691738 DepKind :: IsSized |
692739 DepKind :: IsFreeze |
693740 DepKind :: NeedsDrop |
694741 DepKind :: Layout |
695- DepKind :: TraitSelect |
696742 DepKind :: ConstEval |
697-
698- // We don't have enough information to reconstruct the query key of
699- // these
700743 DepKind :: InstanceSymbolName |
701744 DepKind :: MirShim |
702745 DepKind :: BorrowCheckKrate |
0 commit comments