@@ -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 {
@@ -142,7 +148,7 @@ impl DepGraph {
142148 data : Some ( Lrc :: new ( DepGraphData {
143149 previous_work_products : args. prev_work_products ,
144150 dep_node_debug : Default :: default ( ) ,
145- current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file ) ,
151+ current : CurrentDepGraph :: new ( prev_graph. clone ( ) , args. file , args . invalidated ) ,
146152 emitted_diagnostics : Default :: default ( ) ,
147153 emitted_diagnostics_cond_var : Condvar :: new ( ) ,
148154 colors,
@@ -552,11 +558,28 @@ impl DepGraph {
552558 pub fn serialize ( & self ) -> IndexVec < DepNodeIndex , Fingerprint > {
553559 let data = self . data . as_ref ( ) . unwrap ( ) ;
554560 // Invalidate dep nodes with unknown state as these cannot safely
555- // be marked green in the next session.
561+ // be marked green in the next session. One of the dependencies of the
562+ // unknown node may have changed in this session (and is currently marked red),
563+ // but might be green again in the next session, which may cause the unknown node
564+ // to incorrectly be marked green in the next session, even though one of its dependencies
565+ // did actually change.
566+
556567 let invalidate = data. colors . values . indices ( ) . filter_map ( |prev_index| {
557568 match data. colors . get ( prev_index) {
558- DepNodeState :: Unknown => Some ( prev_index) ,
559- _ => None ,
569+ // In order to this invalidation to be safe, none of the valid nodes can
570+ // point to unknown nodes.
571+ DepNodeState :: Unknown |
572+ DepNodeState :: UnknownEvalAlways => Some ( prev_index) ,
573+
574+ DepNodeState :: WasUnknownWillBeGreen => bug ! ( ) ,
575+
576+ // For green nodes, we either executed the query (which always uses valid nodes)
577+ // or we marked it as green because all its dependencies are green and valid.
578+ DepNodeState :: Green |
579+ // Red nodes were always exexuted.
580+ DepNodeState :: Red |
581+ // We don't need to invalidate already invalid nodes
582+ DepNodeState :: Invalid => None ,
560583 }
561584 } ) . collect ( ) ;
562585 // FIXME: Can this deadlock?
@@ -607,8 +630,11 @@ impl DepGraph {
607630 let prev_index = data. previous . node_to_index_opt ( dep_node) ?;
608631
609632 match data. colors . get ( prev_index) {
633+ DepNodeState :: Invalid => bug ! ( ) ,
610634 DepNodeState :: Green => Some ( prev_index) ,
611- DepNodeState :: Invalid |
635+ // We don't need to mark eval_always nodes as green here, since we'll just be executing
636+ // the query after anyway.
637+ DepNodeState :: UnknownEvalAlways |
612638 DepNodeState :: Red => None ,
613639 DepNodeState :: Unknown |
614640 DepNodeState :: WasUnknownWillBeGreen => {
@@ -678,6 +704,7 @@ impl DepGraph {
678704 false
679705 }
680706 DepNodeState :: Invalid |
707+ DepNodeState :: UnknownEvalAlways |
681708 DepNodeState :: Unknown |
682709 DepNodeState :: WasUnknownWillBeGreen => {
683710 bug ! ( "try_force_previous_green() - Forcing the DepNode \
@@ -721,6 +748,7 @@ impl DepGraph {
721748 let dep_dep_node_color = data. colors . get ( dep_dep_node_index) ;
722749
723750 match dep_dep_node_color {
751+ DepNodeState :: Invalid => bug ! ( ) ,
724752 DepNodeState :: Green => {
725753 // This dependency has been marked as green before, we are
726754 // still fine and can continue with checking the other
@@ -741,9 +769,8 @@ impl DepGraph {
741769 data. previous. index_to_node( dep_dep_node_index) ) ;
742770 return false
743771 }
744- // Either the previous result is too old or
745- // this is a eval_always node. Try to force the node
746- DepNodeState :: Invalid => {
772+ // This is a eval_always node. Try to force the node
773+ DepNodeState :: UnknownEvalAlways => {
747774 if !self . try_force_previous_green ( tcx, data, dep_dep_node_index) {
748775 return false ;
749776 }
@@ -886,8 +913,15 @@ impl DepGraph {
886913 }
887914 }
888915 DepNodeState :: WasUnknownWillBeGreen => bug ! ( "no tasks should be in progress" ) ,
916+
917+ // There cannot be results stored for invalid indices.
889918 DepNodeState :: Invalid |
919+
920+ // Unknown nodes are unused, so we don't want to promote these and we would
921+ // not to mark their colors in order to do so anyway.
922+ DepNodeState :: UnknownEvalAlways |
890923 DepNodeState :: Unknown |
924+
891925 DepNodeState :: Red => {
892926 // We can skip red nodes because a node can only be marked
893927 // as red if the query result was recomputed and thus is
@@ -1004,7 +1038,11 @@ pub(super) struct CurrentDepGraph {
10041038}
10051039
10061040impl CurrentDepGraph {
1007- fn new ( prev_graph : Lrc < PreviousDepGraph > , file : File ) -> CurrentDepGraph {
1041+ fn new (
1042+ prev_graph : Lrc < PreviousDepGraph > ,
1043+ file : File ,
1044+ invalidated : Vec < DepNodeIndex > ,
1045+ ) -> CurrentDepGraph {
10081046 use std:: time:: { SystemTime , UNIX_EPOCH } ;
10091047
10101048 let duration = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap ( ) ;
@@ -1041,7 +1079,7 @@ impl CurrentDepGraph {
10411079 forbidden_edge,
10421080 total_read_count : AtomicU64 :: new ( 0 ) ,
10431081 total_duplicate_read_count : AtomicU64 :: new ( 0 ) ,
1044- serializer : Lock :: new ( Serializer :: new ( file, prev_graph) ) ,
1082+ serializer : Lock :: new ( Serializer :: new ( file, prev_graph, invalidated ) ) ,
10451083 }
10461084 }
10471085
0 commit comments