Fix alignment of by-value returns from Rust
diff --git a/gen/write.rs b/gen/write.rs
index 187bf5e..f0bcaf9 100644
--- a/gen/write.rs
+++ b/gen/write.rs
@@ -105,12 +105,18 @@
     }
 
     let mut needs_manually_drop = false;
-    'outer: for api in apis {
+    let mut needs_maybe_uninit = false;
+    for api in apis {
         if let Api::RustFunction(efn) = api {
             for arg in &efn.args {
                 if arg.ty != RustString && types.needs_indirect_abi(&arg.ty) {
                     needs_manually_drop = true;
-                    break 'outer;
+                    break;
+                }
+            }
+            if let Some(ret) = &efn.ret {
+                if types.needs_indirect_abi(ret) {
+                    needs_maybe_uninit = true;
                 }
             }
         }
@@ -119,7 +125,7 @@
     out.begin_block("namespace rust");
     out.begin_block("inline namespace cxxbridge01");
 
-    if needs_rust_box || needs_manually_drop {
+    if needs_rust_box || needs_manually_drop || needs_maybe_uninit {
         writeln!(out, "// #include \"cxxbridge.h\"");
     }
 
@@ -145,6 +151,16 @@
         writeln!(out, "}};");
     }
 
+    if needs_maybe_uninit {
+        out.next_section();
+        writeln!(out, "template <typename T>");
+        writeln!(out, "union MaybeUninit {{");
+        writeln!(out, "  T value;");
+        writeln!(out, "  MaybeUninit() {{}}");
+        writeln!(out, "  ~MaybeUninit() {{}}");
+        writeln!(out, "}};");
+    }
+
     out.end_block("namespace cxxbridge01");
     out.end_block("namespace rust");
 }
@@ -314,9 +330,9 @@
         }
         write!(out, "  ");
         if indirect_return {
-            write!(out, "char return$[sizeof(");
+            write!(out, "::rust::MaybeUninit<");
             write_type(out, efn.ret.as_ref().unwrap());
-            writeln!(out, ")];");
+            writeln!(out, "> return$;");
             write!(out, "  ");
         } else if let Some(ret) = &efn.ret {
             write!(out, "return ");
@@ -350,17 +366,11 @@
             if !efn.args.is_empty() {
                 write!(out, ", ");
             }
-            write!(out, "reinterpret_cast<");
-            write_return_type(out, &efn.ret);
-            write!(out, "*>(return$)");
+            write!(out, "&return$.value");
         }
         writeln!(out, ");");
         if indirect_return {
-            write!(out, "  return ");
-            write_type(out, efn.ret.as_ref().unwrap());
-            write!(out, "(*reinterpret_cast<");
-            write_return_type(out, &efn.ret);
-            writeln!(out, "*>(return$));");
+            writeln!(out, "  return ::std::move(return$.value);");
         }
         writeln!(out, "}}");
     }