Skip to content

Commit

Permalink
New system for interface metadata
Browse files Browse the repository at this point in the history
- Added the `uniffi_core::metadata` module, which provides a system for
  building metadata buffers using const code.
- Added the `FfiConverter::TYPE_ID_META` const, which holds metadata
  to identify the type.
- Made the proc-macros generate use the new system to generate metadata
  consts, then export them using static variables.
- Removed the current code to generate/store metadata based on the syn
  parsing.
- Removed the type assertions and the requirement for a `uniffi_types`
  module.  We don't need them now that we`re getting the type ids from
  the type itself.
- Made the `FnMetadata.throws` field a Type rather than a String.
- Calculate module paths with the `module_path!()` macro.  This means we
  get accurate module paths without nightly.  Changed mod_path to be a
  String, rather than a Vec since this is what `module_path!()` outputs.
- Added code to strip the `r#` part out of raw idents before serializing
  it into the metadata.
- Replaced the `collect_params()` function with the `ScaffoldingBits`
  struct.  There was too much complexity for a single function -- for
  example unzip() only works with pairs, not 3-tuples.

In general, the new metadata system is more reliable doing everything in
the proc-macros.  Proc-macros can only see the type identifiers, but
they don't anything about the underlying type, since users can rename
types with type aliases.  It's also simpler since you don't have to walk
the AST so much.

One TODO is getting checksum working again.  One limitation of the const
code is that we can't use it to generate function identifiers.
  • Loading branch information
bendk committed Mar 31, 2023
1 parent 41e94c0 commit 5367a3d
Show file tree
Hide file tree
Showing 48 changed files with 1,776 additions and 860 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
### What's changed

- The `include_scaffolding!()` macro must now either be called from your crate root or you must have `use the_mod_that_calls_include_scaffolding::*` in your crate root. This was always the expectation, but wasn't required before. This will now start failing with errors that say `crate::UniFfiTag` does not exist.
- proc-macros now work with many more types including type aliases, type paths, etc.
- The `uniffi_types` module is no longer needed when using proc-macros.

## v0.23.0 (backend crates: v0.23.0) - (_2023-01-27_)

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ members = [
"fixtures/keywords/kotlin",
"fixtures/keywords/rust",
"fixtures/keywords/swift",
"fixtures/metadata",
"fixtures/proc-macro",
"fixtures/reexport-scaffolding-macro",
"fixtures/regressions/enum-without-i32-helpers",
Expand Down
10 changes: 0 additions & 10 deletions docs/manual/src/proc_macro/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,6 @@ User-defined types are also supported in a limited manner: records (structs with
their definition. Opaque objects (`interface` in UDL) can always be used regardless of whether they
are defined in UDL and / or via derive macro; they just need to be put inside an `Arc` as always.

User-defined types also have to be (re-)exported from a module called `uniffi_types` at the crate
root. This is required to ensure that a given type name always means the same thing across all uses
of `#[uniffi::export]` across the whole module tree.

```rust
mod uniffi_types {
pub(crate) use path::to::MyObject;
}
```

## The `uniffi::Record` derive

The `Record` derive macro exposes a `struct` with named fields over FFI. All types that are
Expand Down
6 changes: 0 additions & 6 deletions fixtures/futures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,3 @@ pub async fn broken_sleep(ms: u16, fail_after: u16) {
}

include!(concat!(env!("OUT_DIR"), "/uniffi_futures.uniffi.rs"));

mod uniffi_types {
pub(crate) use super::Megaphone;
pub(crate) use super::MyError;
pub(crate) use super::MyRecord;
}
15 changes: 15 additions & 0 deletions fixtures/metadata/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "uniffi_fixture_metadata"
version = "0.1.0"
authors = ["Firefox Sync Team <sync-team@mozilla.com>"]
edition = "2021"
license = "MPL-2.0"
publish = false

[lib]
name = "uniffi_fixture_metadata"

[dependencies]
uniffi = { path = "../../uniffi" }
uniffi_meta = { path = "../../uniffi_meta" }
uniffi_core = { path = "../../uniffi_core" }
11 changes: 11 additions & 0 deletions fixtures/metadata/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/// This entire crate is just a set of tests for metadata handling. We use a separate crate
/// for testing because the metadata handling is split up between several crates, and no crate
/// on all the functionality.
#[cfg(test)]
mod tests;

pub struct UniFfiTag;
Loading

0 comments on commit 5367a3d

Please sign in to comment.