rust-lang/rust · critical

processing delegation

Error message

processing delegation

What it means

expect() message in hir_delegation_info (compiler/rustc_middle/src/hir/map.rs:873). It calls opt_hir_owner_node(...).fn_decl()?.opt_delegation_info() and unwraps with 'processing delegation'. If the owner has no FnDecl or that FnDecl carries no DelegationInfo, the Option is None and this panics, meaning the def_id is not actually a delegation item.

Source

Thrown at compiler/rustc_middle/src/hir/map.rs:873

    }

    pub fn hir_expect_expr(self, id: HirId) -> &'tcx Expr<'tcx> {
        match self.hir_node(id) {
            Node::Expr(expr) => expr,
            _ => bug!("expected expr, found {}", self.hir_id_to_string(id)),
        }
    }

    pub fn hir_opt_delegation_sig_id(self, def_id: LocalDefId) -> Option<DefId> {
        self.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_sig_id()
    }

    pub fn hir_opt_delegation_info(self, def_id: LocalDefId) -> Option<&'tcx DelegationInfo> {
        self.opt_hir_owner_node(def_id)?.fn_decl()?.opt_delegation_info()
    }

    pub fn hir_delegation_info(self, delegation_id: LocalDefId) -> &'tcx DelegationInfo {
        self.hir_opt_delegation_info(delegation_id).expect("processing delegation")
    }

    #[inline]
    fn hir_opt_ident(self, id: HirId) -> Option<Ident> {
        match self.hir_node(id) {
            Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
            // A `Ctor` doesn't have an identifier itself, but its parent
            // struct/variant does. Compare with `hir::Map::span`.
            Node::Ctor(..) => match self.parent_hir_node(id) {
                Node::Item(item) => Some(item.kind.ident().unwrap()),
                Node::Variant(variant) => Some(variant.ident),
                _ => unreachable!(),
            },
            node => node.ident(),
        }
    }

    #[inline]

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Use hir_opt_delegation_info(def_id) instead and handle the None case before processing.
  2. If reached during normal compilation, report as an ICE; ensure the def_id actually corresponds to a delegation item.
  3. Check the nightly version — the delegation feature is unstable and its HIR representation changes between versions.

Example fix

// before
let info = tcx.hir_delegation_info(def_id);

// after
if let Some(info) = tcx.hir_opt_delegation_info(def_id) {
    // process delegation
}
Defensive patterns

Strategy: try-catch

Validate before calling

// "processing delegation" is an internal HIR-map panic with no
// caller-controllable precondition. No meaningful pre-call check.
// Guard by catching the panic in tool code.

Try / catch

// Tool authors: wrap HIR traversal that may hit this internal
// panic in catch_unwind and degrade gracefully.
use std::panic::{catch_unwind, AssertUnwindSafe};

let visited = catch_unwind(AssertUnwindSafe(|| {
    tcx.hir().walk_map(|node| process_node(tcx, node))
}));
match visited {
    Ok(value) => { let _ = value; }
    Err(_) => {
        eprintln!("skipped delegation processing due to internal HIR-map panic");
        // fall back to a shallow walk that avoids the delegation path
    }
}

Prevention

When it happens

Trigger: Calling tcx.hir_delegation_info(def_id) on a LocalDefId that is not a `reuse`/delegated fn (e.g. a regular fn, a non-fn item, or a foreign item). The DelegationInfo is only populated for items declared via the `pub reuse path::method;` delegation syntax.

Common situations: Compiler passes that assume every fn is a delegation when iterating; user code or macros triggering the delegation code path on a non-delegation def_id; mismatches during nightly upgrades as the `delegate` feature evolves.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/10bed4a573810103.json. Report an issue: GitHub.