@@ -53,9 +53,13 @@ impl DepNodeColor {
5353
5454#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
5555pub enum DepNodeState {
56- /// The node is invalid since its result is older than the previous session .
56+ /// The dep node index is invalid and does not refer to any dep node .
5757 Invalid ,
5858
59+ /// The node is from the previous session and it is a eval_always node,
60+ // but its state is unknown.
61+ UnknownEvalAlways ,
62+
5963 /// The node is from the previous session, but its state is unknown
6064 Unknown ,
6165
@@ -73,7 +77,8 @@ pub enum DepNodeState {
7377impl DepNodeState {
7478 pub fn color ( self ) -> Option < DepNodeColor > {
7579 match self {
76- DepNodeState :: Invalid |
80+ DepNodeState :: Invalid => bug ! ( ) ,
81+ DepNodeState :: UnknownEvalAlways |
7782 DepNodeState :: Unknown |
7883 DepNodeState :: WasUnknownWillBeGreen => None ,
7984 DepNodeState :: Red => Some ( DepNodeColor :: Red ) ,
@@ -128,6 +133,7 @@ pub struct DepGraphArgs {
128133 pub prev_work_products : FxHashMap < WorkProductId , WorkProduct > ,
129134 pub file : File ,
130135 pub state : IndexVec < DepNodeIndex , AtomicCell < DepNodeState > > ,
136+ pub invalidated : Vec < DepNodeIndex > ,
131137}
132138
133139impl DepGraph {
@@ -141,7 +147,7 @@ impl DepGraph {
141147 data : Some ( Lrc :: new ( DepGraphData {
142148 previous_work_products : args. prev_work_products ,
143149 dep_node_debug : Default :: default ( ) ,
144- current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file ) ,
150+ current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file , args . invalidated ) ,
145151 emitted_diagnostics : Default :: default ( ) ,
146152 emitted_diagnostics_cond_var : Condvar :: new ( ) ,
147153 colors,
@@ -551,11 +557,28 @@ impl DepGraph {
551557 pub fn serialize ( & self ) -> IndexVec < DepNodeIndex , Fingerprint > {
552558 let data = self . data . as_ref ( ) . unwrap ( ) ;
553559 // Invalidate dep nodes with unknown state as these cannot safely
554- // be marked green in the next session.
560+ // be marked green in the next session. One of the dependencies of the
561+ // unknown node may have changed in this session (and is currently marked red),
562+ // but might be green again in the next session, which may cause the unknown node
563+ // to incorrectly be marked green in the next session, even though one of its dependencies
564+ // did actually change.
565+
555566 let invalidate = data. colors . values . indices ( ) . filter_map ( |prev_index| {
556567 match data. colors . get ( prev_index) {
557- DepNodeState :: Unknown => Some ( prev_index) ,
558- _ => None ,
568+ // In order to this invalidation to be safe, none of the valid nodes can
569+ // point to unknown nodes.
570+ DepNodeState :: Unknown |
571+ DepNodeState :: UnknownEvalAlways => Some ( prev_index) ,
572+
573+ DepNodeState :: WasUnknownWillBeGreen => bug ! ( ) ,
574+
575+ // For green nodes, we either executed the query (which always uses valid nodes)
576+ // or we marked it as green because all its dependencies are green and valid.
577+ DepNodeState :: Green |
578+ // Red nodes were always exexuted.
579+ DepNodeState :: Red |
580+ // We don't need to invalidate already invalid nodes
581+ DepNodeState :: Invalid => None ,
559582 }
560583 } ) . collect ( ) ;
561584 // FIXME: Can this deadlock?
@@ -606,8 +629,11 @@ impl DepGraph {
606629 let prev_index = data. previous . node_to_index_opt ( dep_node) ?;
607630
608631 match data. colors . get ( prev_index) {
632+ DepNodeState :: Invalid => bug ! ( ) ,
609633 DepNodeState :: Green => Some ( prev_index) ,
610- DepNodeState :: Invalid |
634+ // We don't need to mark eval_always nodes as green here, since we'll just be executing
635+ // the query after anyway.
636+ DepNodeState :: UnknownEvalAlways |
611637 DepNodeState :: Red => None ,
612638 DepNodeState :: Unknown |
613639 DepNodeState :: WasUnknownWillBeGreen => {
@@ -677,6 +703,7 @@ impl DepGraph {
677703 false
678704 }
679705 DepNodeState :: Invalid |
706+ DepNodeState :: UnknownEvalAlways |
680707 DepNodeState :: Unknown |
681708 DepNodeState :: WasUnknownWillBeGreen => {
682709 bug ! ( "try_force_previous_green() - Forcing the DepNode \
@@ -720,6 +747,7 @@ impl DepGraph {
720747 let dep_dep_node_color = data. colors . get ( dep_dep_node_index) ;
721748
722749 match dep_dep_node_color {
750+ DepNodeState :: Invalid => bug ! ( ) ,
723751 DepNodeState :: Green => {
724752 // This dependency has been marked as green before, we are
725753 // still fine and can continue with checking the other
@@ -740,9 +768,8 @@ impl DepGraph {
740768 data. previous. index_to_node( dep_dep_node_index) ) ;
741769 return false
742770 }
743- // Either the previous result is too old or
744- // this is a eval_always node. Try to force the node
745- DepNodeState :: Invalid => {
771+ // This is a eval_always node. Try to force the node
772+ DepNodeState :: UnknownEvalAlways => {
746773 if !self . try_force_previous_green ( tcx, data, dep_dep_node_index) {
747774 return false ;
748775 }
@@ -885,8 +912,15 @@ impl DepGraph {
885912 }
886913 }
887914 DepNodeState :: WasUnknownWillBeGreen => bug ! ( "no tasks should be in progress" ) ,
915+
916+ // There cannot be results stored for invalid indices.
888917 DepNodeState :: Invalid |
918+
919+ // Unknown nodes are unused, so we don't want to promote these and we would
920+ // not to mark their colors in order to do so anyway.
921+ DepNodeState :: UnknownEvalAlways |
889922 DepNodeState :: Unknown |
923+
890924 DepNodeState :: Red => {
891925 // We can skip red nodes because a node can only be marked
892926 // as red if the query result was recomputed and thus is
@@ -1003,7 +1037,11 @@ pub(super) struct CurrentDepGraph {
10031037}
10041038
10051039impl CurrentDepGraph {
1006- fn new ( prev_graph : Lrc < PreviousDepGraph > , file : File ) -> CurrentDepGraph {
1040+ fn new (
1041+ prev_graph : Lrc < PreviousDepGraph > ,
1042+ file : File ,
1043+ invalidated : Vec < DepNodeIndex > ,
1044+ ) -> CurrentDepGraph {
10071045 use std:: time:: { SystemTime , UNIX_EPOCH } ;
10081046
10091047 let duration = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) ;
@@ -1040,7 +1078,7 @@ impl CurrentDepGraph {
10401078 forbidden_edge,
10411079 total_read_count : AtomicU64 :: new ( 0 ) ,
10421080 total_duplicate_read_count : AtomicU64 :: new ( 0 ) ,
1043- serializer : Lock :: new ( Serializer :: new ( file, prev_graph) ) ,
1081+ serializer : Lock :: new ( Serializer :: new ( file, prev_graph, invalidated ) ) ,
10441082 }
10451083 }
10461084
0 commit comments