summaryrefslogtreecommitdiffstats
path: root/source/xap/mozilla-firefox/8f889cf198ae7ffa9341423cb5a07ed39c07463a.patch
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/xap/mozilla-firefox/8f889cf198ae7ffa9341423cb5a07ed39c07463a.patch801
1 files changed, 0 insertions, 801 deletions
diff --git a/source/xap/mozilla-firefox/8f889cf198ae7ffa9341423cb5a07ed39c07463a.patch b/source/xap/mozilla-firefox/8f889cf198ae7ffa9341423cb5a07ed39c07463a.patch
deleted file mode 100644
index 89e7c12b8..000000000
--- a/source/xap/mozilla-firefox/8f889cf198ae7ffa9341423cb5a07ed39c07463a.patch
+++ /dev/null
@@ -1,801 +0,0 @@
-From 8f889cf198ae7ffa9341423cb5a07ed39c07463a Mon Sep 17 00:00:00 2001
-From: Mike Hommey <mh@glandium.org>
-Date: Thu, 15 Dec 2022 16:36:52 +0900
-Subject: [PATCH] Replace the use of Hash with a custom trait
-
-The custom trait is expected to consistently give the result that Hash
-gives on 64-bits little-endian, but on all platforms
----
- uniffi_bindgen/src/interface/attributes.rs | 19 ++--
- uniffi_bindgen/src/interface/callbacks.rs | 11 +-
- uniffi_bindgen/src/interface/enum_.rs | 5 +-
- uniffi_bindgen/src/interface/error.rs | 3 +-
- uniffi_bindgen/src/interface/function.rs | 17 ++--
- uniffi_bindgen/src/interface/literal.rs | 11 +-
- uniffi_bindgen/src/interface/mod.rs | 28 +++---
- uniffi_bindgen/src/interface/object.rs | 37 +++----
- uniffi_bindgen/src/interface/record.rs | 5 +-
- uniffi_bindgen/src/interface/types/mod.rs | 3 +-
- uniffi_checksum_derive/Cargo.toml | 22 ++++
- uniffi_checksum_derive/src/lib.rs | 111 +++++++++++++++++++++
- uniffi_meta/Cargo.toml | 1 +
- uniffi_meta/src/lib.rs | 89 +++++++++++++++--
- 14 files changed, 288 insertions(+), 74 deletions(-)
- create mode 100644 uniffi_checksum_derive/Cargo.toml
- create mode 100644 uniffi_checksum_derive/src/lib.rs
-
-diff --git a/uniffi_bindgen/src/interface/attributes.rs b/uniffi_bindgen/src/interface/attributes.rs
-index 49b885520..3c9bd522b 100644
---- a/uniffi_bindgen/src/interface/attributes.rs
-+++ b/uniffi_bindgen/src/interface/attributes.rs
-@@ -15,13 +15,14 @@
- //! if we grow significantly more complicated attribute handling.
-
- use anyhow::{bail, Result};
-+use uniffi_meta::Checksum;
-
- /// Represents an attribute parsed from UDL, like `[ByRef]` or `[Throws]`.
- ///
- /// This is a convenience enum for parsing UDL attributes and erroring out if we encounter
- /// any unsupported ones. These don't convert directly into parts of a `ComponentInterface`, but
- /// may influence the properties of things like functions and arguments.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub(super) enum Attribute {
- ByRef,
- Enum,
-@@ -119,7 +120,7 @@ where
-
- /// Attributes that can be attached to an `enum` definition in the UDL.
- /// There's only one case here: using `[Error]` to mark an enum as an error class.
--#[derive(Debug, Clone, Hash, Default)]
-+#[derive(Debug, Clone, Checksum, Default)]
- pub(super) struct EnumAttributes(Vec<Attribute>);
-
- impl EnumAttributes {
-@@ -155,7 +156,7 @@ impl<T: TryInto<EnumAttributes, Error = anyhow::Error>> TryFrom<Option<T>> for E
- ///
- /// This supports the `[Throws=ErrorName]` attribute for functions that
- /// can produce an error.
--#[derive(Debug, Clone, Hash, Default)]
-+#[derive(Debug, Clone, Checksum, Default)]
- pub(super) struct FunctionAttributes(Vec<Attribute>);
-
- impl FunctionAttributes {
-@@ -198,7 +199,7 @@ impl<T: TryInto<FunctionAttributes, Error = anyhow::Error>> TryFrom<Option<T>>
- ///
- /// This supports the `[ByRef]` attribute for arguments that should be passed
- /// by reference in the generated Rust scaffolding.
--#[derive(Debug, Clone, Hash, Default)]
-+#[derive(Debug, Clone, Checksum, Default)]
- pub(super) struct ArgumentAttributes(Vec<Attribute>);
-
- impl ArgumentAttributes {
-@@ -233,7 +234,7 @@ impl<T: TryInto<ArgumentAttributes, Error = anyhow::Error>> TryFrom<Option<T>>
- }
-
- /// Represents UDL attributes that might appear on an `interface` definition.
--#[derive(Debug, Clone, Hash, Default)]
-+#[derive(Debug, Clone, Checksum, Default)]
- pub(super) struct InterfaceAttributes(Vec<Attribute>);
-
- impl InterfaceAttributes {
-@@ -287,7 +288,7 @@ impl<T: TryInto<InterfaceAttributes, Error = anyhow::Error>> TryFrom<Option<T>>
- ///
- /// This supports the `[Throws=ErrorName]` attribute for constructors that can produce
- /// an error, and the `[Name=MethodName]` for non-default constructors.
--#[derive(Debug, Clone, Hash, Default)]
-+#[derive(Debug, Clone, Checksum, Default)]
- pub(super) struct ConstructorAttributes(Vec<Attribute>);
-
- impl ConstructorAttributes {
-@@ -326,7 +327,7 @@ impl TryFrom<&weedle::attribute::ExtendedAttributeList<'_>> for ConstructorAttri
- ///
- /// This supports the `[Throws=ErrorName]` attribute for methods that can produce
- /// an error, and the `[Self=ByArc]` attribute for methods that take `Arc<Self>` as receiver.
--#[derive(Debug, Clone, Hash, Default)]
-+#[derive(Debug, Clone, Checksum, Default)]
- pub(super) struct MethodAttributes(Vec<Attribute>);
-
- impl MethodAttributes {
-@@ -375,7 +376,7 @@ impl<T: TryInto<MethodAttributes, Error = anyhow::Error>> TryFrom<Option<T>> for
- /// Actually we only support one of these right now, `[Self=ByArc]`.
- /// We might add more in future, e.g. a `[Self=ByRef]` if there are cases
- /// where we need to force the receiver to be taken by reference.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub(super) enum SelfType {
- ByArc, // Method receiver is `Arc<Self>`.
- }
-@@ -398,7 +399,7 @@ impl TryFrom<&weedle::attribute::IdentifierOrString<'_>> for SelfType {
- /// Represents UDL attributes that might appear on a typedef
- ///
- /// This supports the `[External="crate_name"]` and `[Custom]` attributes for types.
--#[derive(Debug, Clone, Hash, Default)]
-+#[derive(Debug, Clone, Checksum, Default)]
- pub(super) struct TypedefAttributes(Vec<Attribute>);
-
- impl TypedefAttributes {
-diff --git a/uniffi_bindgen/src/interface/callbacks.rs b/uniffi_bindgen/src/interface/callbacks.rs
-index 654652afe..886f02b29 100644
---- a/uniffi_bindgen/src/interface/callbacks.rs
-+++ b/uniffi_bindgen/src/interface/callbacks.rs
-@@ -33,9 +33,10 @@
- //! # Ok::<(), anyhow::Error>(())
- //! ```
-
--use std::hash::{Hash, Hasher};
-+use std::hash::Hasher;
-
- use anyhow::{bail, Result};
-+use uniffi_meta::Checksum;
-
- use super::ffi::{FFIArgument, FFIFunction, FFIType};
- use super::object::Method;
-@@ -88,16 +89,16 @@ impl CallbackInterface {
- }
- }
-
--impl Hash for CallbackInterface {
-- fn hash<H: Hasher>(&self, state: &mut H) {
-+impl Checksum for CallbackInterface {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
- // We don't include the FFIFunc in the hash calculation, because:
- // - it is entirely determined by the other fields,
- // so excluding it is safe.
- // - its `name` property includes a checksum derived from the very
- // hash value we're trying to calculate here, so excluding it
- // avoids a weird circular depenendency in the calculation.
-- self.name.hash(state);
-- self.methods.hash(state);
-+ self.name.checksum(state);
-+ self.methods.checksum(state);
- }
- }
-
-diff --git a/uniffi_bindgen/src/interface/enum_.rs b/uniffi_bindgen/src/interface/enum_.rs
-index 04eba0d25..b8fe0ddd7 100644
---- a/uniffi_bindgen/src/interface/enum_.rs
-+++ b/uniffi_bindgen/src/interface/enum_.rs
-@@ -77,6 +77,7 @@
- //! ```
-
- use anyhow::{bail, Result};
-+use uniffi_meta::Checksum;
-
- use super::record::Field;
- use super::types::{Type, TypeIterator};
-@@ -87,7 +88,7 @@ use super::{APIConverter, ComponentInterface};
- ///
- /// Enums are passed across the FFI by serializing to a bytebuffer, with a
- /// i32 indicating the variant followed by the serialization of each field.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub struct Enum {
- pub(super) name: String,
- pub(super) variants: Vec<Variant>,
-@@ -174,7 +175,7 @@ impl APIConverter<Enum> for weedle::InterfaceDefinition<'_> {
- /// Represents an individual variant in an Enum.
- ///
- /// Each variant has a name and zero or more fields.
--#[derive(Debug, Clone, Default, Hash)]
-+#[derive(Debug, Clone, Default, Checksum)]
- pub struct Variant {
- pub(super) name: String,
- pub(super) fields: Vec<Field>,
-diff --git a/uniffi_bindgen/src/interface/error.rs b/uniffi_bindgen/src/interface/error.rs
-index 7e9b571a1..adae769f0 100644
---- a/uniffi_bindgen/src/interface/error.rs
-+++ b/uniffi_bindgen/src/interface/error.rs
-@@ -83,6 +83,7 @@
- //! ```
-
- use anyhow::Result;
-+use uniffi_meta::Checksum;
-
- use super::enum_::{Enum, Variant};
- use super::types::{Type, TypeIterator};
-@@ -94,7 +95,7 @@ use super::{APIConverter, ComponentInterface};
- /// they're handled in the FFI very differently. We create them in `uniffi::call_with_result()` if
- /// the wrapped function returns an `Err` value
- /// struct and assign an integer error code to each variant.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub struct Error {
- pub name: String,
- enum_: Enum,
-diff --git a/uniffi_bindgen/src/interface/function.rs b/uniffi_bindgen/src/interface/function.rs
-index 4eff0795c..869c1b59b 100644
---- a/uniffi_bindgen/src/interface/function.rs
-+++ b/uniffi_bindgen/src/interface/function.rs
-@@ -32,9 +32,10 @@
- //! # Ok::<(), anyhow::Error>(())
- //! ```
- use std::convert::TryFrom;
--use std::hash::{Hash, Hasher};
-+use std::hash::Hasher;
-
- use anyhow::{bail, Result};
-+use uniffi_meta::Checksum;
-
- use super::ffi::{FFIArgument, FFIFunction};
- use super::literal::{convert_default_value, Literal};
-@@ -142,18 +143,18 @@ impl From<uniffi_meta::FnMetadata> for Function {
- }
- }
-
--impl Hash for Function {
-- fn hash<H: Hasher>(&self, state: &mut H) {
-+impl Checksum for Function {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
- // We don't include the FFIFunc in the hash calculation, because:
- // - it is entirely determined by the other fields,
- // so excluding it is safe.
- // - its `name` property includes a checksum derived from the very
- // hash value we're trying to calculate here, so excluding it
- // avoids a weird circular depenendency in the calculation.
-- self.name.hash(state);
-- self.arguments.hash(state);
-- self.return_type.hash(state);
-- self.attributes.hash(state);
-+ self.name.checksum(state);
-+ self.arguments.checksum(state);
-+ self.return_type.checksum(state);
-+ self.attributes.checksum(state);
- }
- }
-
-@@ -185,7 +186,7 @@ impl APIConverter<Function> for weedle::namespace::OperationNamespaceMember<'_>
- /// Represents an argument to a function/constructor/method call.
- ///
- /// Each argument has a name and a type, along with some optional metadata.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub struct Argument {
- pub(super) name: String,
- pub(super) type_: Type,
-diff --git a/uniffi_bindgen/src/interface/literal.rs b/uniffi_bindgen/src/interface/literal.rs
-index 8b333c614..1aa1c8785 100644
---- a/uniffi_bindgen/src/interface/literal.rs
-+++ b/uniffi_bindgen/src/interface/literal.rs
-@@ -8,12 +8,13 @@
- //! which appear in places such as default arguments.
-
- use anyhow::{bail, Result};
-+use uniffi_meta::Checksum;
-
- use super::types::Type;
-
- // Represents a literal value.
- // Used for e.g. default argument values.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub enum Literal {
- Boolean(bool),
- String(String),
-@@ -35,13 +36,19 @@ pub enum Literal {
-
- // Represent the radix of integer literal values.
- // We preserve the radix into the generated bindings for readability reasons.
--#[derive(Debug, Clone, Copy, Hash)]
-+#[derive(Debug, Clone, Copy)]
- pub enum Radix {
- Decimal = 10,
- Octal = 8,
- Hexadecimal = 16,
- }
-
-+impl Checksum for Radix {
-+ fn checksum<H: ::core::hash::Hasher>(&self, state: &mut H) {
-+ state.write(&(*self as u64).to_le_bytes());
-+ }
-+}
-+
- pub(super) fn convert_default_value(
- default_value: &weedle::literal::DefaultValue<'_>,
- type_: &Type,
-diff --git a/uniffi_bindgen/src/interface/mod.rs b/uniffi_bindgen/src/interface/mod.rs
-index 9aa92e9b0..eb40ea3fd 100644
---- a/uniffi_bindgen/src/interface/mod.rs
-+++ b/uniffi_bindgen/src/interface/mod.rs
-@@ -47,7 +47,7 @@
- use std::{
- collections::HashSet,
- convert::TryFrom,
-- hash::{Hash, Hasher},
-+ hash::Hasher,
- iter,
- };
-
-@@ -77,7 +77,7 @@ pub use record::{Field, Record};
-
- pub mod ffi;
- pub use ffi::{FFIArgument, FFIFunction, FFIType};
--use uniffi_meta::{MethodMetadata, ObjectMetadata};
-+use uniffi_meta::{Checksum, MethodMetadata, ObjectMetadata};
-
- /// The main public interface for this module, representing the complete details of an interface exposed
- /// by a rust component and the details of consuming it via an extern-C FFI layer.
-@@ -672,20 +672,16 @@ impl ComponentInterface {
- }
- }
-
--/// `ComponentInterface` structs can be hashed, but this is mostly a convenient way to
--/// produce a checksum of their contents. They're not really intended to live in a hashtable.
--impl Hash for ComponentInterface {
-- fn hash<H: Hasher>(&self, state: &mut H) {
-- // We can't hash `self.types`, but its contents are implied by the other fields
-- // anyway, so it's safe to ignore it.
-- self.uniffi_version.hash(state);
-- self.namespace.hash(state);
-- self.enums.hash(state);
-- self.records.hash(state);
-- self.functions.hash(state);
-- self.objects.hash(state);
-- self.callback_interfaces.hash(state);
-- self.errors.hash(state);
-+impl Checksum for ComponentInterface {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ Checksum::checksum(&self.uniffi_version, state);
-+ Checksum::checksum(&self.namespace, state);
-+ Checksum::checksum(&self.enums, state);
-+ Checksum::checksum(&self.records, state);
-+ Checksum::checksum(&self.functions, state);
-+ Checksum::checksum(&self.objects, state);
-+ Checksum::checksum(&self.callback_interfaces, state);
-+ Checksum::checksum(&self.errors, state);
- }
- }
-
-diff --git a/uniffi_bindgen/src/interface/object.rs b/uniffi_bindgen/src/interface/object.rs
-index e366123b5..3bd6bfabe 100644
---- a/uniffi_bindgen/src/interface/object.rs
-+++ b/uniffi_bindgen/src/interface/object.rs
-@@ -58,10 +58,11 @@
- //! ```
-
- use std::convert::TryFrom;
--use std::hash::{Hash, Hasher};
-+use std::hash::Hasher;
- use std::{collections::HashSet, iter};
-
- use anyhow::{bail, Result};
-+use uniffi_meta::Checksum;
-
- use super::ffi::{FFIArgument, FFIFunction, FFIType};
- use super::function::Argument;
-@@ -190,17 +191,17 @@ impl Object {
- }
- }
-
--impl Hash for Object {
-- fn hash<H: Hasher>(&self, state: &mut H) {
-+impl Checksum for Object {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
- // We don't include the FFIFunc in the hash calculation, because:
- // - it is entirely determined by the other fields,
- // so excluding it is safe.
- // - its `name` property includes a checksum derived from the very
- // hash value we're trying to calculate here, so excluding it
- // avoids a weird circular depenendency in the calculation.
-- self.name.hash(state);
-- self.constructors.hash(state);
-- self.methods.hash(state);
-+ self.name.checksum(state);
-+ self.constructors.checksum(state);
-+ self.methods.checksum(state);
- }
- }
-
-@@ -299,17 +300,17 @@ impl Constructor {
- }
- }
-
--impl Hash for Constructor {
-- fn hash<H: Hasher>(&self, state: &mut H) {
-+impl Checksum for Constructor {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
- // We don't include the FFIFunc in the hash calculation, because:
- // - it is entirely determined by the other fields,
- // so excluding it is safe.
- // - its `name` property includes a checksum derived from the very
- // hash value we're trying to calculate here, so excluding it
- // avoids a weird circular depenendency in the calculation.
-- self.name.hash(state);
-- self.arguments.hash(state);
-- self.attributes.hash(state);
-+ self.name.checksum(state);
-+ self.arguments.checksum(state);
-+ self.attributes.checksum(state);
- }
- }
-
-@@ -450,19 +451,19 @@ impl From<uniffi_meta::MethodMetadata> for Method {
- }
- }
-
--impl Hash for Method {
-- fn hash<H: Hasher>(&self, state: &mut H) {
-+impl Checksum for Method {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
- // We don't include the FFIFunc in the hash calculation, because:
- // - it is entirely determined by the other fields,
- // so excluding it is safe.
- // - its `name` property includes a checksum derived from the very
- // hash value we're trying to calculate here, so excluding it
- // avoids a weird circular depenendency in the calculation.
-- self.name.hash(state);
-- self.object_name.hash(state);
-- self.arguments.hash(state);
-- self.return_type.hash(state);
-- self.attributes.hash(state);
-+ self.name.checksum(state);
-+ self.object_name.checksum(state);
-+ self.arguments.checksum(state);
-+ self.return_type.checksum(state);
-+ self.attributes.checksum(state);
- }
- }
-
-diff --git a/uniffi_bindgen/src/interface/record.rs b/uniffi_bindgen/src/interface/record.rs
-index c55200eb1..dd6a48e2c 100644
---- a/uniffi_bindgen/src/interface/record.rs
-+++ b/uniffi_bindgen/src/interface/record.rs
-@@ -45,6 +45,7 @@
- //! ```
-
- use anyhow::{bail, Result};
-+use uniffi_meta::Checksum;
-
- use super::types::{Type, TypeIterator};
- use super::{
-@@ -58,7 +59,7 @@ use super::{APIConverter, ComponentInterface};
- /// In the FFI these are represented as a byte buffer, which one side explicitly
- /// serializes the data into and the other serializes it out of. So I guess they're
- /// kind of like "pass by clone" values.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub struct Record {
- pub(super) name: String,
- pub(super) fields: Vec<Field>,
-@@ -109,7 +110,7 @@ impl APIConverter<Record> for weedle::DictionaryDefinition<'_> {
- }
-
- // Represents an individual field on a Record.
--#[derive(Debug, Clone, Hash)]
-+#[derive(Debug, Clone, Checksum)]
- pub struct Field {
- pub(super) name: String,
- pub(super) type_: Type,
-diff --git a/uniffi_bindgen/src/interface/types/mod.rs b/uniffi_bindgen/src/interface/types/mod.rs
-index 8a0131c9f..65426926f 100644
---- a/uniffi_bindgen/src/interface/types/mod.rs
-+++ b/uniffi_bindgen/src/interface/types/mod.rs
-@@ -25,6 +25,7 @@ use std::{collections::hash_map::Entry, collections::BTreeSet, collections::Hash
-
- use anyhow::{bail, Result};
- use heck::ToUpperCamelCase;
-+use uniffi_meta::Checksum;
-
- use super::ffi::FFIType;
-
-@@ -36,7 +37,7 @@ pub(super) use resolver::{resolve_builtin_type, TypeResolver};
- /// Represents all the different high-level types that can be used in a component interface.
- /// At this level we identify user-defined types by name, without knowing any details
- /// of their internal structure apart from what type of thing they are (record, enum, etc).
--#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
-+#[derive(Debug, Clone, Eq, PartialEq, Checksum, Ord, PartialOrd)]
- pub enum Type {
- // Primitive types.
- UInt8,
-diff --git a/uniffi_checksum_derive/Cargo.toml b/uniffi_checksum_derive/Cargo.toml
-new file mode 100644
-index 000000000..a04c31aab
---- /dev/null
-+++ b/uniffi_checksum_derive/Cargo.toml
-@@ -0,0 +1,22 @@
-+[package]
-+name = "uniffi_checksum_derive"
-+version = "0.21.0"
-+authors = ["Firefox Sync Team <sync-team@mozilla.com>"]
-+description = "a multi-language bindings generator for rust (checksum custom derive)"
-+documentation = "https://mozilla.github.io/uniffi-rs"
-+homepage = "https://mozilla.github.io/uniffi-rs"
-+repository = "https://github.com/mozilla/uniffi-rs"
-+license = "MPL-2.0"
-+edition = "2021"
-+keywords = ["ffi", "bindgen"]
-+
-+[lib]
-+proc-macro = true
-+
-+[dependencies]
-+quote = "1.0"
-+syn = { version = "1.0", features = ["derive"] }
-+
-+[features]
-+default = []
-+nightly = []
-diff --git a/uniffi_checksum_derive/src/lib.rs b/uniffi_checksum_derive/src/lib.rs
-new file mode 100644
-index 000000000..c79064d8b
---- /dev/null
-+++ b/uniffi_checksum_derive/src/lib.rs
-@@ -0,0 +1,111 @@
-+/* 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/. */
-+#![cfg_attr(feature = "nightly", feature(proc_macro_expand))]
-+
-+//! Custom derive for uniffi_meta::Checksum
-+
-+use proc_macro::TokenStream;
-+use quote::{format_ident, quote};
-+use syn::{parse_macro_input, Data, DeriveInput, Fields, Index};
-+
-+#[proc_macro_derive(Checksum)]
-+pub fn checksum_derive(input: TokenStream) -> TokenStream {
-+ let input: DeriveInput = parse_macro_input!(input);
-+
-+ let name = input.ident;
-+
-+ let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
-+
-+ let code = match input.data {
-+ Data::Enum(enum_)
-+ if enum_.variants.len() == 1
-+ && enum_
-+ .variants
-+ .iter()
-+ .all(|variant| matches!(variant.fields, Fields::Unit)) =>
-+ {
-+ quote!()
-+ }
-+ Data::Enum(enum_) => {
-+ let match_inner = enum_.variants.iter().enumerate().map(|(num, variant)| {
-+ let num = num as u64;
-+ let ident = &variant.ident;
-+ if variant.discriminant.is_some() {
-+ panic!("#[derive(Checksum)] doesn't support explicit discriminants in enums");
-+ }
-+ let discriminant = quote! { state.write(&#num.to_le_bytes()) };
-+ match &variant.fields {
-+ Fields::Unnamed(fields) => {
-+ let field_idents = fields
-+ .unnamed
-+ .iter()
-+ .enumerate()
-+ .map(|(num, _)| format_ident!("__self_{}", num))
-+ .collect::<Vec<_>>();
-+ let field_stmts = field_idents
-+ .iter()
-+ .map(|ident| quote! { Checksum::checksum(#ident, state); });
-+ quote! {
-+ Self::#ident(#(#field_idents,)*) => {
-+ #discriminant;
-+ #(#field_stmts)*
-+ }
-+ }
-+ }
-+ Fields::Named(fields) => {
-+ let field_idents = fields
-+ .named
-+ .iter()
-+ .map(|field| field.ident.as_ref().unwrap())
-+ .collect::<Vec<_>>();
-+ let field_stmts = field_idents
-+ .iter()
-+ .map(|ident| quote! { Checksum::checksum(#ident, state); });
-+ quote! {
-+ Self::#ident { #(#field_idents,)* } => {
-+ #discriminant;
-+ #(#field_stmts)*
-+ }
-+ }
-+ }
-+ Fields::Unit => quote! { Self::#ident => #discriminant, },
-+ }
-+ });
-+ quote! {
-+ match self {
-+ #(#match_inner)*
-+ }
-+ }
-+ }
-+ Data::Struct(struct_) => {
-+ let stmts =
-+ struct_
-+ .fields
-+ .iter()
-+ .enumerate()
-+ .map(|(num, field)| match field.ident.as_ref() {
-+ Some(ident) => quote! { Checksum::checksum(&self.#ident, state); },
-+ None => {
-+ let i = Index::from(num);
-+ quote! { Checksum::checksum(&self.#i, state); }
-+ }
-+ });
-+ quote! {
-+ #(#stmts)*
-+ }
-+ }
-+ Data::Union(_) => {
-+ panic!("#[derive(Checksum)] is not supported for unions");
-+ }
-+ };
-+
-+ quote! {
-+ impl #impl_generics Checksum for #name #ty_generics #where_clause {
-+ fn checksum<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
-+ #code
-+ }
-+ }
-+ }
-+ .into()
-+}
-diff --git a/uniffi_meta/Cargo.toml b/uniffi_meta/Cargo.toml
-index ca33156df..358b6ef4c 100644
---- a/uniffi_meta/Cargo.toml
-+++ b/uniffi_meta/Cargo.toml
-@@ -10,3 +10,4 @@ keywords = ["ffi", "bindgen"]
-
- [dependencies]
- serde = { version = "1.0.136", features = ["derive"] }
-+uniffi_checksum_derive = { version = "0.21.0", path = "../uniffi_checksum_derive" }
-diff --git a/uniffi_meta/src/lib.rs b/uniffi_meta/src/lib.rs
-index 6cfa733e9..2555ae19c 100644
---- a/uniffi_meta/src/lib.rs
-+++ b/uniffi_meta/src/lib.rs
-@@ -6,10 +6,79 @@ use std::{
- collections::hash_map::DefaultHasher,
- hash::{Hash, Hasher},
- };
-+pub use uniffi_checksum_derive::Checksum;
-
- use serde::{Deserialize, Serialize};
-
--#[derive(Clone, Debug, Hash, Deserialize, Serialize)]
-+pub trait Checksum {
-+ fn checksum<H: Hasher>(&self, state: &mut H);
-+}
-+
-+impl Checksum for bool {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ Hash::hash(self, state);
-+ }
-+}
-+
-+impl Checksum for u64 {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ state.write(&self.to_le_bytes());
-+ }
-+}
-+
-+impl Checksum for i64 {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ state.write(&self.to_le_bytes());
-+ }
-+}
-+
-+impl<T: Checksum> Checksum for Box<T> {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ (**self).checksum(state)
-+ }
-+}
-+
-+impl<T: Checksum> Checksum for [T] {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ state.write(&(self.len() as u64).to_le_bytes());
-+ for item in self {
-+ Checksum::checksum(item, state);
-+ }
-+ }
-+}
-+
-+impl<T: Checksum> Checksum for Vec<T> {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ Checksum::checksum(&**self, state);
-+ }
-+}
-+
-+impl<T: Checksum> Checksum for Option<T> {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ match self {
-+ None => state.write(&0u64.to_le_bytes()),
-+ Some(value) => {
-+ state.write(&1u64.to_le_bytes());
-+ Checksum::checksum(value, state)
-+ }
-+ }
-+ }
-+}
-+
-+impl Checksum for str {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ state.write(self.as_bytes());
-+ state.write_u8(0xff);
-+ }
-+}
-+
-+impl Checksum for String {
-+ fn checksum<H: Hasher>(&self, state: &mut H) {
-+ (**self).checksum(state)
-+ }
-+}
-+
-+#[derive(Clone, Debug, Checksum, Deserialize, Serialize)]
- pub struct FnMetadata {
- pub module_path: Vec<String>,
- pub name: String,
-@@ -23,7 +92,7 @@ impl FnMetadata {
- }
- }
-
--#[derive(Clone, Debug, Hash, Deserialize, Serialize)]
-+#[derive(Clone, Debug, Checksum, Deserialize, Serialize)]
- pub struct MethodMetadata {
- pub module_path: Vec<String>,
- pub self_name: String,
-@@ -39,14 +108,14 @@ impl MethodMetadata {
- }
- }
-
--#[derive(Clone, Debug, Hash, Deserialize, Serialize)]
-+#[derive(Clone, Debug, Checksum, Deserialize, Serialize)]
- pub struct FnParamMetadata {
- pub name: String,
- #[serde(rename = "type")]
- pub ty: Type,
- }
-
--#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
-+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Checksum, Deserialize, Serialize)]
- pub enum Type {
- U8,
- U16,
-@@ -78,21 +147,21 @@ pub enum Type {
- },
- }
-
--#[derive(Clone, Debug, Hash, Deserialize, Serialize)]
-+#[derive(Clone, Debug, Checksum, Deserialize, Serialize)]
- pub struct RecordMetadata {
- pub module_path: Vec<String>,
- pub name: String,
- pub fields: Vec<FieldMetadata>,
- }
-
--#[derive(Clone, Debug, Hash, Deserialize, Serialize)]
-+#[derive(Clone, Debug, Checksum, Deserialize, Serialize)]
- pub struct FieldMetadata {
- pub name: String,
- #[serde(rename = "type")]
- pub ty: Type,
- }
-
--#[derive(Clone, Debug, Hash, Deserialize, Serialize)]
-+#[derive(Clone, Debug, Checksum, Deserialize, Serialize)]
- pub struct ObjectMetadata {
- pub module_path: Vec<String>,
- pub name: String,
-@@ -112,9 +181,9 @@ impl ObjectMetadata {
- ///
- /// To be used as a checksum of FFI symbols, as a safeguard against different UniFFI versions being
- /// used for scaffolding and bindings generation.
--pub fn checksum<T: Hash>(val: &T) -> u16 {
-+pub fn checksum<T: Checksum>(val: &T) -> u16 {
- let mut hasher = DefaultHasher::new();
-- val.hash(&mut hasher);
-+ val.checksum(&mut hasher);
- (hasher.finish() & 0x000000000000FFFF) as u16
- }
-
-@@ -124,7 +193,7 @@ pub fn fn_ffi_symbol_name(mod_path: &[String], name: &str, checksum: u16) -> Str
- }
-
- /// Enum covering all the possible metadata types
--#[derive(Clone, Debug, Hash, Deserialize, Serialize)]
-+#[derive(Clone, Debug, Checksum, Deserialize, Serialize)]
- pub enum Metadata {
- Func(FnMetadata),
- Method(MethodMetadata),