rust-lang / rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
https://rust-lang.github.io/rust-bindgen/
BSD 3-Clause "New" or "Revised" License
4.4k stars 691 forks source link

Inappropriate generated type for function-returning-function #2713

Open cole-miller opened 9 months ago

cole-miller commented 9 months ago

Input C/C++ Header

void (*(*xDlSym)(const char *))(void);

Bindgen Invocation

$ bindgen input.h

Actual Results

/* automatically generated by rust-bindgen 0.69.1 */

extern "C" {
    pub static mut xDlSym: ::std::option::Option<
        unsafe extern "C" fn(
            arg3: *const ::std::os::raw::c_char,
        ) -> ::std::option::Option<
            unsafe extern "C" fn(
                arg3: *const ::std::os::raw::c_char,
            ),
        >,
    >;
}

Expected Results

extern "C" {
    pub static mut xDlSym: ::std::option::Option<
        unsafe extern "C" fn(
            arg3: *const ::std::os::raw::c_char,
        ) -> ::std::option::Option<
            unsafe extern "C" fn(
-               arg3: *const ::std::os::raw::c_char,
            ),
        >,
    >;
}

The original C signature is hard to read: it describes a function pointer xDlSym that takes a single const char * argument and returns another function pointer of type void (*)(void). But in the bindgen-generated output, the returned function pointer has the inappropriate type void (*)(const char *) instead.

This affects the public API of libsqlite3-sys here; the reproducer is minimized from that situation.

emilio commented 8 months ago

Interesting. We're reading stuff from libclang, but IIRC there were some quirks with how we get the right function type.