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

How to handle async-traits with external types #2423

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

dignifiedquire
Copy link
Contributor

@dignifiedquire dignifiedquire commented Jan 30, 2025

I have been trying to get external types, combined with async trait implementations to work, and created this failing test to show how far I ave come. I don't know if this is missing something fundamental, or if I am setting it up wrong. I would appreciate any pointers.

This fails with

cargo test -p uniffi-fixture-ext-types-proc-macro

running 3 tests
    Finished test [unoptimized + debuginfo] target(s) in 0.03s
test uniffi_foreign_language_testcase_test_imported_types_kts ... FAILED
test uniffi_foreign_language_testcase_test_imported_types_swift ... FAILED
Traceback (most recent call last):
  File "/Users/dignified/opensource/uniffi-rs/fixtures/ext-types/proc-macro-lib/tests/bindings/test_imported_types.py", line 9, in <module>
    from imported_types_lib import *
  File "/Users/dignified/.rust_target/tmp/uniffi_ext_types_proc_macro_lib-1cb60e4ace85aa40/imported_types_lib.py", line 1909, in <module>
    class UniffiOneAsyncTraitImpl(UniffiOneAsyncTrait,):
                                  ^^^^^^^^^^^^^^^^^^^
NameError: name 'UniffiOneAsyncTrait' is not defined. Did you mean: 'UniffiOneTrait'?
test uniffi_foreign_language_testcase_test_imported_types_py ... FAILED

failures:

---- uniffi_foreign_language_testcase_test_imported_types_kts stdout ----
Creating testing out_dir: /Users/dignified/.rust_target/tmp/uniffi_ext_types_proc_macro_lib-d2ca99a8849fc342
Error: failed to create a binding generator

Caused by:
    0: no interface UniffiOneAsyncTrait
    1: no interface UniffiOneAsyncTrait

---- uniffi_foreign_language_testcase_test_imported_types_swift stdout ----
Creating testing out_dir: /Users/dignified/.rust_target/tmp/uniffi_ext_types_proc_macro_lib-d3c7181a63ab8a7a
thread 'uniffi_foreign_language_testcase_test_imported_types_swift' panicked at uniffi_bindgen/src/bindings/swift/gen_swift/mod.rs:429:55:
called `Result::unwrap()` on an `Err` value: Custom(no interface UniffiOneAsyncTrait)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- uniffi_foreign_language_testcase_test_imported_types_py stdout ----
Creating testing out_dir: /Users/dignified/.rust_target/tmp/uniffi_ext_types_proc_macro_lib-1cb60e4ace85aa40
Error: running `python3` failed


failures:
    uniffi_foreign_language_testcase_test_imported_types_kts
    uniffi_foreign_language_testcase_test_imported_types_py
    uniffi_foreign_language_testcase_test_imported_types_swift

test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.44s

error: test failed, to rerun pass `-p uniffi-fixture-ext-types-proc-macro --test test_generated_bindings`

@dignifiedquire dignifiedquire requested a review from a team as a code owner January 30, 2025 17:37
@dignifiedquire dignifiedquire requested review from mhammond and removed request for a team January 30, 2025 17:37
@dignifiedquire dignifiedquire marked this pull request as draft January 30, 2025 17:37
@mhammond
Copy link
Member

external types have had many many changes since 0.28 - are you able to test against main?

@mhammond
Copy link
Member

(oops, actually, I see you are, sorry about that!)

@mhammond
Copy link
Member

mhammond commented Feb 4, 2025

The problem here is that the type isn't being "used" by the lib crate - eg, adding this:

#[uniffi::export]
fn get_trait_2() -> std::sync::Arc<dyn UniffiOneAsyncTrait> {
    panic!()
}

to the proc-macro crate is enough to make it work. This is clearly a bug though, but sadly it's not immediately obvious how to fix it in a reasonable way, so in the meantime this might be an OK work-around?

(Also note this has nothing to do with async, it's just about objects implementing traits)

@mhammond
Copy link
Member

mhammond commented Feb 4, 2025

and for someone in the future looking at actually fixing it - I think what we need is somehow to call add_known_type as we are adding the trait here. The problem is, this CI doesn't actually know about the type, so, eg, get_object(&mut self.objects, &trait_impl.trait_name) returns None rather than the object definition. The work-around I mentioned above means that the trait does appear in a signature, so the trait becomes known in this CI.

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

Successfully merging this pull request may close these issues.

2 participants