Skip to content

type is redefined #2571

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

Open
alexcwyu opened this issue Jun 30, 2023 · 2 comments
Open

type is redefined #2571

alexcwyu opened this issue Jun 30, 2023 · 2 comments

Comments

@alexcwyu
Copy link

alexcwyu commented Jun 30, 2023

Input C/C++ Header

Header

#include "AeronArchive.h"

the actual header can be found here
https://github.com/real-logic/aeron/blob/1.41.4/aeron-archive/src/main/cpp/client/AeronArchive.h

Bindgen Invocation

bindgen code

    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=bindings.h");

    let aeron_path = canonicalize(Path::new("./aeron")).unwrap();
    let header_path = aeron_path.join("aeron-archive/src/main/cpp/client");
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());

    let cmake_output = Config::new(&aeron_path)
        .build();

    let base_lib_dir = cmake_output.join("build");
    println!(
        "cargo:rustc-link-search=native={}",
        base_lib_dir.join("lib").display()
    );
    // Because the `cmake_output` path is different for debug/release, we're not worried
    // about accidentally linking the Debug library when this is a release build or vice-versa
    println!(
        "cargo:rustc-link-search=native={}",
        base_lib_dir.join("lib/Debug").display()
    );
    println!(
        "cargo:rustc-link-search=native={}",
        base_lib_dir.join("binaries/Debug").display()
    );
    println!(
        "cargo:rustc-link-search=native={}",
        base_lib_dir.join("lib/Release").display()
    );
    println!(
        "cargo:rustc-link-search=native={}",
        base_lib_dir.join("binaries/Release").display()
    );

    println!("cargo:rustc-link-lib=static=aeron_archive_client");
    println!("cargo:rustc-link-lib=static=aeron_archive_client_wrapper");
    println!("cargo:rustc-link-lib=stdc++");

    println!("cargo:include={}", header_path.display());
    let bindings = bindgen::Builder::default()
        .clang_arg(format!("-I{}", header_path.display()))
        .clang_arg(format!(
            "-I{}",
            aeron_path.join("aeron-client/src/main/c").display()
        ))
        .header("bindings.h")
        .enable_cxx_namespaces()
        // enable C++
        .clang_args(&["-x", "c++", "--std=c++14"])
        .opaque_type("std::.*")
        .constified_enum_module("aeron_.*_enum")
        .derive_debug(false)
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()
        .expect("Unable to generate aeron bindings");

    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");

Actual Results

error

error[E0428]: the name `this_t` is defined multiple times
     --> /home/alex/workspaces/personal/aeron-lib/target/debug/build/libaeron_archive-sys-0a7352ee9f461a4a/out/bindings.rs:10595:5
      |
10115 |     pub type this_t = root::aeron::concurrent::logbuffer::BufferClaim;
      |     ------------------------------------------------------------------ previous definition of the type `this_t` here
...
10595 |     pub type this_t = root::aeron::ChannelUri;
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `this_t` redefined here
      |
      = note: `this_t` must be defined only once in the type namespace of this module

error[E0428]: the name `this_t` is defined multiple times
     --> /home/alex/workspaces/personal/aeron-lib/target/debug/build/libaeron_archive-sys-0a7352ee9f461a4a/out/bindings.rs:10597:5
      |
10115 |     pub type this_t = root::aeron::concurrent::logbuffer::BufferClaim;
      |     ------------------------------------------------------------------ previous definition of the type `this_t` here
...
10597 |     pub type this_t = root::aeron::archive::client::Context;
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `this_t` redefined here
      |
      = note: `this_t` must be defined only once in the type namespace of this module

error[E0428]: the name `this_t` is defined multiple times
     --> /home/alex/workspaces/personal/aeron-lib/target/debug/build/libaeron_archive-sys-0a7352ee9f461a4a/out/bindings.rs:10598:5
      |
10115 |     pub type this_t = root::aeron::concurrent::logbuffer::BufferClaim;
      |     ------------------------------------------------------------------ previous definition of the type `this_t` here
...
10598 |     pub type this_t = root::aeron::BufferBuilder;
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `this_t` redefined here
      |
      = note: `this_t` must be defined only once in the type namespace of this module

generated file

// skip other line....
    pub type this_t = root::aeron::ChannelUri;
    pub type this_t = root::aeron::archive::client::Context;
    pub type this_t = root::aeron::BufferBuilder;
}

Expected Results

no redefined type

@pvdrz
Copy link
Contributor

pvdrz commented Jul 24, 2023

This sounds like another of those C++ template issues where we don't have a straight solution and it is mostly caused by how libclang exposes the information of the templates. There's not much we can do about how clang exposes this and using other tools like libtooling is not viable due to distribution issues.

@boydjohnson
Copy link

I wanted to get creduced test cases even if there might not be a solution soon.

Here is the preprocessed header output.
__bindgen.hpp.gz

I grepped for 3 things in the interestingness tests for creduce when running rustc --test on the bindings

  • previous definition of the type
  • erroneous constant encountered
  • cycle detected when expanding type alias

test-case1.hpp

typedef long a;
template <typename = int> class b {
  typedef int bu;
  typedef b bv;
  bv &bw(bu *, a, bu);
};
template <> b<> &b<>::bw(bu *, a, bu);
template <> b<wchar_t> &b<wchar_t>::bw(bu *, a, bu);

test-case1.rs

/* automatically generated by rust-bindgen 0.69.4 */

pub type a = ::std::os::raw::c_long;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct b {
    pub _address: u8,
}
pub type b_bu = ::std::os::raw::c_int;
pub type b_bv = b;
pub type bu = ::std::os::raw::c_int;
pub type bu = ::std::os::raw::c_int;

test-case2.hpp

template <typename, typename a> class d { a ay; };
template <typename, typename, typename, typename b> using bf = d<b, int>;
template <typename b> class e { bf<int, int, int, b> bh; };
e<int> c;

test-case2.rs

/* automatically generated by rust-bindgen 0.69.4 */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct d<a> {
    pub ay: a,
    pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<a>>,
}
pub type bf = d<a>;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct e {
    pub bh: bf,
}
#[test]
fn __bindgen_test_layout_e_open0_int_close0_instantiation() {
    assert_eq!(
        ::std::mem::size_of::<e>(),
        4usize,
        concat!("Size of template specialization: ", stringify!(e))
    );
    assert_eq!(
        ::std::mem::align_of::<e>(),
        4usize,
        concat!("Alignment of template specialization: ", stringify!(e))
    );
}
extern "C" {
    pub static mut c: e;
}

test-case3.hpp

typedef struct a b;
template <typename, typename = a> class bk;
template <typename> struct c { typedef int bm; };
struct a : c<int> {};
template <typename, typename bu> class bk {
  typedef typename bu::bm bm;
  typedef bk by;
  by &ca(b, bm);
};
template <> bk<wchar_t> &bk<wchar_t>::ca(b, bm);

test-case3.rs

pub struct c {
    pub _address: u8,
}
pub type c_bm = ::std::os::raw::c_int;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct a {
    pub _address: u8,
}
#[test]
fn bindgen_test_layout_a() {
    assert_eq!(
        ::std::mem::size_of::<a>(),
        1usize,
        concat!("Size of: ", stringify!(a))
    );
    assert_eq!(
        ::std::mem::align_of::<a>(),
        1usize,
        concat!("Alignment of ", stringify!(a))
    );
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct bk {
    pub _address: u8,
}
pub type bk_bm = [u8; 0usize];
pub type bk_by = bk;
#[test]
fn __bindgen_test_layout_c_open0_int_close0_instantiation() {
    assert_eq!(
        ::std::mem::size_of::<c>(),
        1usize,
        concat!("Size of template specialization: ", stringify!(c))
    );
    assert_eq!(
        ::std::mem::align_of::<c>(),
        1usize,
        concat!("Alignment of template specialization: ", stringify!(c))
    );
}
pub type bm = bm;
pub type bm = ::std::os::raw::c_int;

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

3 participants