Fix previous commit.
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 2ea6ca8..70620ce 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -5,7 +5,7 @@
 use crate::syntax::symbol::Symbol;
 use crate::syntax::{mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, Types, Var};
 use proc_macro2::Ident;
-use std::collections::{HashMap, HashSet};
+use std::collections::HashMap;
 
 pub(super) fn gen(
     namespace: &Namespace,
@@ -46,7 +46,6 @@
         }
     }
 
-    let mut cxx_types = HashSet::new();
     let mut methods_for_type = HashMap::new();
     for api in apis {
         if let Api::RustFunction(efn) = api {
@@ -57,9 +56,6 @@
                     .push(efn);
             }
         }
-        if let Api::CxxType(enm) = api {
-            cxx_types.insert(&enm.ident);
-        }
     }
 
     for api in apis {
@@ -70,7 +66,7 @@
             }
             Api::Enum(enm) => {
                 out.next_section();
-                if cxx_types.contains(&enm.ident) {
+                if types.cxx.contains(&enm.ident) {
                     check_enum(out, enm);
                 } else {
                     write_enum(out, enm);
@@ -382,31 +378,24 @@
 }
 
 fn check_enum(out: &mut OutFile, enm: &Enum) {
-    let discriminants = enm
-        .variants
-        .iter()
-        .scan(None, |prev_discriminant, variant| {
-            let discriminant = variant
-                .discriminant
-                .unwrap_or_else(|| prev_discriminant.map_or(0, |n| n + 1));
-            *prev_discriminant = Some(discriminant);
-            Some(discriminant)
-        });
     writeln!(
         out,
         "static_assert(sizeof({}) == sizeof(uint32_t));",
         enm.ident
     );
-    enm.variants
-        .iter()
-        .zip(discriminants)
-        .for_each(|(variant, discriminant)| {
-            writeln!(
-                out,
-                "static_assert({}::{} == {});",
-                enm.ident, variant.ident, discriminant
-            );
-        });
+    let mut prev_discriminant = None;
+    for variant in &enm.variants {
+        let discriminant = variant
+            .discriminant
+            .unwrap_or_else(|| prev_discriminant.map_or(0, |n| n + 1));
+        writeln!(
+            out,
+            "static_assert(static_cast<uint32_t>({}::{}) == {},
+              \"disagrees with the value in #[cxx::bridge]\");",
+            enm.ident, variant.ident, discriminant,
+        );
+        prev_discriminant = Some(discriminant);
+    }
 }
 
 fn write_exception_glue(out: &mut OutFile, apis: &[Api]) {
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 1a23960..d8810dc 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -7,7 +7,6 @@
 };
 use proc_macro2::{Ident, Span, TokenStream};
 use quote::{format_ident, quote, quote_spanned, ToTokens};
-use std::collections::HashSet;
 use syn::{parse_quote, Error, ItemMod, Result, Token};
 
 pub fn bridge(namespace: &Namespace, mut ffi: ItemMod) -> Result<TokenStream> {
@@ -40,19 +39,13 @@
         }
     }
 
-    let mut enums = HashSet::new();
-    for api in apis {
-        if let Api::Enum(enm) = api {
-            enums.insert(&enm.ident);
-        }
-    }
     for api in apis {
         match api {
             Api::Include(_) | Api::RustType(_) => {}
             Api::Struct(strct) => expanded.extend(expand_struct(strct)),
             Api::Enum(enm) => expanded.extend(expand_enum(enm)),
             Api::CxxType(ety) => {
-                if !enums.contains(&ety.ident) {
+                if !types.enums.contains_key(&ety.ident) {
                     expanded.extend(expand_cxx_type(ety));
                 }
             }
diff --git a/syntax/types.rs b/syntax/types.rs
index bfe7bf0..5800513 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -61,11 +61,12 @@
                 }
                 Api::Enum(enm) => {
                     let ident = &enm.ident;
-                    if type_names.insert(ident) {
-                        enums.insert(ident.clone(), enm);
-                    } else {
+                    // We allow declaring the same type as a shared enum and as a Cxxtype, as this
+                    // means not to emit the C++ enum definition.
+                    if !type_names.insert(ident) && !cxx.contains(ident) {
                         duplicate_name(cx, enm, ident);
                     }
+                    enums.insert(ident.clone(), enm);
                 }
                 Api::CxxType(ety) => {
                     let ident = &ety.ident;
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index 0162c9b..16846fb 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -84,6 +84,15 @@
         fn set2(&mut self, n: usize) -> usize;
     }
 
+    extern "C" {
+        type COwnedEnum;
+    }
+
+    enum COwnedEnum {
+        CVal1,
+        CVal2,
+    }
+
     extern "Rust" {
         type R;
         type R2;
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index d3b7d38..795b4a9 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -23,6 +23,11 @@
   std::vector<uint8_t> v;
 };
 
+enum COwnedEnum {
+  CVal1,
+  CVal2,
+};
+
 size_t c_return_primitive();
 Shared c_return_shared();
 rust::Box<R> c_return_box();