cbindgen panics during monomorphization if two distinct #[repr(C)] enums declare a data-bearing variant with the same name (e.g. both have an Ok(T) variant) and both get monomorphized over the same concrete type.
The payload struct that cbindgen synthesizes for each enum variant is named solely after the variant identifier, independent of the enclosing enum:
let path = Path::new(format!("{}_Body", variant.ident));
(src/bindgen/ir/enumeration.rs)
So EnumA<T>::Ok and EnumB<T>::Ok both produce a payload path Ok_Body, and instantiating both with the same T tries to register Ok_Body<T> twice, triggering the debug_assert!(!self.contains(&replacement_path)) in src/bindgen/monomorph.rs.
It seems cbindgen:prefix-with-name=true config also doesn't help because it applies later, and does not affect the path used during monomorph.rs
Minimial Repro
use std::os::raw::c_void;
#[repr(C)]
pub enum ResultA<T> {
Ok(T),
Err(*mut c_void),
}
// Same `Ok`/`Err` variant *names* as ResultA.
#[repr(C)]
pub enum ResultB<T> {
Ok(T),
Err(*mut c_void),
}
#[repr(C)]
pub struct Payload {
pub x: i32,
}
// Force both enums to be monomorphized over the SAME type.
#[no_mangle]
pub extern "C" fn use_a(_a: ResultA<Payload>) {}
#[no_mangle]
pub extern "C" fn use_b(_b: ResultB<Payload>) {}
cbindgen panics during monomorphization if two distinct
#[repr(C)]enums declare a data-bearing variant with the same name (e.g. both have an Ok(T) variant) and both get monomorphized over the same concrete type.The payload struct that cbindgen synthesizes for each enum variant is named solely after the variant identifier, independent of the enclosing enum:
(src/bindgen/ir/enumeration.rs)
So
EnumA<T>::OkandEnumB<T>::Okboth produce a payload pathOk_Body, and instantiating both with the sameTtries to registerOk_Body<T>twice, triggering thedebug_assert!(!self.contains(&replacement_path))in src/bindgen/monomorph.rs.It seems
cbindgen:prefix-with-name=trueconfig also doesn't help because it applies later, and does not affect the path used duringmonomorph.rsMinimial Repro