{"record":{"id":"fb62a93132bafb56","repo":"rust-lang/rust","slug":"input-too-large-ran-out-of-nodeids","errorCode":null,"errorMessage":"input too large; ran out of NodeIds","messagePattern":"input too large; ran out of NodeIds","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_ast_lowering/src/lib.rs","lineNumber":770,"sourceCode":"            def_kind,\n            self.tcx.hir_def_key(self.local_def_id(node_id)),\n        );\n\n        let def_id = self\n            .tcx\n            .at(span)\n            .create_def(parent, name, def_kind, None, &mut self.current_disambiguator)\n            .def_id();\n\n        debug!(\"create_def: def_id_to_node_id[{:?}] <-> {:?}\", def_id, node_id);\n        self.node_id_to_def_id.insert(node_id, def_id);\n\n        def_id\n    }\n\n    fn next_node_id(&mut self) -> NodeId {\n        let start = self.next_node_id;\n        let next = start.as_u32().checked_add(1).expect(\"input too large; ran out of NodeIds\");\n        self.next_node_id = NodeId::from_u32(next);\n        start\n    }\n\n    /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name\n    /// resolver (if any).\n    #[instrument(level = \"trace\", skip(self), ret)]\n    fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {\n        self.node_id_to_def_id\n            .get(&node)\n            .or_else(|| self.owner.node_id_to_def_id.get(&node))\n            .copied()\n    }\n\n    fn local_def_id(&self, node: NodeId) -> LocalDefId {\n        self.opt_local_def_id(node).unwrap_or_else(|| {\n            self.resolver.owners.items().any(|(id, items)| {\n                items.node_id_to_def_id.items().any(|(node_id, def_id)| {","sourceCodeStart":752,"sourceCodeEnd":788,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/compiler/rustc_ast_lowering/src/lib.rs#L752-L788","documentation":"rustc_ast_lowering assigns a u32-backed NodeId to every AST node (lib.rs:770). next_node_id does checked_add(1).expect(\"input too large; ran out of NodeIds\"); if the counter would exceed u32::MAX the compiler panics. This is a hard limit on the number of nodes in one crate.","triggerScenarios":"Compiling/generated input with more than ~4.29 billion AST nodes in a single crate, almost always heavily generated code (large build.rs output, macro explosions, machine-generated bindings).","commonSituations":"Code generators (e.g. giant #[derive] expansions, build-script-generated source, vendored data tables) that expand into an enormous single crate; pathological macro recursion.","solutions":["Split the oversized crate into smaller sub-crates so no single crate exceeds the node budget.","Reduce generated/macro-expanded content; avoid unrolling huge data into source.","Move large data into include_bytes!/include_str! or a build step rather than literal AST nodes.","If genuinely needed, track the upstream issue for wider NodeId; for now the only fix is smaller crates."],"exampleFix":"// before: one crate with millions of generated items\n// (generated.rs: 5_000_000 fn items)\n\n// after: shard generated items across submodules compiled as separate crates\n// crate a: mod m1; crate b: mod m2; ... link them","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Split oversized generated crates into smaller sub-crates so each stays well under the u32 node budget.","Prefer include_bytes!/include_str! or build-time binary assets over literal unrolled AST nodes.","Audit build.rs and proc-macro output for runaway expansion before compiling.","Track the upstream issue for a wider NodeId; until then, smaller crates are the only mitigation."],"tags":["rust","ast-lowering","scale","node-id"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}