Skip a move construction on Unique/SharedPtr::new
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 26da9e4..77bff8d 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1520,16 +1520,19 @@
writeln!(out, " new (ptr) ::std::unique_ptr<{}>();", inner);
writeln!(out, "}}");
if can_construct_from_value {
+ out.builtin.maybe_uninit = true;
writeln!(
out,
- "void cxxbridge1$unique_ptr${}$new(::std::unique_ptr<{}> *ptr, {} *value) noexcept {{",
- instance, inner, inner,
+ "{} *cxxbridge1$unique_ptr${}$uninit(::std::unique_ptr<{}> *ptr) noexcept {{",
+ inner, instance, inner,
);
writeln!(
out,
- " new (ptr) ::std::unique_ptr<{}>(new {}(::std::move(*value)));",
- inner, inner,
+ " {} *uninit = reinterpret_cast<{} *>(new ::rust::MaybeUninit<{}>);",
+ inner, inner, inner,
);
+ writeln!(out, " new (ptr) ::std::unique_ptr<{}>(uninit);", inner);
+ writeln!(out, " return uninit;");
writeln!(out, "}}");
}
writeln!(
@@ -1615,16 +1618,19 @@
writeln!(out, " new (ptr) ::std::shared_ptr<{}>();", inner);
writeln!(out, "}}");
if can_construct_from_value {
+ out.builtin.maybe_uninit = true;
writeln!(
out,
- "void cxxbridge1$shared_ptr${}$new(::std::shared_ptr<{}> *ptr, {} *value) noexcept {{",
- instance, inner, inner,
+ "{} *cxxbridge1$shared_ptr${}$uninit(::std::shared_ptr<{}> *ptr) noexcept {{",
+ inner, instance, inner,
);
writeln!(
out,
- " new (ptr) ::std::shared_ptr<{}>(new {}(::std::move(*value)));",
- inner, inner,
+ " {} *uninit = reinterpret_cast<{} *>(new ::rust::MaybeUninit<{}>);",
+ inner, inner, inner,
);
+ writeln!(out, " new (ptr) ::std::shared_ptr<{}>(uninit);", inner);
+ writeln!(out, " return uninit;");
writeln!(out, "}}");
}
writeln!(
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index a94625a..9f16e5e 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -1041,7 +1041,7 @@
let name = ident.rust.to_string();
let prefix = format!("cxxbridge1$unique_ptr${}$", ident.to_symbol(types));
let link_null = format!("{}null", prefix);
- let link_new = format!("{}new", prefix);
+ let link_uninit = format!("{}uninit", prefix);
let link_raw = format!("{}raw", prefix);
let link_get = format!("{}get", prefix);
let link_release = format!("{}release", prefix);
@@ -1054,11 +1054,11 @@
Some(quote! {
fn __new(mut value: Self) -> *mut ::std::ffi::c_void {
extern "C" {
- #[link_name = #link_new]
- fn __new(this: *mut *mut ::std::ffi::c_void, value: *mut #ident);
+ #[link_name = #link_uninit]
+ fn __uninit(this: *mut *mut ::std::ffi::c_void) -> *mut ::std::ffi::c_void;
}
let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
- unsafe { __new(&mut repr, &mut value) }
+ unsafe { __uninit(&mut repr).cast::<#ident>().write(value) }
repr
}
})
@@ -1126,7 +1126,7 @@
let name = ident.rust.to_string();
let prefix = format!("cxxbridge1$shared_ptr${}$", ident.to_symbol(types));
let link_null = format!("{}null", prefix);
- let link_new = format!("{}new", prefix);
+ let link_uninit = format!("{}uninit", prefix);
let link_clone = format!("{}clone", prefix);
let link_get = format!("{}get", prefix);
let link_drop = format!("{}drop", prefix);
@@ -1138,10 +1138,10 @@
Some(quote! {
unsafe fn __new(mut value: Self, new: *mut ::std::ffi::c_void) {
extern "C" {
- #[link_name = #link_new]
- fn __new(new: *mut ::std::ffi::c_void, value: *mut ::std::ffi::c_void);
+ #[link_name = #link_uninit]
+ fn __uninit(new: *mut ::std::ffi::c_void) -> *mut ::std::ffi::c_void;
}
- __new(new, &mut value as *mut Self as *mut ::std::ffi::c_void);
+ __uninit(new).cast::<#ident>().write(value);
}
})
} else {