Skip to content

Update and add support for uniffi v0.31.2 - #2

Merged
alan-george-lk merged 6 commits into
livekit/devfrom
livekit/uniffi-0.31
Sep 22, 2026
Merged

alan-george-lk merged 6 commits into
livekit/devfrom
livekit/uniffi-0.31

Conversation

@alan-george-lk

@alan-george-lk alan-george-lk commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

This PR updates the C++ bindgen from UniFFI 0.29.4 to 0.31.2.

Required compatibility changes include:

  • Adapting to UniFFI’s new DefaultValue and relocated interface APIs
  • Replacing pointer-based Rust object ABI values with uint64_t handles
  • Supporting the updated trait-interface ABI, including uniffi_clone, odd/even handle ownership, and round-tripping Rust- and C++-implemented trait objects
  • Generating the new Ord::cmp trait method
  • Handling unnamed enum fields, deduplicating generated definitions, and preventing false dependency cycles during type ordering
  • Marking external Rust traits with #[uniffi::trait_interface]
  • Updating all fixtures and expected reference-count behavior for UniFFI 0.31.2
  • Generating exported methods on records and enums, including rich enums, flat enums, and error enums
  • Exposing UniFFI’s Debug, Display, Eq, Hash, and Ord traits on record and enum value types
  • Restricting C++ definition ordering to record fields and enum variants, preventing method self-types from introducing false dependency cycles
  • Adding C++ coverage for record/enum methods and standard traits, including error-value comparison and flat-enum functions

@alan-george-lk alan-george-lk changed the title Livekit/uniffi 0.31 Update and add support for uniffi v0.31.2 Sep 15, 2026
@alan-george-lk
alan-george-lk added this pull request to stack #4 September 15, 2026 03:44

pub(crate) fn literal_cpp(
literal: &Literal,
default: &DefaultValue,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, default_value might be better name here ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

while !definition_topology.peek_all().is_empty() {
let list = definition_topology.pop_all();
let mut list = definition_topology.pop_all();
list.sort();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any technical reason why we need list.sort() here ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a technically unrelated fix, I could move off this branch if you prefer.

My understanding is pop_all() does not guarantee order due to hashing, so without this list.sort() generated code could be non-deterministic in order.

Would not affect a lot, but I know there are some C++ nuances around member initialization order/lifetimes so this is a good practice I'd argue.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK to keep it as is.

@jhugman jhugman left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good from a uniffi and Rust pov. It's a real pleasure looking at small bindgen.

It may be further up in the stack, but I'm not seeing:

  • methods on records and enums
  • uniffi traits on the same.

(these are the largest omissions by comparing against the uniffi-rs changelog for the version range).

These omissions may be better done in another PR, so I'm going to r+ this one so as not to hold you up.


let rest = types
.filter(|&t| !sorted.contains(t))
.filter(|t| type_name(t).map_or(true, |name| !emitted_names.contains(name)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment here might be nice.

Comment on lines +74 to +79
ASSERT_EQ(first.to_debug_string(), "TraitRecord { s: \"same\", i: 1 }");
ASSERT_TRUE(first.eq(second));
ASSERT_FALSE(first.ne(second));
ASSERT_FALSE(first.eq(different));
ASSERT_EQ(first.hash(), second.hash());
ASSERT_EQ(first.cmp(second), 0);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was skeptical of these method names vs. operators and other options in C++, but there is precedent for them in this bindgen/Rust already for objects

@jhugman jhugman left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice. Thank you so much.

int8_t cmp({{ type_name }} _uniffi_self, {{ type_name }} other) {
return uniffi::{{ Type::Int8.borrow()|lift_fn }}({% call macros::rust_call_with_value(method, typ) %});
}
{%- endif %}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.

{%- if uniffi_trait_methods.ord_cmp.is_some() %}
/** Calls the value's Rust `Ord` implementation. */
int8_t cmp({{ type_name }} _uniffi_self, {{ type_name }} other);
{%- endif %}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@xianshijing-lk xianshijing-lk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@alan-george-lk
alan-george-lk removed this pull request from stack #4 September 22, 2026 19:04
@alan-george-lk
alan-george-lk merged commit 8a9d867 into livekit/dev Sep 22, 2026
6 checks passed
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.

3 participants