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

Multiple mods in the same file creating a type alias for the same type raises "the name ... is defined multiple times" error #1279

Open
dpaoliello opened this issue Oct 25, 2023 · 0 comments

Comments

@dpaoliello
Copy link

dpaoliello commented Oct 25, 2023

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 mods in the file. Thus, if the same type alias is declared in multiple mods 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 mods 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.

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

1 participant