cxx
cxx copied to clipboard
Multiple mods in the same file creating a type alias for the same type raises "the name `...` is defined multiple times" error
In Types::collect()
, the cxx crate checks for duplicate definitions of Rust identifiers.
This works for the proc macro (which is run per mod
) but causes issues for the build script as it operates on a file level, gathering all APIs across all mod
s in the file. Thus, if the same type alias is declared in multiple mod
s in the same file then the build script will raise an error despite there being no issue with being able to generate the final C++ code.
Example
For :
pub struct MyStruct {
pub val: u32,
}
unsafe impl cxx::ExternType for MyStruct {
type Id = cxx::type_id!("handle::ffi::MyStruct");
type Kind = cxx::kind::Opaque;
}
#[cxx::bridge]
mod ffi1 {
extern "C++" {
type MyStruct = crate::MyStruct;
}
}
#[cxx::bridge]
mod ffi2 {
extern "C++" {
type MyStruct = crate::MyStruct;
}
}
Building this will cause an error to be raised
error[cxxbridge]: the name `MyStruct` is defined multiple times
┌─ src/lib.rs:20:9
│
20 │ type MyStruct = crate::MyStruct;
│ ^^^^^^^^^^^^^ the name `MyStruct` is defined multiple times
Why do you need this?
APIs in an extern "C++"
block may only reference types that are built-in to cxx
and other types in the same mod
, thus it is pretty reasonable to need to access the same type via an alias across multiple mod
s in the same file.
Possible fixes
The simplest fix would be to disable checking when calling Types::collect
from the build script - but this would drop other checks that may still be valuable.
I believe the correct fix is to use a different set of checking logic instead - the current logic is only looking at Rust names and so isn't validating that the C++ names being emitted are not duplicated. Types::collect
should add a parameter to indicate if the Rust or C++ names should be checked, and then perform the appropriate checks.