Skip to content

Commit

Permalink
Merge pull request #94 from dtolnay/uniquenew
Browse files Browse the repository at this point in the history
Do not emit UniquePtr::new for opaque C types
  • Loading branch information
dtolnay authored Apr 10, 2020
2 parents b1637ad + 5383891 commit eb0ac1a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 25 deletions.
28 changes: 15 additions & 13 deletions gen/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ fn write_generic_instantiations(out: &mut OutFile, types: &Types) {
if let Type::Ident(inner) = &ptr.inner {
if allow_unique_ptr(inner) {
out.next_section();
write_unique_ptr(out, inner);
write_unique_ptr(out, inner, types);
}
}
}
Expand Down Expand Up @@ -830,7 +830,7 @@ fn write_rust_box_impl(out: &mut OutFile, ident: &Ident) {
writeln!(out, "}}");
}

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

let mut inner = String::new();
Expand Down Expand Up @@ -860,17 +860,19 @@ fn write_unique_ptr(out: &mut OutFile, ident: &Ident) {
);
writeln!(out, " new (ptr) ::std::unique_ptr<{}>();", inner);
writeln!(out, "}}");
writeln!(
out,
"void cxxbridge02$unique_ptr${}$new(::std::unique_ptr<{}> *ptr, {} *value) noexcept {{",
instance, inner, inner,
);
writeln!(
out,
" new (ptr) ::std::unique_ptr<{}>(new {}(::std::move(*value)));",
inner, inner,
);
writeln!(out, "}}");
if types.structs.contains_key(ident) {
writeln!(
out,
"void cxxbridge02$unique_ptr${}$new(::std::unique_ptr<{}> *ptr, {} *value) noexcept {{",
instance, inner, inner,
);
writeln!(
out,
" new (ptr) ::std::unique_ptr<{}>(new {}(::std::move(*value)));",
inner, inner,
);
writeln!(out, "}}");
}
writeln!(
out,
"void cxxbridge02$unique_ptr${}$raw(::std::unique_ptr<{}> *ptr, {} *raw) noexcept {{",
Expand Down
30 changes: 19 additions & 11 deletions macro/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn bridge(namespace: &Namespace, ffi: ItemMod) -> Result<TokenStream> {
} else if let Type::UniquePtr(ptr) = ty {
if let Type::Ident(ident) = &ptr.inner {
if Atom::from(ident).is_none() {
expanded.extend(expand_unique_ptr(namespace, ident));
expanded.extend(expand_unique_ptr(namespace, ident, types));
}
}
}
Expand Down Expand Up @@ -474,7 +474,7 @@ fn expand_rust_box(namespace: &Namespace, ident: &Ident) -> TokenStream {
}
}

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

let new_method = if types.structs.contains_key(ident) {
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);
}
let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
unsafe { __new(&mut repr, &mut value) }
repr
}
})
} else {
None
};

quote! {
unsafe impl ::cxx::private::UniquePtrTarget for #ident {
fn __null() -> *mut ::std::ffi::c_void {
Expand All @@ -494,15 +510,7 @@ fn expand_unique_ptr(namespace: &Namespace, ident: &Ident) -> TokenStream {
unsafe { __null(&mut repr) }
repr
}
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);
}
let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
unsafe { __new(&mut repr, &mut value) }
repr
}
#new_method
unsafe fn __raw(raw: *mut Self) -> *mut ::std::ffi::c_void {
extern "C" {
#[link_name = #link_raw]
Expand Down
10 changes: 9 additions & 1 deletion src/unique_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ pub unsafe trait UniquePtrTarget {
#[doc(hidden)]
fn __null() -> *mut c_void;
#[doc(hidden)]
fn __new(value: Self) -> *mut c_void;
fn __new(value: Self) -> *mut c_void
where
Self: Sized,
{
// Opaque C types do not get this method because they can never exist by
// value on the Rust side of the bridge.
let _ = value;
unreachable!()
}
#[doc(hidden)]
unsafe fn __raw(raw: *mut Self) -> *mut c_void;
#[doc(hidden)]
Expand Down

0 comments on commit eb0ac1a

Please sign in to comment.