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, "}}");
}