{"record":{"id":"fe7c2fdf7eeab976","repo":"rust-lang/rust-analyzer","slug":"you-have-way-too-many-items-in-the-same-file","errorCode":null,"errorMessage":"you have way too many items in the same file!","messagePattern":"you have way too many items in the same file!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/span/src/ast_id.rs","lineNumber":491,"sourceCode":"        let mut hash = initial_hash;\n        let index = loop {\n            match self.0.entry((kind, hash)) {\n                std::collections::hash_map::Entry::Occupied(mut entry) => {\n                    let i = entry.get_mut();\n                    if *i < ((1 << INDEX_BITS) - 1) {\n                        *i += 1;\n                        break *i;\n                    }\n                }\n                std::collections::hash_map::Entry::Vacant(entry) => {\n                    entry.insert(0);\n                    break 0;\n                }\n            }\n            hash = hash.wrapping_add(1);\n            if hash == initial_hash {\n                // That's 2^27=134,217,728 items!\n                panic!(\"you have way too many items in the same file!\");\n            }\n        };\n        let kind = kind as u32;\n        ErasedFileAstId(pack_hash_index_and_kind(hash, index, kind))\n    }\n}\n\nmacro_rules! register_enum_ast_id {\n    (impl $AstIdNode:ident for $($ident:ident),+ ) => {\n        $(\n            impl $AstIdNode for ast::$ident {}\n        )+\n    };\n}\nregister_enum_ast_id! {\n    impl AstIdNode for\n    Item, AnyHasGenericParams, Adt, Macro,\n    AssocItem","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/span/src/ast_id.rs#L473-L509","documentation":"AstIdMap uses an open-addressed hash table to assign compact ids (ErasedFileAstId) to syntax nodes of a single file, encoding hash, index, and kind into one u32. When probing for a free slot wraps all the way around to the initial hash, it means 2^27 (134,217,728) items were hashed into the same file's map — the id space is exhausted. This is an intentional safeguard against runaway insertion, since a real source file can never legitimately contain that many items.","triggerScenarios":"Inserting more than 2^27 distinct AST nodes into a single AstIdMap via `new_id`, which in practice only happens if the insertion loop never finds its slot due to a corrupted/oversized map, or a pathological generated/huge file, or a bug inserting the same overflowing data repeatedly.","commonSituations":"Essentially only seen by rust-analyzer developers during changes to AstIdMap internals (hashing, capacity, or arena growth), or when fuzzing/parsing an absurdly large synthetic file; end users should never hit it.","solutions":["Reduce the number of items inserted into a single file's AstIdMap (split or truncate the file)","If you changed AstIdMap internals, verify the probe loop terminates correctly and capacity invariants hold","Check for a bug that re-inserts the same nodes infinitely (arena growth loop)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Cap file size before parsing/id-mapping:\nif node_count_estimate(file_text) > MAX_SUPPORTED_ITEMS {\n    return Err(AnalysisCancelled::FileTooLarge);\n}","typeGuard":null,"tryCatchPattern":"// Wrap map construction during experiments:\nlet map = std::panic::catch_unwind(|| AstIdMap::from_source(source))\n    .unwrap_or_else(|_| AstIdMap::default());","preventionTips":["Don't feed synthetic multi-hundred-million-node files to analysis","Review probe-loop/termination logic when touching AstIdMap internals","Fuzz AstIdMap with large generated inputs before landing encoding changes"],"tags":["rust","panic","invariant","internal-limit"],"backgroundTag":"ast-id-capacity-exceeded","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}