diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2024-04-22 20:26:00 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-22 20:26:00 +0200 |
| commit | a60ccc18765f5da5cf872f3e68b3e6adc18d7bc3 (patch) | |
| tree | 8dbc105dfc95f136f51d88407b30c1ec6dc13f8c /compiler/rustc_query_system | |
| parent | 6a326d889a7076936fa1baeee16cfce6e72e1c24 (diff) | |
| parent | 6146a51f17f19b557c2baf11a1ae04cbafdd89bb (diff) | |
| download | rust-a60ccc18765f5da5cf872f3e68b3e6adc18d7bc3.tar.gz rust-a60ccc18765f5da5cf872f3e68b3e6adc18d7bc3.zip | |
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 https://github.com/rust-lang/rust/pull/123781, where this would have been helpful.
Diffstat (limited to 'compiler/rustc_query_system')
| -rw-r--r-- | compiler/rustc_query_system/src/dep_graph/graph.rs | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 534937003eb..2b3fa7f6cfa 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -459,7 +459,8 @@ impl<D: Deps> DepGraph<D> { } TaskDepsRef::Ignore => return, TaskDepsRef::Forbid => { - panic!("Illegal read of: {dep_node_index:?}") + // Reading is forbidden in this context. ICE with a useful error message. + panic_on_forbidden_read(data, dep_node_index) } }; let task_deps = &mut *task_deps; @@ -1366,3 +1367,45 @@ pub(crate) fn print_markframe_trace<D: Deps>(graph: &DepGraph<D>, frame: Option< eprintln!("end of try_mark_green dep node stack"); } + +#[cold] +#[inline(never)] +fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepNodeIndex) -> ! { + // We have to do an expensive reverse-lookup of the DepNode that + // corresponds to `dep_node_index`, but that's OK since we are about + // to ICE anyway. + let mut dep_node = None; + + // First try to find the dep node among those that already existed in the + // previous session + for (prev_index, index) in data.current.prev_index_to_index.lock().iter_enumerated() { + if index == &Some(dep_node_index) { + dep_node = Some(data.previous.index_to_node(prev_index)); + break; + } + } + + if dep_node.is_none() { + // Try to find it among the new nodes + for shard in data.current.new_node_to_index.lock_shards() { + if let Some((node, _)) = shard.iter().find(|(_, index)| **index == dep_node_index) { + dep_node = Some(*node); + break; + } + } + } + + let dep_node = dep_node.map_or_else( + || format!("with index {:?}", dep_node_index), + |dep_node| format!("`{:?}`", dep_node), + ); + + panic!( + "Error: trying to record dependency on DepNode {dep_node} in a \ + context that does not allow it (e.g. during query deserialization). \ + The most common case of recording a dependency on a DepNode `foo` is \ + when the correspondng query `foo` is invoked. Invoking queries is not \ + allowed as part of loading something from the incremental on-disk cache. \ + See <https://github.com/rust-lang/rust/pull/91919>." + ) +} |
