rust-lang/rust · error
function ptr
Error message
function ptr
What it means
Thrown by rustc_codegen_gcc inside check_ptr_call(), which validates and bitcasts the arguments of an indirect (function-pointer) call. The backend calls func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr") to recover the function's parameter/return types; if libgccjit reports the value's type as something other than a function-pointer type (returns None), the expect panics. It indicates the GCC type system lost or never attached function-pointer type information to the callee value.
Source
Thrown at compiler/rustc_codegen_gcc/src/builder.rs:221
}
})
.collect();
debug_assert_eq!(casted_args.len(), args.len());
Cow::Owned(casted_args)
}
fn check_ptr_call<'b>(
&mut self,
_typ: &str,
func_ptr: RValue<'gcc>,
args: &'b [RValue<'gcc>],
on_stack_param_indices: &FxHashSet<usize>,
) -> Cow<'b, [RValue<'gcc>]> {
let mut all_args_match = true;
let mut param_types = vec![];
let gcc_func = func_ptr.get_type().dyncast_function_ptr_type().expect("function ptr");
for (index, arg) in args.iter().enumerate().take(gcc_func.get_param_count()) {
let param = gcc_func.get_param_type(index);
if param != arg.get_type() {
all_args_match = false;
}
param_types.push(param);
}
if all_args_match {
return Cow::Borrowed(args);
}
let func_name = format!("{:?}", func_ptr);
let mut casted_args: Vec<_> = param_types
.into_iter()
.zip(args.iter())
.enumerate()View on GitHub (pinned to 22057b88b0)
Solutions
- Update (or pin to a known-good) libgccjit matching the rustc_codegen_gcc version - opaque-pointer support changed across gcc 13/14.
- Ensure the callee is constructed/cast as an explicit function-pointer type before the call rather than through an integer or generic pointer.
- Switch to the LLVM backend for the affected crate while the gccjit issue is reproduced.
- Report the failing intrinsic/call signature to rustc_codegen_gcc with a minimal reproducer so check_ptr_call can handle the type gracefully instead of expect-ing.
Example fix
// before - integer cast to fn pointer confuses dyncast
let f: extern "C" fn(u32) -> u32 = unsafe { std::mem::transmute(0xdeadbeefusize) };
f(1);
// after - obtain a real function pointer from a defined extern item
extern "C" { fn real_fn(x: u32) -> u32; }
unsafe { real_fn(1) } Defensive patterns
Strategy: type-guard
Validate before calling
// Avoid calling-pattern code that requires cg_gcc to materialize a raw
// function pointer via bitcast from an integer/non-pointer type.
// e.g. `let f: fn() = unsafe { std::mem::transmute(0usize) };`
// Audit for int->fn-ptr transmutes before building with cg_gcc.
let re = regex::Regex::new(r"transmute::<(?:usize|u\d+|i\d+),\s*fn").unwrap();
if re.is_match(&src) { eprintln!("cg_gcc cannot build function ptr from int; refactor."); } Type guard
// Rust: keep function references as real `fn` types, never as usize.
fn is_real_fn_pointer<T>(_v: &T) -> bool { false }
fn is_real_fn_pointer(_v: &dyn Fn()) -> bool { true }
// Better: encode it in the type system so transmute is unnecessary.
trait FnPtr: Sized { fn as_ptr(self) -> Self { self } }
impl FnPtr for fn() {} Try / catch
// Compile-time panic in cg_gcc; not catchable at runtime. // Switch crate to LLVM backend, or refactor the offending fn-ptr construction.
Prevention
- Never transmute integers to `fn(...)` types; store and pass real `fn` / `unsafe extern "C" fn` types.
- Avoid `as` casts from `usize` to function pointers under cg_gcc.
- Use pointer-to-pointer transmute (`*mut c_void` -> `unsafe extern "C" fn(...)`), the supported path.
When it happens
Trigger: Calling through a value that the gccjit backend does not recognise as a function pointer: an opaque pointer cast to fn(...), an integer reinterpreted as a function pointer, a libgccjit intrinsic whose argument list has an unusual signature, or a value that was bitcast through a non-function type before the call. The panic occurs in check_ptr_call, which runs for every function_ptr_call after argument adjustment.
Common situations: libgccjit version mismatch where opaque-pointer handling changed how dyncast_function_ptr_type behaves; calling intrinsics or raw addresses cast to fn pointers; older gccjit builds that don't tag casted pointers with function-pointer type info. Most frequent after a gcc/libgccjit upgrade.
Related errors
- pointee type
- not implemented
- first index in inbounds_gep
- not implemented
- internal error: entered unreachable code
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/8c5410e304299e69.json.
Report an issue: GitHub.