{"id":"3378c1560700ea47","repo":"rust-lang/rust","slug":"counting-sort-fills-every-slot-of-a-kind-s-range","errorCode":null,"errorMessage":"counting sort fills every slot of a kind's range","messagePattern":"counting sort fills every slot of a kind's range","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_middle/src/dep_graph/serialized.rs","lineNumber":189,"sourceCode":"\nimpl LazyKindIndex {\n    /// Returns this kind's `key_fingerprint -> node index` map.\n    fn fingerprint_map(\n        &self,\n        kind: DepKind,\n        nodes: &IndexSlice<SerializedDepNodeIndex, DepNode>,\n        nodes_by_kind: &[Option<SerializedDepNodeIndex>],\n        profiler: &Option<SelfProfilerRef>,\n    ) -> &UnhashMap<PackedFingerprint, SerializedDepNodeIndex> {\n        self.map.get_or_init(|| {\n            let _prof_timer = profiler\n                .as_ref()\n                .map(|p| p.generic_activity(\"incr_comp_load_dep_graph_reverse_index\"));\n            let range = (self.start as usize)..(self.start as usize + self.len as usize);\n            let mut map =\n                UnhashMap::with_capacity_and_hasher(self.len as usize, Default::default());\n            for &idx in &nodes_by_kind[range] {\n                let idx = idx.expect(\"counting sort fills every slot of a kind's range\");\n                let node = nodes[idx];\n                debug_assert_eq!(node.kind, kind);\n                if map.insert(node.key_fingerprint, idx).is_some()\n                    // Side effect nodes can legitimately share a fingerprint.\n                    && node.kind != DepKind::SideEffect\n                {\n                    panic!(\n                        \"Error: A dep graph node ({kind:?}) does not have an unique index. \\\n                         Running a clean build on a nightly compiler with \\\n                         `-Z incremental-verify-ich` can help narrow down the issue for reporting. \\\n                         A clean build may also work around the issue.\\n\n                         DepNode: {node:?}\"\n                    )\n                }\n            }\n            map\n        })\n    }","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_middle/src/dep_graph/serialized.rs#L171-L207","documentation":"Sanity-check panic inside SerializedDepGraph's reverse-index construction (compiler/rustc_middle/src/dep_graph/serialized.rs:189). While building the key_fingerprint->index map for a given DepKind, it iterates the kind's contiguous range in nodes_by_kind and expects every slot to be Some (the counting sort that built nodes_by_kind should leave no holes). A None slot means the serialized dep-graph is internally inconsistent/corrupt.","triggerScenarios":"Loading an incremental compilation cache whose on-disk SerializedDepGraph was truncated, partially overwritten, or produced by a different rustc version with an incompatible encoding. The panic fires the first time that kind's fingerprint_map is queried (lazy OnceLock init).","commonSituations":"Incremental cache left over from an older/newer nightly after an ABI change; a crashed or killed previous build leaving a half-written dep-graph file; concurrent invocations of rustc writing the same target directory; disk/NFS corruption.","solutions":["Delete the incremental compilation cache directory (e.g. target/debug/incremental) and rebuild clean.","Run with -C incremental=no to bypass incremental loading entirely until the root cause is identified.","Ensure only one rustc process writes a given target dir and that the same toolchain version is used across builds.","If reproducible on a clean build, file a rustc bug with the reproduction case — the serialized dep-graph should never have gaps."],"exampleFix":"# before\nrm -rf target/debug/incremental  # scattered leftovers\n\n# after\ncargo clean && cargo build","handlingStrategy":"retry","validationCode":"// The assertion fires during dep-graph serialization counting sort;\n// no user-facing input can be validated. Pre-flight by ensuring the\n// incremental cache is in a clean state.\nfn ensure_clean_incremental(target_dir: &std::path::Path) {\n    let inc = target_dir.join(\"incremental\");\n    if inc.exists() {\n        std::fs::remove_dir_all(&inc)\n            .expect(\"failed to remove stale incremental cache\");\n    }\n}","typeGuard":null,"tryCatchPattern":"// Wrapper that retries the build once after wiping the incremental\n// cache when an internal dep-graph panic is observed.\nfn build_with_cache_fallback(cmd_fn: impl Fn() -> std::process::Command) -> std::process::ExitStatus {\n    let status = cmd_fn().status().expect(\"failed to spawn cargo\");\n    if !status.success() && std::env::var(\"RUST_BACKTRACE\").is_ok() {\n        let _ = std::fs::remove_dir_all(\"target/debug/incremental\");\n        return cmd_fn().status().expect(\"failed to spawn cargo retry\");\n    }\n    status\n}","preventionTips":["Run periodic clean builds (cargo clean) to discard corrupted incremental state","Avoid interrupting builds mid-write to the incremental cache","Disable incremental compilation for crates with heavy procedural-macro use","Pin a single nightly toolchain per project; do not alternate between nightlies on the same target dir"],"tags":["rustc","incremental-compilation","dep-graph","cache-corruption","deserialization"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}