Emit operator== for structs with derive(PartialEq)
diff --git a/macro/src/derive.rs b/macro/src/derive.rs
index 91d4c64..28dfae3 100644
--- a/macro/src/derive.rs
+++ b/macro/src/derive.rs
@@ -2,6 +2,8 @@
 use proc_macro2::{Ident, Span, TokenStream};
 use quote::{quote, quote_spanned, ToTokens};
 
+pub use crate::syntax::derive::*;
+
 pub fn expand_struct(strct: &Struct, actual_derives: &mut Option<TokenStream>) -> TokenStream {
     let mut expanded = TokenStream::new();
     let mut traits = Vec::new();
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 62ab95f..bd1aefa 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -5,7 +5,7 @@
 use crate::syntax::symbol::Symbol;
 use crate::syntax::{
     self, check, mangle, Api, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Signature,
-    Struct, Type, TypeAlias, Types,
+    Struct, Trait, Type, TypeAlias, Types,
 };
 use proc_macro2::{Ident, Span, TokenStream};
 use quote::{format_ident, quote, quote_spanned, ToTokens};
@@ -40,7 +40,10 @@
     for api in apis {
         match api {
             Api::Include(_) | Api::Impl(_) => {}
-            Api::Struct(strct) => expanded.extend(expand_struct(strct)),
+            Api::Struct(strct) => {
+                expanded.extend(expand_struct(strct));
+                hidden.extend(expand_struct_operators(strct));
+            }
             Api::Enum(enm) => expanded.extend(expand_enum(enm)),
             Api::CxxType(ety) => {
                 let ident = &ety.name.rust;
@@ -154,6 +157,30 @@
     }
 }
 
+fn expand_struct_operators(strct: &Struct) -> TokenStream {
+    let ident = &strct.name.rust;
+    let mut operators = TokenStream::new();
+
+    for derive in &strct.derives {
+        let span = derive.span;
+        match derive.what {
+            Trait::PartialEq => operators.extend({
+                let link_name = mangle::operator(&strct.name, "__operator_eq");
+                quote_spanned! {span=>
+                    #[doc(hidden)]
+                    #[export_name = #link_name]
+                    extern "C" fn __operator_eq(lhs: &#ident, rhs: &#ident) -> bool {
+                        *lhs == *rhs
+                    }
+                }
+            }),
+            _ => {}
+        }
+    }
+
+    operators
+}
+
 fn expand_enum(enm: &Enum) -> TokenStream {
     let ident = &enm.name.rust;
     let doc = &enm.doc;