Skip to content

Commit eb0ac1a

Browse files
authored
Merge pull request #94 from dtolnay/uniquenew
Do not emit UniquePtr::new for opaque C types
2 parents b1637ad + 5383891 commit eb0ac1a

File tree

3 files changed

+43
-25
lines changed

3 files changed

+43
-25
lines changed

gen/write.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ fn write_generic_instantiations(out: &mut OutFile, types: &Types) {
766766
if let Type::Ident(inner) = &ptr.inner {
767767
if allow_unique_ptr(inner) {
768768
out.next_section();
769-
write_unique_ptr(out, inner);
769+
write_unique_ptr(out, inner, types);
770770
}
771771
}
772772
}
@@ -830,7 +830,7 @@ fn write_rust_box_impl(out: &mut OutFile, ident: &Ident) {
830830
writeln!(out, "}}");
831831
}
832832

833-
fn write_unique_ptr(out: &mut OutFile, ident: &Ident) {
833+
fn write_unique_ptr(out: &mut OutFile, ident: &Ident, types: &Types) {
834834
out.include.utility = true;
835835

836836
let mut inner = String::new();
@@ -860,17 +860,19 @@ fn write_unique_ptr(out: &mut OutFile, ident: &Ident) {
860860
);
861861
writeln!(out, " new (ptr) ::std::unique_ptr<{}>();", inner);
862862
writeln!(out, "}}");
863-
writeln!(
864-
out,
865-
"void cxxbridge02$unique_ptr${}$new(::std::unique_ptr<{}> *ptr, {} *value) noexcept {{",
866-
instance, inner, inner,
867-
);
868-
writeln!(
869-
out,
870-
" new (ptr) ::std::unique_ptr<{}>(new {}(::std::move(*value)));",
871-
inner, inner,
872-
);
873-
writeln!(out, "}}");
863+
if types.structs.contains_key(ident) {
864+
writeln!(
865+
out,
866+
"void cxxbridge02$unique_ptr${}$new(::std::unique_ptr<{}> *ptr, {} *value) noexcept {{",
867+
instance, inner, inner,
868+
);
869+
writeln!(
870+
out,
871+
" new (ptr) ::std::unique_ptr<{}>(new {}(::std::move(*value)));",
872+
inner, inner,
873+
);
874+
writeln!(out, "}}");
875+
}
874876
writeln!(
875877
out,
876878
"void cxxbridge02$unique_ptr${}$raw(::std::unique_ptr<{}> *ptr, {} *raw) noexcept {{",

macro/src/expand.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub fn bridge(namespace: &Namespace, ffi: ItemMod) -> Result<TokenStream> {
5757
} else if let Type::UniquePtr(ptr) = ty {
5858
if let Type::Ident(ident) = &ptr.inner {
5959
if Atom::from(ident).is_none() {
60-
expanded.extend(expand_unique_ptr(namespace, ident));
60+
expanded.extend(expand_unique_ptr(namespace, ident, types));
6161
}
6262
}
6363
}
@@ -474,7 +474,7 @@ fn expand_rust_box(namespace: &Namespace, ident: &Ident) -> TokenStream {
474474
}
475475
}
476476

477-
fn expand_unique_ptr(namespace: &Namespace, ident: &Ident) -> TokenStream {
477+
fn expand_unique_ptr(namespace: &Namespace, ident: &Ident, types: &Types) -> TokenStream {
478478
let prefix = format!("cxxbridge02$unique_ptr${}{}$", namespace, ident);
479479
let link_null = format!("{}null", prefix);
480480
let link_new = format!("{}new", prefix);
@@ -483,6 +483,22 @@ fn expand_unique_ptr(namespace: &Namespace, ident: &Ident) -> TokenStream {
483483
let link_release = format!("{}release", prefix);
484484
let link_drop = format!("{}drop", prefix);
485485

486+
let new_method = if types.structs.contains_key(ident) {
487+
Some(quote! {
488+
fn __new(mut value: Self) -> *mut ::std::ffi::c_void {
489+
extern "C" {
490+
#[link_name = #link_new]
491+
fn __new(this: *mut *mut ::std::ffi::c_void, value: *mut #ident);
492+
}
493+
let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
494+
unsafe { __new(&mut repr, &mut value) }
495+
repr
496+
}
497+
})
498+
} else {
499+
None
500+
};
501+
486502
quote! {
487503
unsafe impl ::cxx::private::UniquePtrTarget for #ident {
488504
fn __null() -> *mut ::std::ffi::c_void {
@@ -494,15 +510,7 @@ fn expand_unique_ptr(namespace: &Namespace, ident: &Ident) -> TokenStream {
494510
unsafe { __null(&mut repr) }
495511
repr
496512
}
497-
fn __new(mut value: Self) -> *mut ::std::ffi::c_void {
498-
extern "C" {
499-
#[link_name = #link_new]
500-
fn __new(this: *mut *mut ::std::ffi::c_void, value: *mut #ident);
501-
}
502-
let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
503-
unsafe { __new(&mut repr, &mut value) }
504-
repr
505-
}
513+
#new_method
506514
unsafe fn __raw(raw: *mut Self) -> *mut ::std::ffi::c_void {
507515
extern "C" {
508516
#[link_name = #link_raw]

src/unique_ptr.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,15 @@ pub unsafe trait UniquePtrTarget {
118118
#[doc(hidden)]
119119
fn __null() -> *mut c_void;
120120
#[doc(hidden)]
121-
fn __new(value: Self) -> *mut c_void;
121+
fn __new(value: Self) -> *mut c_void
122+
where
123+
Self: Sized,
124+
{
125+
// Opaque C types do not get this method because they can never exist by
126+
// value on the Rust side of the bridge.
127+
let _ = value;
128+
unreachable!()
129+
}
122130
#[doc(hidden)]
123131
unsafe fn __raw(raw: *mut Self) -> *mut c_void;
124132
#[doc(hidden)]

0 commit comments

Comments
 (0)