{"record":{"id":"4ef3c7c918a1dd76","repo":"rust-lang/rust","slug":"coroutine-lowered-from-async-gen-fn-should-be-in-f","errorCode":null,"errorMessage":"coroutine lowered from async gen fn should be in fn","messagePattern":"coroutine lowered from async gen fn should be in fn","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_borrowck/src/diagnostics/region_name.rs","lineNumber":898,"sourceCode":"                    )) => \" of async gen block\",\n\n                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(\n                        hir::CoroutineDesugaring::AsyncGen,\n                        hir::CoroutineSource::Closure,\n                    ))\n                    | hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::AsyncGen) => {\n                        \" of async gen closure\"\n                    }\n\n                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(\n                        hir::CoroutineDesugaring::AsyncGen,\n                        hir::CoroutineSource::Fn,\n                    )) => {\n                        let parent_item =\n                            tcx.hir_node_by_def_id(tcx.hir_get_parent_item(mir_hir_id).def_id);\n                        let output = &parent_item\n                            .fn_decl()\n                            .expect(\"coroutine lowered from async gen fn should be in fn\")\n                            .output;\n                        span = output.span();\n                        \" of async gen function\"\n                    }\n\n                    hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_)) => {\n                        \" of coroutine\"\n                    }\n                    hir::ClosureKind::Closure => \" of closure\",\n                };\n                (span, mir_description, hir_ty)\n            }\n            node => match node.fn_decl() {\n                Some(fn_decl) => {\n                    let hir_ty = match fn_decl.output {\n                        hir::FnRetTy::DefaultReturn(_) => None,\n                        hir::FnRetTy::Return(ty) => Some(ty),\n                    };","sourceCodeStart":880,"sourceCodeEnd":916,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/compiler/rustc_borrowck/src/diagnostics/region_name.rs#L880-L916","documentation":"This assertion fires inside rustc's borrow-checker region-naming diagnostics when generating a human-readable name for a region belonging to a coroutine that was desugared from an `async gen fn`. The code walks to the coroutine's parent HIR node and calls `.fn_decl().expect(...)` on it. It assumes an async-gen-fn coroutine is always nested inside a function item with an `fn_decl`. If the parent HIR node is not a function (has no fn_decl), the compiler panics with an ICE.","triggerScenarios":"Compiling code that uses `async gen fn` (an unstable async generator function feature) where the desugared coroutine's parent HIR node does not carry an `fn_decl`. This can be triggered by unusual or not-yet-supported placements of async gen functions, or by bugs in HIR construction/coroutine desugaring for new syntax around async generators.","commonSituations":"Using nightly Rust with experimental `async gen fn` or coroutine-closure features in combinations the compiler hasn't fully accounted for. Often appears after a compiler upgrade that changes coroutine desugaring, or when async gen functions appear in unusual HIR positions (e.g. inside certain macro expansions or trait items).","solutions":["Check if the ICE reproduces on the latest nightly; async-gen support is rapidly evolving and this may already be fixed.","Minimize the reproduction: remove async gen functions one by one until the panic disappears, then file a bug at https://github.com/rust-lang/rust/issues with the minimal case.","Rewrite the `async gen fn` as a manual `impl Future` + `Gen` combination or a regular `async fn` returning a stream, to avoid the unstable desugaring path.","If you are a compiler contributor, audit `region_name.rs` lines 890-902: the `parent_item` may need to handle non-`fn_decl` HIR nodes by falling back to `self.body.span` instead of panicking."],"exampleFix":"// before (triggers ICE on some nightly versions)\nasync gen fn items() -> impl Stream<Item = u32> {\n    yield 42;\n}\n\n// after (stable workaround using async-stream crate)\nfn items() -> impl Stream<Item = u32> {\n    async_stream::stream! { yield 42; }\n}","handlingStrategy":"validation","validationCode":"// Before relying on async gen fn, verify the compiler supports the\n// specific HIR placement. As an end user you cannot directly validate\n// compiler internals, but you can gate unstable features:\n// In Cargo.toml or build.rs, check the nightly version:\n#[cfg(not(feature = \"stable-workaround\"))]\ncompile_error!(\"If you hit ICE on async gen fn, enable feature stable-workaround\");","typeGuard":"// No user-level type guard applies; this is a compiler-internal assertion\n// on HIR structure. The 'guard' is avoiding async gen fn in unusual positions.\nnull","tryCatchPattern":"// Rust ICEs are panics; you can catch_unwind to report gracefully\n// (compiler drivers only, not user crates):\nstd::panic::catch_unwind(|| {\n    // invoke rustc/compilation here\n}).unwrap_or_else(|_| {\n    eprintln!(\"ICE encountered; falling back to default borrow checker\");\n});","preventionTips":["Avoid async gen fn in non-fn HIR contexts (trait bodies, macro-generated items) until stabilized.","Pin your nightly toolchain version once verified working with async gen fn.","Track the async-gen feature tracking issue for known ICEs.","Use async-stream crate as a stable alternative to async gen fn."],"tags":["rustc","borrowck","ice","async-gen","coroutine","nightly","compiler-internal"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}