Skip to content

Commit a60ccc1

Browse files
Rollup merge of #124252 - michaelwoerister:better-forbidden-read-ice, r=oli-obk
Improve ICE message for forbidden dep-graph reads. The new message mentions the main context that the ICE might occur in and it mentions the query/dep-node that is being read. cc #123781, where this would have been helpful.
2 parents 6a326d8 + 6146a51 commit a60ccc1

File tree

1 file changed

+44
-1
lines changed
  • compiler/rustc_query_system/src/dep_graph

1 file changed

+44
-1
lines changed

compiler/rustc_query_system/src/dep_graph/graph.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,8 @@ impl<D: Deps> DepGraph<D> {
459459
}
460460
TaskDepsRef::Ignore => return,
461461
TaskDepsRef::Forbid => {
462-
panic!("Illegal read of: {dep_node_index:?}")
462+
// Reading is forbidden in this context. ICE with a useful error message.
463+
panic_on_forbidden_read(data, dep_node_index)
463464
}
464465
};
465466
let task_deps = &mut *task_deps;
@@ -1366,3 +1367,45 @@ pub(crate) fn print_markframe_trace<D: Deps>(graph: &DepGraph<D>, frame: Option<
13661367

13671368
eprintln!("end of try_mark_green dep node stack");
13681369
}
1370+
1371+
#[cold]
1372+
#[inline(never)]
1373+
fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepNodeIndex) -> ! {
1374+
// We have to do an expensive reverse-lookup of the DepNode that
1375+
// corresponds to `dep_node_index`, but that's OK since we are about
1376+
// to ICE anyway.
1377+
let mut dep_node = None;
1378+
1379+
// First try to find the dep node among those that already existed in the
1380+
// previous session
1381+
for (prev_index, index) in data.current.prev_index_to_index.lock().iter_enumerated() {
1382+
if index == &Some(dep_node_index) {
1383+
dep_node = Some(data.previous.index_to_node(prev_index));
1384+
break;
1385+
}
1386+
}
1387+
1388+
if dep_node.is_none() {
1389+
// Try to find it among the new nodes
1390+
for shard in data.current.new_node_to_index.lock_shards() {
1391+
if let Some((node, _)) = shard.iter().find(|(_, index)| **index == dep_node_index) {
1392+
dep_node = Some(*node);
1393+
break;
1394+
}
1395+
}
1396+
}
1397+
1398+
let dep_node = dep_node.map_or_else(
1399+
|| format!("with index {:?}", dep_node_index),
1400+
|dep_node| format!("`{:?}`", dep_node),
1401+
);
1402+
1403+
panic!(
1404+
"Error: trying to record dependency on DepNode {dep_node} in a \
1405+
context that does not allow it (e.g. during query deserialization). \
1406+
The most common case of recording a dependency on a DepNode `foo` is \
1407+
when the correspondng query `foo` is invoked. Invoking queries is not \
1408+
allowed as part of loading something from the incremental on-disk cache. \
1409+
See <https://github.com/rust-lang/rust/pull/91919>."
1410+
)
1411+
}

0 commit comments

Comments
 (0)