{"id":"06153050529c7436","repo":"rust-lang/rust","slug":"forbidden-edge-created","errorCode":null,"errorMessage":"forbidden edge {:?} -> {:?} created","messagePattern":"forbidden edge (.+?) -> (.+?) created","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_middle/src/dep_graph/graph.rs","lineNumber":538,"sourceCode":"                        panic_on_forbidden_read(data, dep_node_index)\n                    }\n                };\n                let task_deps = &mut *task_deps;\n\n                if cfg!(debug_assertions) {\n                    data.current.total_read_count.fetch_add(1, Ordering::Relaxed);\n                }\n\n                let new_read = task_deps.reads.insert(dep_node_index, &data.read_recorder_pool);\n                if new_read {\n                    #[cfg(debug_assertions)]\n                    {\n                        if let Some(target) = task_deps.node\n                            && let Some(ref forbidden_edge) = data.current.forbidden_edge\n                        {\n                            let src = forbidden_edge.index_to_node.lock()[&dep_node_index];\n                            if forbidden_edge.test(&src, &target) {\n                                panic!(\"forbidden edge {:?} -> {:?} created\", src, target)\n                            }\n                        }\n                    }\n                } else if cfg!(debug_assertions) {\n                    data.current.total_duplicate_read_count.fetch_add(1, Ordering::Relaxed);\n                }\n            })\n        }\n    }\n\n    /// This encodes a side effect by creating a node with an unique index and associating\n    /// it with the node, for use in the next session.\n    #[inline]\n    pub fn record_diagnostic<'tcx>(&self, tcx: TyCtxt<'tcx>, diagnostic: &DiagInner) {\n        if let Some(ref data) = self.data {\n            read_deps(|task_deps| match task_deps {\n                TaskDepsRef::EvalAlways | TaskDepsRef::Ignore => return,\n                TaskDepsRef::Forbid | TaskDepsRef::Allow(..) => {","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_middle/src/dep_graph/graph.rs#L520-L556","documentation":"Only under `debug_assertions`: when a task records a read edge in the dep graph (graph.rs:538), rustc checks it against a declared `forbidden_edge` set. Creating an edge the dep-graph ordering rules forbid is an internal invariant violation, so the debug build panics with the offending source→target pair. Release builds skip the check.","triggerScenarios":"Running a debug build of rustc (or a dev build with assertions on) where a query records a dependency the dep-graph model says must not exist — i.e. a compiler-internal bug in query dependency tracking. Never reached in release/user builds.","commonSituations":"Hacking on rustc itself with a debug build; running rustc tests under debug assertions; very rarely via a debug-built rustdoc or tool. End users on release builds never see it.","solutions":["If you are not developing rustc, switch to a release/stable rustc — the assertion is debug-only and the underlying behavior is otherwise allowed.","If developing rustc, inspect the src/target dep-node kinds of the reported edge and verify the query's TaskDeps/dep-graph ordering is correct.","Reproduce minimally and file a rustc internal-compiler-error issue with the edge and the query call stack."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before inserting a dependency edge, confirm the (from,to) pair is\n// one the graph's policy actually permits.\nfn assert_edge_allowed(\n    g: &DepGraph,\n    from: DepNodeIndex,\n    to: DepNodeIndex,\n) -> Result<(), String> {\n    if g.is_edge_allowed(from, to) {\n        Ok(())\n    } else {\n        Err(format!(\"forbidden edge {:?} -> {:?}\", from, to))\n    }\n}","typeGuard":"fn is_allowed_edge(g: &DepGraph, from: DepNodeIndex, to: DepNodeIndex) -> bool {\n    g.is_edge_allowed(from, to)\n}","tryCatchPattern":null,"preventionTips":["Do not mix nodes from two different dep-graph instances; edges across graphs are forbidden by construction.","Avoid hand-editing the dep graph; rely on the query system to create edges.","If you observe this from a custom tool, double-check that task serialization preserves the graph identity."],"tags":["rustc","dep-graph","internal","debug-only"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}