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

Issue using only a few types from a uniffi dependency in a uniffi library #2282

Open
thunderbiscuit opened this issue Oct 22, 2024 · 3 comments

Comments

@thunderbiscuit
Copy link

Hi there. I maintain a uniffi-based library which we have recently broken into two (I'll call them main and low-level-types). Our main library imports some of the types defined in this lower-level library we maintain to offer those lower-level types to other libraries that use uniffi.

I recently found an issue where types defined in my main library that are also defined in the lowe-level-types dependency name clash in Swift because Swift imports all types at once. This lead me to look into the glue code generated for the lower-level dependency, and notice that all types in that library are added to the glue code even though our library only imports some of them.

I'm wondering if I am maybe not configuring the dependency correctly, or if there is something I misunderstood.

Here is an example udl from the lower-level-types library:

interface Script {
  constructor(sequence<u8> raw_output_script); 
  sequence<u8> to_bytes();
};

dictionary OutPoint {
  Txid txid;
  u32 vout;
};

And our use of the Script type in the main library:

[ExternalInterface="core_types_ffi"]
typedef extern Script;

Again our issue is that the OutPoint type will appear in the glue code for the lower-level-types even though we do not need it there. Moreover, because we do have an OutPoint type in the main library, the two Outpoints will clash and runtime tests/code will fail.

@mhammond
Copy link
Member

This does seem like a bug, but I can't repro it. eg, in our repo and the following patch:

--- a/fixtures/ext-types/uniffi-one/src/lib.rs
+++ b/fixtures/ext-types/uniffi-one/src/lib.rs
@@ -49,4 +49,9 @@
     fn hello(&self) -> String;
 }
 
+// A "local" type - not referenced by consumers of our crate,
+// so we test support for it is *not* generated for those consumers.
+#[derive(uniffi::Record)]
+pub struct LocalType {}
+
 uniffi::include_scaffolding!("uniffi-one");

This is your "low level" crate. I run the command cargo test -p uniffi-fixture-ext-types (which is your main crate), and the generated code doesn't reference the type. If I add the following patch:

--- a/fixtures/ext-types/lib/src/lib.rs
+++ b/fixtures/ext-types/lib/src/lib.rs
@@ -203,4 +203,8 @@
     t
 }
 
+#[uniffi::export]
+fn get_local_type(_t: uniffi_one::LocalType) {
+}
+
 uniffi::include_scaffolding!("ext-types-lib");

(which is your "main" crate, the crate we are testing) it does.

@thunderbiscuit
Copy link
Author

thunderbiscuit commented Nov 4, 2024

I wonder if it's because you are using the proc macros?

I made a smaller reproducible example here: uniffi/2282.

My calendar-ffi library imports a single type from the lower level clock-ffi library, the ClockType enum. You can see the UDL file here. The generated glue code for the clock-ffi (clock.kt), however, also contains the OtherTypeNotUseful enum, which was not imported at all. It's as if the glue code file generated for the lower level library builds all of the UDL file regardless of what is imported at the higher level lib.

I only realized this because one of our types was defined at both layers (but the higher-level library did not import the low-level one) and that created issues for Swift because in Swift all imports are imported at once and therefore we were getting a name clash.

@mhammond
Copy link
Member

mhammond commented Nov 4, 2024

I don't think procmacros would make a difference here, but both those crates I mentioned above do have udl files.

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

2 participants