@@ -671,15 +671,45 @@ impl<K: DepKind> DepGraph<K> {
671671 let prev_index = data. previous . node_to_index_opt ( dep_node) ?;
672672
673673 match data. colors . get ( prev_index) {
674- Some ( DepNodeColor :: Green ( dep_node_index) ) => Some ( ( prev_index, dep_node_index) ) ,
675- Some ( DepNodeColor :: Red ) => None ,
676- None => {
677- // This DepNode and the corresponding query invocation existed
678- // in the previous compilation session too, so we can try to
679- // mark it as green by recursively marking all of its
680- // dependencies green.
681- self . try_mark_previous_green ( qcx, data, prev_index, & dep_node)
682- . map ( |dep_node_index| ( prev_index, dep_node_index) )
674+ Some ( DepNodeColor :: Green ( dep_node_index) ) => return Some ( ( prev_index, dep_node_index) ) ,
675+ Some ( DepNodeColor :: Red ) => return None ,
676+ None => { }
677+ }
678+
679+ let mut stack =
680+ MarkingStack { stack : vec ! [ prev_index] , sess : qcx. dep_context ( ) . sess ( ) , graph : data } ;
681+
682+ // This DepNode and the corresponding query invocation existed
683+ // in the previous compilation session too, so we can try to
684+ // mark it as green by recursively marking all of its
685+ // dependencies green.
686+ return self
687+ . try_mark_previous_green ( qcx, data, prev_index, & dep_node, & mut stack. stack )
688+ . map ( |dep_node_index| ( prev_index, dep_node_index) ) ;
689+
690+ /// Remember the stack of queries we are forcing in the event of an incr. comp. panic.
691+ struct MarkingStack < ' a , K : DepKind > {
692+ stack : Vec < SerializedDepNodeIndex > ,
693+ sess : & ' a rustc_session:: Session ,
694+ graph : & ' a DepGraphData < K > ,
695+ }
696+
697+ impl < ' a , K : DepKind > Drop for MarkingStack < ' a , K > {
698+ /// Print the forcing backtrace.
699+ fn drop ( & mut self ) {
700+ for & frame in self . stack . iter ( ) . skip ( 1 ) . rev ( ) {
701+ let node = self . graph . previous . index_to_node ( frame) ;
702+ // Do not try to rely on DepNode's Debug implementation,
703+ // since it may panic.
704+ let diag = rustc_errors:: Diagnostic :: new (
705+ rustc_errors:: Level :: FailureNote ,
706+ & format ! (
707+ "encountered while trying to mark dependency green: {:?}({})" ,
708+ node. kind, node. hash
709+ ) ,
710+ ) ;
711+ self . sess . diagnostic ( ) . force_print_diagnostic ( diag) ;
712+ }
683713 }
684714 }
685715 }
@@ -691,6 +721,7 @@ impl<K: DepKind> DepGraph<K> {
691721 data : & DepGraphData < K > ,
692722 parent_dep_node_index : SerializedDepNodeIndex ,
693723 dep_node : & DepNode < K > ,
724+ stack : & mut Vec < SerializedDepNodeIndex > ,
694725 ) -> Option < ( ) > {
695726 let dep_dep_node_color = data. colors . get ( parent_dep_node_index) ;
696727 let dep_dep_node = & data. previous . index_to_node ( parent_dep_node_index) ;
@@ -723,7 +754,7 @@ impl<K: DepKind> DepGraph<K> {
723754 ) ;
724755
725756 let node_index =
726- self . try_mark_previous_green ( qcx, data, parent_dep_node_index, dep_dep_node) ;
757+ self . try_mark_previous_green ( qcx, data, parent_dep_node_index, dep_dep_node, stack ) ;
727758
728759 if node_index. is_some ( ) {
729760 debug ! ( "managed to MARK dependency {dep_dep_node:?} as green" , ) ;
@@ -779,6 +810,7 @@ impl<K: DepKind> DepGraph<K> {
779810 data : & DepGraphData < K > ,
780811 prev_dep_node_index : SerializedDepNodeIndex ,
781812 dep_node : & DepNode < K > ,
813+ stack : & mut Vec < SerializedDepNodeIndex > ,
782814 ) -> Option < DepNodeIndex > {
783815 #[ cfg( not( parallel_compiler) ) ]
784816 {
@@ -794,7 +826,9 @@ impl<K: DepKind> DepGraph<K> {
794826 let prev_deps = data. previous . edge_targets_from ( prev_dep_node_index) ;
795827
796828 for & dep_dep_node_index in prev_deps {
797- self . try_mark_parent_green ( qcx, data, dep_dep_node_index, dep_node) ?
829+ stack. push ( dep_dep_node_index) ;
830+ self . try_mark_parent_green ( qcx, data, dep_dep_node_index, dep_node, stack) ?;
831+ stack. pop ( ) ;
798832 }
799833
800834 // If we got here without hitting a `return` that means that all
0 commit comments