Rollup merge of #152067 - Zoxc:graph-weak-assert, r=jackh726

Weaken `assert_dep_node_not_yet_allocated_in_current_session` for multiple threads

This changes `assert_dep_node_not_yet_allocated_in_current_session` to not panic if the node is already marked green. Another thread may manage to mark it green if there was uncolored node when we initially tried to mark it green.
This commit is contained in:
Stuart Cook 2026-02-08 16:58:25 +11:00 committed by GitHub
commit 60eaaba6c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 9 deletions

View file

@ -1111,7 +1111,7 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) ->
// know that later). If we are not doing LTO, there is only one optimized
// version of each module, so we re-use that.
let dep_node = cgu.codegen_dep_node(tcx);
tcx.dep_graph.assert_dep_node_not_yet_allocated_in_current_session(&dep_node, || {
tcx.dep_graph.assert_dep_node_not_yet_allocated_in_current_session(tcx.sess, &dep_node, || {
format!(
"CompileCodegenUnit dep-node for CGU `{}` already exists before marking.",
cgu.name()

View file

@ -336,13 +336,17 @@ impl<D: Deps> DepGraphData<D> {
// in `DepGraph::try_mark_green()`.
// 2. Two distinct query keys get mapped to the same `DepNode`
// (see for example #48923).
self.assert_dep_node_not_yet_allocated_in_current_session(&key, || {
format!(
"forcing query with already existing `DepNode`\n\
self.assert_dep_node_not_yet_allocated_in_current_session(
cx.dep_context().sess(),
&key,
|| {
format!(
"forcing query with already existing `DepNode`\n\
- query-key: {arg:?}\n\
- dep-node: {key:?}"
)
});
)
},
);
let with_deps = |task_deps| D::with_deps(task_deps, || task(cx, arg));
let (result, edges) = if cx.dep_context().is_eval_always(key.kind) {
@ -627,12 +631,20 @@ impl<D: Deps> DepGraph<D> {
impl<D: Deps> DepGraphData<D> {
fn assert_dep_node_not_yet_allocated_in_current_session<S: std::fmt::Display>(
&self,
sess: &Session,
dep_node: &DepNode,
msg: impl FnOnce() -> S,
) {
if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) {
let current = self.colors.get(prev_index);
assert_matches!(current, DepNodeColor::Unknown, "{}", msg())
let color = self.colors.get(prev_index);
let ok = match color {
DepNodeColor::Unknown => true,
DepNodeColor::Red => false,
DepNodeColor::Green(..) => sess.threads() > 1, // Other threads may mark this green
};
if !ok {
panic!("{}", msg())
}
} else if let Some(nodes_in_current_session) = &self.current.nodes_in_current_session {
outline(|| {
let seen = nodes_in_current_session.lock().contains_key(dep_node);
@ -1035,11 +1047,12 @@ impl<D: Deps> DepGraph<D> {
pub fn assert_dep_node_not_yet_allocated_in_current_session<S: std::fmt::Display>(
&self,
sess: &Session,
dep_node: &DepNode,
msg: impl FnOnce() -> S,
) {
if let Some(data) = &self.data {
data.assert_dep_node_not_yet_allocated_in_current_session(dep_node, msg)
data.assert_dep_node_not_yet_allocated_in_current_session(sess, dep_node, msg)
}
}