mozilla / cbindgen

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

'FfiPoll_u32_Tag' is going to be declared twice #913

Open svok opened 6 months ago

svok commented 6 months ago

I'm trying to generate header file for a test with async-ffi crate and getting such a result:

enum FfiPoll_u32_Tag {
  Ready_u32,
  Pending_u32,
  Panicked_u32,
};
typedef uint8_t FfiPoll_u32_Tag;

typedef struct FfiPoll_u32 {
  FfiPoll_u32_Tag tag;
  union {
    struct {
      uint32_t ready;
    };
  };
} FfiPoll_u32;

With this file I get an error: "'FfiPoll_u32_Tag' is going to be declared twice". As far as I understand, this is due to the name of the FfiPoll_u32 struct field "tag" is converted to the same name as the enum. I tried different renaming configurations and they didn't help me.

The test application code:

use std::time::Duration;
use async_ffi::{FfiFuture, FutureExt};
use tokio::time::sleep;

#[no_mangle]
pub extern "C" fn work(arg: u32) -> FfiFuture<u32> {
    async move {
        let ret = do_some_io(arg).await;
        do_some_sleep(42).await;
        ret
    }
    .into_ffi()
}

async fn do_some_io(arg: u32) -> u32 {
    println!("res {arg}");
    arg + 2
}

async fn do_some_sleep(secs: u32) {
    let _ = sleep(Duration::from_secs(secs.into()));
}

And the cbindgen.toml file

language = "C"
braces = "SameLine"
style = "both"

[parse]
parse_deps = true
include = [
    "src/lib.rs", 
    "async-ffi"
]

exclude = [
    "libc",
]
clean = true
extra_bindings = []

Other information:

rustc 1.77.0-nightly (e51e98dde 2023-12-31)
cbindgen = "0.26"
OS: ubuntu 20.04
svok commented 5 months ago

So, I was a bit wrong. That was just an error in enum generation. Any enum is converted into such a structure:

enum FfiPoll_u32_Tag {
  Ready_u32,
  Pending_u32,
  Panicked_u32,
};
typedef uint8_t FfiPoll_u32_Tag;

And it is not working for c compiler.

  1. uint8_t - where is it from?
  2. for structs there is such a setting style = "tag" that manages style of generation. But it is not applied to enums, while it should to be as I see.