rust-lang/rust · critical
shouldn't exist here
Error message
shouldn't exist here
What it means
Panic in block lowering when a statement of kind StmtKind::MacCall is encountered. After macro expansion completes, statements must be fully expanded — no StmtKind::MacCall should survive into AST lowering. Reaching this panic means lowering was invoked on an un-expanded AST, a violation of the expansion-then-lowering pipeline invariant.
Source
Thrown at compiler/rustc_ast_lowering/src/block.rs:74
expr = Some(e);
} else {
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
let kind = hir::StmtKind::Expr(e);
let span = self.lower_span(s.span);
stmts.push(hir::Stmt { hir_id, kind, span });
}
}
StmtKind::Semi(e) => {
let e = self.lower_expr(e);
let hir_id = self.lower_node_id(s.id);
self.alias_attrs(hir_id, e.hir_id);
let kind = hir::StmtKind::Semi(e);
let span = self.lower_span(s.span);
stmts.push(hir::Stmt { hir_id, kind, span });
}
StmtKind::Empty => {}
StmtKind::MacCall(..) => panic!("shouldn't exist here"),
}
ast_stmts = tail;
}
(self.arena.alloc_from_iter(stmts), expr)
}
/// Return an `ImplTraitContext` that allows impl trait in bindings if
/// the feature gate is enabled, or issues a feature error if it is not.
fn impl_trait_in_bindings_ctxt(&self, position: ImplTraitPosition) -> ImplTraitContext {
if self.tcx.features().impl_trait_in_bindings() {
ImplTraitContext::InBinding
} else {
ImplTraitContext::FeatureGated(position, sym::impl_trait_in_bindings)
}
}
fn lower_local(&mut self, l: &Local) -> &'hir hir::LetStmt<'hir> {
// Let statements are allowed to have impl trait in bindings.View on GitHub (pinned to 22057b88b0)
Solutions
- Report the ICE to rust-lang/rust with the source and rustc version.
- If invoking rustc internals directly, ensure the expansion pass runs before ast_lowering.
- Bisect nightlies to find the regression commit in the expansion/lowering pipeline.
- Minimize the macro usage that triggers the unexpanded statement reaching lowering.
Defensive patterns
Strategy: validation
Validate before calling
// block.rs lowers StmtKind::MacCall only BEFORE macro expansion; reaching
// lowering with a MacCall statement means expansion was incomplete.
// Validate that no statement in the block is still a MacCall:
fn fully_expanded(block: &ast::Block) -> bool {
block.stmts.iter().all(|s| !matches!(s.kind, ast::StmtKind::MacCall(_)))
}
if !fully_expanded(&block) {
return Err("block contains an unexpanded macro call; run expansion to fixed point first");
} Type guard
fn is_lowerable_stmt(s: &ast::Stmt) -> bool {
!matches!(s.kind, ast::StmtKind::MacCall(_))
} Try / catch
let lowered = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| lower_block(&block)));
match lowered {
Ok(hir_block) => hir_block,
Err(_) => return Err("block lowering panicked: macro call statement survived into lowering"),
} Prevention
- If you drive expansion manually (proc-macro server, rust-analyzer), run macro expansion to a true fixed point before invoking AST lowering — a leftover MacCall is a symptom of an early-exit in expansion.
- Never splice a raw macro call expression into a statement position and bypass the expander; expand it to its output first.
- In generated AST, prefer emitting the already-expanded statement form rather than a MacCall node that the compiler must expand.
- Check for `StmtKind::MacCall` presence as a post-expansion sanity assertion in any pipeline that feeds rustc_ast_lowering.
When it happens
Trigger: Triggered when lower_block (or related lowering entry points) is called on a crate/block that has not been through macro expansion — e.g. a direct invocation of the AST-lowering pass on raw parsed AST, a compiler refactor that skips expansion, or a proc-macro/tool that feeds unexpanded stmts into lowering. Also seen after nightly regressions in the expansion driver.
Common situations: Nightly rustc regressions in macro expansion; compiler-internals tooling that bypasses the expansion phase; fuzzers exercising lowering directly. Ordinary user code with macro invocations is expanded first and never reaches this path.
Related errors
- {:?} shouldn't exist here
- must contain self type as `SelfTy` propagation kind is speci
- arg must exist for infer
- non-`async`/`gen` closure body turned `async`/`gen` during l
- already handled
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/adaec2f6238acefe.json.
Report an issue: GitHub.