Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__IncompleteArrayField does not impl ::std::marker::Copy #2791

Closed
VariableExp0rt opened this issue Mar 26, 2024 · 2 comments
Closed

__IncompleteArrayField does not impl ::std::marker::Copy #2791

VariableExp0rt opened this issue Mar 26, 2024 · 2 comments

Comments

@VariableExp0rt
Copy link

VariableExp0rt commented Mar 26, 2024

Input C/C++ Header

/*
 * IO completion data structure (Completion Queue Entry)
 */
struct io_uring_cqe {
	__u64	user_data;	/* sqe->data submission passed back */
	__s32	res;		/* result code for this event */
	__u32	flags;

	/*
	 * If the ring is initialized with IORING_SETUP_CQE32, then this field
	 * contains 16-bytes of padding, doubling the size of the CQE.
	 */
	__u64 big_cqe[];
};

Bindgen Invocation

bindgen::Builder::default()
        .header("wrapper.h")
        .allowlist_type("(io_uring_(sqe|cqe)|io_(sq|cq)ring_offsets|io_uring_params)")
        .blocklist_type("__(u8|u16|s32|u32|u64|kernel_rwf_t).*")
        .derive_debug(true)
        .derive_copy(true)
        .formatter(bindgen::Formatter::Rustfmt)
        .impl_debug(true)
        .layout_tests(false)
        .parse_callbacks(Box::new(CallBack))
        .generate()
        .expect("Unable to generate bindings");

Actual Results

/* automatically generated by rust-bindgen 0.69.4 */

#[repr(C)]
#[derive(Default)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
    #[inline]
    pub const fn new() -> Self {
        __IncompleteArrayField(::std::marker::PhantomData, [])
    }
    #[inline]
    pub fn as_ptr(&self) -> *const T {
        self as *const _ as *const T
    }
    #[inline]
    pub fn as_mut_ptr(&mut self) -> *mut T {
        self as *mut _ as *mut T
    }
    #[inline]
    pub unsafe fn as_slice(&self, len: usize) -> &[T] {
        ::std::slice::from_raw_parts(self.as_ptr(), len)
    }
    #[inline]
    pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
        ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
    }
}
impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        fmt.write_str("__IncompleteArrayField")
    }
}

Expected Results

::std::marker::Copy is implemented for __IncompleteArrayField<__u64>

It seems that a few of the other examples I can find related to this field imply that it can be Copy, but perhaps I am missing some constraints about why it's omitted here (I am new to bindgen and Rust). Should I be doing this manually because PhantomData<T> cannot be sure that T is actually Copy? For instance the below works but I'm unsure it's "sound":

impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
    #[inline]
    fn clone(&self) -> Self {
        Self::new()
    }
}
impl<T: std::marker::Copy> ::std::marker::Copy for __IncompleteArrayField<T> {}

I should also mention I'm using blocklisted_item_implements_trait in ParseCallback to get the behaviour I need too (so that the io_uring types can implement the necessary traits).

Thanks!

@emilio
Copy link
Contributor

emilio commented Apr 1, 2024

That's intended, since we don't know how much memory we'd need to copy?

@emilio
Copy link
Contributor

emilio commented Apr 1, 2024

In general trailing incomplete array members are used to implement dynamically sized data. That can't implement Copy in rust, because it can't be allocated on the stack (easily at least), and bindgen doesn't know the length of the array per se.

Closing because I don't think generating Copy there is reasonable, but lmk if I'm missing something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants