Skip to content

Bindgen sometimes drops the type parameter of a struct for fields with multiple type parameters #3214

Open
@jku20

Description

@jku20

Header File

Here is an example header, though there are a lot of others which exhibit similar behavior (briefly mentioned in the discussion).

template <typename T, typename K = bool> struct Inner {
  T foo;
  K bar;
};

template <typename T> struct Outer {
  Inner<T> inner;
};

Expected Result

Something along the lines of:

/* automatically generated by rust-bindgen 0.71.1 */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Inner<T, K = bool> {
    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
    pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell<K>>,
    pub foo: T,
    pub bar: K,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Outer<T> {
    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
    pub inner: Inner<T>,
}

Actual Translation

When running bindgen lib.hpp -o bindings.rs (with lib.hpp containing the cpp code above), bindgen writes the following to bindings.rs:

/* automatically generated by rust-bindgen 0.71.1 */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Inner<T, K> {
    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
    pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell<K>>,
    pub foo: T,
    pub bar: K,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Outer {
    pub inner: Inner<T, K>,
}

The log is attached here.

Discussion

The problem seems to be in the translating Outer's field. Removing the default type of K (the = bool) and instead instantiating it in the field as Inner<T, bool> inner exhibits the same problem.

Interestingly, changing the field to be Inner<T, T> inner lets the Rust generate fine, creating

// Definition of Inner omitted for brevity
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Outer<T> {
    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
    pub inner: Inner<T, T>,
}

This leads me to believe the problem isn't to do with the default type parameter, but instead some more general problem when dealing with templates with multiple type parameters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions