Respect inferred enum repr in C++ code generator
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 8f54bd7..0849d90 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -365,7 +365,9 @@
     for line in enm.doc.to_string().lines() {
         writeln!(out, "//{}", line);
     }
-    writeln!(out, "enum class {} : uint32_t {{", enm.ident);
+    write!(out, "enum class {} : ", enm.ident);
+    write_atom(out, enm.repr);
+    writeln!(out, " {{");
     for variant in &enm.variants {
         writeln!(out, "  {} = {},", variant.ident, variant.discriminant);
     }
@@ -373,16 +375,15 @@
 }
 
 fn check_enum(out: &mut OutFile, enm: &Enum) {
-    writeln!(
-        out,
-        "static_assert(sizeof({}) == sizeof(uint32_t), \"incorrect size\");",
-        enm.ident
-    );
+    write!(out, "static_assert(sizeof({}) == sizeof(", enm.ident);
+    write_atom(out, enm.repr);
+    writeln!(out, "), \"incorrect size\");");
     for variant in &enm.variants {
+        write!(out, "static_assert(static_cast<");
+        write_atom(out, enm.repr);
         writeln!(
             out,
-            "static_assert(static_cast<uint32_t>({}::{}) == {},
-              \"disagrees with the value in #[cxx::bridge]\");",
+            ">({}::{}) == {}, \"disagrees with the value in #[cxx::bridge]\");",
             enm.ident, variant.ident, variant.discriminant,
         );
     }
@@ -849,21 +850,7 @@
 fn write_type(out: &mut OutFile, ty: &Type) {
     match ty {
         Type::Ident(ident) => match Atom::from(ident) {
-            Some(Bool) => write!(out, "bool"),
-            Some(U8) => write!(out, "uint8_t"),
-            Some(U16) => write!(out, "uint16_t"),
-            Some(U32) => write!(out, "uint32_t"),
-            Some(U64) => write!(out, "uint64_t"),
-            Some(Usize) => write!(out, "size_t"),
-            Some(I8) => write!(out, "int8_t"),
-            Some(I16) => write!(out, "int16_t"),
-            Some(I32) => write!(out, "int32_t"),
-            Some(I64) => write!(out, "int64_t"),
-            Some(Isize) => write!(out, "::rust::isize"),
-            Some(F32) => write!(out, "float"),
-            Some(F64) => write!(out, "double"),
-            Some(CxxString) => write!(out, "::std::string"),
-            Some(RustString) => write!(out, "::rust::String"),
+            Some(atom) => write_atom(out, atom),
             None => write!(out, "{}", ident),
         },
         Type::RustBox(ty) => {
@@ -922,6 +909,26 @@
     }
 }
 
+fn write_atom(out: &mut OutFile, atom: Atom) {
+    match atom {
+        Bool => write!(out, "bool"),
+        U8 => write!(out, "uint8_t"),
+        U16 => write!(out, "uint16_t"),
+        U32 => write!(out, "uint32_t"),
+        U64 => write!(out, "uint64_t"),
+        Usize => write!(out, "size_t"),
+        I8 => write!(out, "int8_t"),
+        I16 => write!(out, "int16_t"),
+        I32 => write!(out, "int32_t"),
+        I64 => write!(out, "int64_t"),
+        Isize => write!(out, "::rust::isize"),
+        F32 => write!(out, "float"),
+        F64 => write!(out, "double"),
+        CxxString => write!(out, "::std::string"),
+        RustString => write!(out, "::rust::String"),
+    }
+}
+
 fn write_type_space(out: &mut OutFile, ty: &Type) {
     write_type(out, ty);
     write_space_after_type(out, ty);
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index 9457229..d4e96fc 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -44,7 +44,7 @@
         fn c_return_ref_rust_vec(c: &C) -> &Vec<u8>;
         fn c_return_identity(_: usize) -> usize;
         fn c_return_sum(_: usize, _: usize) -> usize;
-        fn c_return_enum(n: u32) -> Enum;
+        fn c_return_enum(n: u16) -> Enum;
 
         fn c_take_primitive(n: usize);
         fn c_take_shared(shared: Shared);
@@ -89,6 +89,7 @@
         type COwnedEnum;
     }
 
+    #[repr(u32)]
     enum COwnedEnum {
         CVal1,
         CVal2,
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index 21637d8..af7a4a0 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -107,10 +107,10 @@
 
 size_t c_return_sum(size_t n1, size_t n2) { return n1 + n2; }
 
-Enum c_return_enum(uint32_t n) {
-  if (n <= static_cast<uint32_t>(Enum::AVal)) {
+Enum c_return_enum(uint16_t n) {
+  if (n <= static_cast<uint16_t>(Enum::AVal)) {
     return Enum::AVal;
-  } else if (n <= static_cast<uint32_t>(Enum::BVal)) {
+  } else if (n <= static_cast<uint16_t>(Enum::BVal)) {
     return Enum::BVal;
   } else {
     return Enum::CVal;
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index 795b4a9..1173a0a 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -7,7 +7,7 @@
 
 struct R;
 struct Shared;
-enum class Enum : uint32_t;
+enum class Enum : uint16_t;
 
 class C {
 public:
@@ -46,7 +46,7 @@
 const rust::Vec<uint8_t> &c_return_ref_rust_vec(const C &c);
 size_t c_return_identity(size_t n);
 size_t c_return_sum(size_t n1, size_t n2);
-Enum c_return_enum(uint32_t n);
+Enum c_return_enum(uint16_t n);
 
 void c_take_primitive(size_t n);
 void c_take_shared(Shared shared);