Skip to content

Fix collector ICE on closures from non-local crates#345

Open
mbrobbel wants to merge 2 commits into
NVlabs:mainfrom
mbrobbel:fix-collector-ice-external-crate-closures
Open

Fix collector ICE on closures from non-local crates#345
mbrobbel wants to merge 2 commits into
NVlabs:mainfrom
mbrobbel:fix-collector-ice-external-crate-closures

Conversation

@mbrobbel

@mbrobbel mbrobbel commented Jul 6, 2026

Copy link
Copy Markdown

Kernels that reach a closure defined in a dependency crate ICE the compiler:

error: internal compiler error: .../rustc_middle/src/ty/mod.rs:1529:13: item_name: no name for DefPath { data: [DisambiguatedDefPathData { data: ValueNs("gated_load"), disambiguator: 0 }, DisambiguatedDefPathData { data: Closure, disambiguator: 0 }], krate: crate48 }
  ...
  <rustc_codegen_cuda::collector::DeviceCollector>::should_collect_from_crate
  <rustc_codegen_cuda::collector::DeviceCollector>::enqueue_callable_trait_receiver_body

should_collect_from_crate (collector.rs) calls tcx.item_name to allow cross-crate kernel entry points, but closures have no item name. Closure DefIds from non-local crates reach it via enqueue_callable_trait_receiver_body — e.g. an FnOnce receiver inside a library function called from a kernel. Local-crate closures take the early LOCAL_CRATE return, so existing examples never hit this.

The fix uses opt_item_name and falls through to the crate-based decision for unnamed items, which can never be kernel entry points.

The first commit adds an extern_crate_closure example (following the cross_crate_embedded pattern) that reproduces the ICE without the fix; the closure is routed through an #[inline(never)] applier so MIR inlining doesn't erase it before collection.

🤖 Generated with Claude Code

mbrobbel and others added 2 commits July 6, 2026 11:15
Kernels that reach a closure defined in a non-local crate (here via an
FnOnce trait receiver in helper-lib) ICE the device collector:

  internal compiler error: item_name: no name for DefPath { ...
  Closure ... } via DeviceCollector::should_collect_from_crate <-
  enqueue_callable_trait_receiver_body

Local-crate closures never hit this (early LOCAL_CRATE return), which is
why existing examples pass. This example fails until the collector fix
in the next commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Matthijs Brobbel <m1brobbel@gmail.com>
should_collect_from_crate checked the cross-crate kernel-entry-point
case with tcx.item_name, which ICEs for unnamed items. Closures in a
non-local crate reach it via enqueue_callable_trait_receiver_body
(e.g. an FnOnce receiver inside a library function called from a
kernel); local-crate closures take the early LOCAL_CRATE return, so
this only surfaced with external dependencies.

Use opt_item_name and fall through to the crate-based decision for
unnamed items, which can never be kernel entry points.

Fixes the extern_crate_closure example added in the previous commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Matthijs Brobbel <m1brobbel@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant