Skip to content

Commit 87644d8

Browse files
committed
Print a backtrace when query forcing fails.
1 parent 7919ef0 commit 87644d8

File tree

1 file changed

+45
-11
lines changed
  • compiler/rustc_query_system/src/dep_graph

1 file changed

+45
-11
lines changed

compiler/rustc_query_system/src/dep_graph/graph.rs

+45-11
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)