mozilla / cbindgen

A project for generating C bindings from Rust code
Mozilla Public License 2.0
2.27k stars 294 forks source link

Support generics with defaulted args #959

Closed scovich closed 1 month ago

scovich commented 1 month ago

Rust allows generics with defaulted arguments, such as:

#[repr(transparent)]
pub struct Foo<T, P = c_void> {
    field: T,
    _phantom: std::marker::PhantomData<P>,
}

However, any usage that actually relies on such default(s) can trigger assertion failures, e.g.

#[repr(C)]
pub struct Bar<T> {
    f: Foo<T>,
}

or

pub type Baz<T> = Foo<T>;

Fails with

cbindgen failed: None with error: thread 'main' panicked at src/bindgen/ir/generic_path.rs:85:9:
Foo has 2 params but is being instantiated with 1 values
stack backtrace:
   0: rust_begin_unwind
             at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/c987ad527540e8f1565f57c31204bde33f63df76/library/core/src/panicking.rs:72:14
   2: cbindgen::bindgen::ir::generic_path::GenericParams::call
             at ./src/bindgen/ir/generic_path.rs:85:9
   3: <cbindgen::bindgen::ir::structure::Struct as cbindgen::bindgen::ir::item::Item>::instantiate_monomorph
             at ./src/bindgen/ir/structure.rs:372:24
   4: cbindgen::bindgen::ir::ty::Type::add_monomorphs
             at ./src/bindgen/ir/ty.rs:868:25
   5: cbindgen::bindgen::ir::function::Function::add_monomorphs
             at ./src/bindgen/ir/function.rs:128:13
   6: cbindgen::bindgen::library::Library::instantiate_monomorphs
             at ./src/bindgen/library.rs:410:13
   7: cbindgen::bindgen::library::Library::generate
             at ./src/bindgen/library.rs:73:13

This PR fixes the problem by capturing generic parameter default values at parse time, and using them to "pad" the list of generic arguments if the latter is too short.