Add support for UniFFI 0.31.2 #287 - #289
Open
colintheshots wants to merge 8 commits into
Open
Conversation
Rework gobley-uniffi-bindgen against the breaking external-binding-author API changes in UniFFI 0.30/0.31 and bump the bindgen/Gradle plugin to 0.4.0. - Migrate the object ABI to opaque 64-bit handles (Kotlin Long) instead of pointers, with Rust-vs-foreign handle disambiguation via the lowest bit. - Reorder the callback-interface VTable to (free, clone, methods...) and add the new clone entry; use the odd-handle scheme in UniffiHandleMap. - Migrate the async foreign-future drop model to UniffiForeignFutureDroppedCallback. - Adapt the bindgen to the new APIs: vendor backend::filters/to_askama_error, FfiType::Handle, DefaultValue, self_type(), and ObjectTraitImplMetadata. - Add #[uniffi::trait_interface] to UDL-declared foreign traits in fixtures and update the coverall strong-count expectation to the 0.31 handle-clone semantics. - Add insta snapshot tests over representative UDL fixtures. - Update the bindgen/UniFFI version mapping, tutorials, and CHANGELOG. Co-authored-by: Cursor <cursoragent@cursor.com>
Widen JNA direct-mapped u8/u16 FFI return values to Int at the boundary and lift them back to UByte/UShort, matching upstream UniFFI 0.31, and update generated-code snapshots accordingly. Enable the wasm-unstable-single-threaded feature for the coverall fixture (UniFFI 0.31's wasm32 futures require it), and update the coverall JVM/Android nodeTrait strong-count assertions to reflect 0.31 handle-clone semantics. Co-authored-by: Cursor <cursoragent@cursor.com>
…erage A bare `#[uniffi(default)]` (DefaultValue::Default) previously emitted `TypeName()` for any named type, silently producing Kotlin that fails to compile for objects, custom types, callbacks, and records with required fields. Restore a clear generation-time error for those cases while still allowing records whose fields all have defaults. Add callback, trait (WithForeign), and async snapshot fixtures plus unit tests covering the bare-default codegen behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
Upgrade to uniffi 0.31.2
Mask widened 16-bit checksum returns so undefined upper register bits cannot cause false API mismatch failures. Co-authored-by: Cursor <cursoragent@cursor.com>
Fix UniFFI checksum validation on JVM
|
Hi @colintheshots, while testing this PR with UniFFI 0.31.2, I noticed that types declared in submodules of the same crate are treated as external. This generates references that do not exist. Since UniFFI 0.31, diff --git a/crates/gobley-uniffi-bindgen/src/gen_kotlin_multiplatform/mod.rs b/crates/gobley-uniffi-bindgen/src/gen_kotlin_multiplatform/mod.rs
--- a/crates/gobley-uniffi-bindgen/src/gen_kotlin_multiplatform/mod.rs
+++ b/crates/gobley-uniffi-bindgen/src/gen_kotlin_multiplatform/mod.rs
@@ -855,7 +855,7 @@ impl KotlinCodeOracle {
FfiType::Handle => "Long".to_string(),
FfiType::RustBuffer(maybe_external) => match maybe_external {
- Some(external_meta) if external_meta.module_path != ci.crate_name() => {
+ Some(external_meta) if external_meta.crate_name() != ci.crate_name() => {
format!("RustBuffer{}", external_meta.name)
}
@@ -883,7 +883,7 @@ impl KotlinCodeOracle {
FfiType::Handle => "int64_t".to_string(),
FfiType::RustBuffer(maybe_external) => match maybe_external {
- Some(external_meta) if external_meta.module_path != ci.crate_name() => {
+ Some(external_meta) if external_meta.crate_name() != ci.crate_name() => {
format!("RustBuffer{}", external_meta.name)
}
@@ -1298,7 +1298,7 @@ mod filters {
- if metadata.module_path == ci.crate_name() {
+ if metadata.crate_name() == ci.crate_name() {
return Ok(String::new());
}
@@ -1312,7 +1312,7 @@ mod filters {
- if metadata.module_path == ci.crate_name() {
+ if metadata.crate_name() == ci.crate_name() {
return Ok(String::new());
}With this patch, the generated bindings no longer reference nonexistent per-type |
Since UniFFI 0.31, ExternalFfiMetadata.module_path holds the full module path rather than only the crate name, so types declared in submodules of the same crate were misclassified as external and generated references to nonexistent per-type RustBuffer symbols. Compare crate_name() instead. Co-authored-by: Cursor <cursoragent@cursor.com>
Fix external RustBuffer detection for same-crate submodule types
Author
|
I made that update and verified the changes. |
|
Merging this would be awesome |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
Testing
Unit tests (cargo test -p gobley-uniffi-bindgen):
Integration: ran the UniFFI Gradle test matrix (JVM + host native) for the coverall, futures, callbacks, and type-limits fixtures.
Notes
As a long-time Kotlin dev, I went over the changes by hand and got a human Rust reviewer to review the changes and identify issues I'd missed:
colintheshots#1