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

  1. Update (or pin to a known-good) libgccjit matching the rustc_codegen_gcc version - opaque-pointer support changed across gcc 13/14.
  2. Ensure the callee is constructed/cast as an explicit function-pointer type before the call rather than through an integer or generic pointer.
  3. Switch to the LLVM backend for the affected crate while the gccjit issue is reproduced.
  4. 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

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


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