rust-lang/rust · error
func
Error message
func
What it means
`const_undef` (and `const_poison`, which delegates to it) in `common.rs:212` calls `self.current_func.borrow().expect("func")`. The `current_func` field is a `RefCell<Option<Function>>` (context.rs:38) initialized to `None` and only populated when a basic block is built (builder.rs:519: `*cx.current_func.borrow_mut() = Some(block.get_function())`). The panic fires when an undef/poison constant is materialized before any function is active on the codegen context. rustc_codegen_gcc uses this to lower LLVM-style `undef`/`poison` values by emitting a GCC local in the current function, so it fundamentally requires a live function.
Source
Thrown at compiler/rustc_codegen_gcc/src/common.rs:212
.iter()
.map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32))
.collect();
context.new_array_constructor(None, typ, &elements)
}
}
}
pub fn type_is_pointer(typ: Type<'_>) -> bool {
typ.get_pointee().is_some()
}
impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> {
if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
}
fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> {
let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined");
local.to_rvalue()
}
fn const_poison(&self, typ: Type<'gcc>) -> RValue<'gcc> {
// No distinction between undef and poison.
self.const_undef(typ)
}
fn const_bool(&self, val: bool) -> RValue<'gcc> {
self.const_uint(self.type_i1(), val as u64)
}
fn const_i8(&self, i: i8) -> RValue<'gcc> {
self.const_int(self.type_i8(), i as i64)
}
fn const_i16(&self, i: i16) -> RValue<'gcc> {
self.const_int(self.type_i16(), i as i64)View on GitHub (pinned to 22057b88b0)
Solutions
- Confirm the panic stack shows a call into `const_undef`/`const_poison` from a non-function codegen path; if so the codegen driver must guarantee `current_func` is set (via `set_block`) before lowering such constants.
- If you control the call site, defer the undef/poison materialization until inside a function body, or model undef without a GCC local (e.g. a zero value) until a function is available.
- Upgrade/downgrade rustc_codegen_gcc to match the rustc version whose MIR/const lowering is compatible; mismatches are a frequent cause of unexpected undef emission.
- File or check an upstream issue in rustc_codegen_gcc: undef-at-module-scope is an LLVM-ism that has no direct GCC-jit equivalent and may need an alternate lowering.
Example fix
// before
fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> {
let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined");
local.to_rvalue()
}
// after (fall back to a zero value when no function is active; undef semantics are best-effort anyway)
fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> {
match self.current_func.borrow().as_ref() {
Some(func) => func.new_local(None, typ, "undefined").to_rvalue(),
None => self.const_null(typ),
}
} Defensive patterns
Strategy: validation
Validate before calling
// common.rs:212 -> .expect("func") on self.current_func.borrow().
// const_undef/const_poison need an active function; panic fires when none is set.
// Validate before lowering any const that needs undef/poison:
if cx.current_func.borrow().is_none() {
// push a function frame first, or skip const_undef entirely
return Err("cannot lower const_undef: no current function in CodegenCx");
} Prevention
- ConstCodegenMethods.const_undef/const_poison dereference current_func; always set a current function on the CodegenCx before lowering such constants.
- When driving CodegenCx by hand, never call const_undef outside an active function frame.
- If you only need a zero value, prefer const_int/const_null over const_undef to avoid the func-local path entirely.
When it happens
Trigger: Calling `const_undef`/`const_poison` from a path that runs before `set_block`/block construction sets `current_func`, or after the function context has been cleared. Concretely: codegen of a constant with undef scalar bytes outside a function body, or any ConstCodegenMethods call driven from a module-level (non-function) context. The panic is `Option::expect` on `current_func` being `Some`.
Common situations: Hitting this during codegen of a crate that exercises an undef/poison value path the backend did not expect (e.g. new rustc version emits undef where old one did not); running the backend with a partial/broken function-builder wiring; regressions after refactors that moved `const_undef` emission out of a function scope. It is a backend-internal invariant failure, not a user-code error.
Related errors
- struct type
- Can't get the layout of `i128`
- cannot allocate registers
- first index in inbounds_gep
- Called extract_element on a non-vector type
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/331a81fb2a7fd569.json.
Report an issue: GitHub.