Support taking an owned Self in function exports
authorMatt Corallo <git@bluematt.me>
Sun, 18 Apr 2021 18:10:39 +0000 (18:10 +0000)
committerMatt Corallo <git@bluematt.me>
Thu, 29 Apr 2021 18:59:50 +0000 (18:59 +0000)
c-bindings-gen/src/blocks.rs
c-bindings-gen/src/main.rs

index 2c51572a9378150fdc861c12c5c9e3edec11c7aa..28323498336c750d97abe45e899d282a3042265a 100644 (file)
@@ -442,14 +442,16 @@ pub fn write_method_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, t
        for inp in sig.inputs.iter() {
                match inp {
                        syn::FnArg::Receiver(recv) => {
-                               if !recv.attrs.is_empty() || recv.reference.is_none() { unimplemented!(); }
-                               write!(w, "this_arg: {}{}",
-                                       match (self_ptr, recv.mutability.is_some()) {
-                                               (true, true) => "*mut ",
-                                               (true, false) => "*const ",
-                                               (false, true) => "&mut ",
-                                               (false, false) => "&",
-                                       }, this_param).unwrap();
+                               if !recv.attrs.is_empty() { unimplemented!(); }
+                               write!(w, "{}this_arg: {}{}", if recv.reference.is_none() { "mut " } else { "" },
+                                       if recv.reference.is_some() {
+                                               match (self_ptr, recv.mutability.is_some()) {
+                                                       (true, true) => "*mut ",
+                                                       (true, false) => "*const ",
+                                                       (false, true) => "&mut ",
+                                                       (false, false) => "&",
+                                               }
+                                       } else { "" }, this_param).unwrap();
                                assert!(first_arg);
                                first_arg = false;
                        },
@@ -556,8 +558,9 @@ pub fn write_method_call_params<W: std::io::Write>(w: &mut W, sig: &syn::Signatu
        for inp in sig.inputs.iter() {
                match inp {
                        syn::FnArg::Receiver(recv) => {
-                               if !recv.attrs.is_empty() || recv.reference.is_none() { unimplemented!(); }
+                               if !recv.attrs.is_empty() { unimplemented!(); }
                                if to_c {
+                                       if recv.reference.is_none() { unimplemented!(); }
                                        write!(w, "self.this_arg").unwrap();
                                        first_arg = false;
                                }
index 149ae76791a9c82b94355535269e4eb5ba33d31f..75b537c7022c49b47bbd7ce43c650f4ec10da09a 100644 (file)
@@ -987,10 +987,12 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        write_method_var_decl_body(w, &m.sig, "", types, Some(&meth_gen_types), false);
                                                                        let mut takes_self = false;
                                                                        let mut takes_mut_self = false;
+                                                                       let mut takes_owned_self = false;
                                                                        for inp in m.sig.inputs.iter() {
                                                                                if let syn::FnArg::Receiver(r) = inp {
                                                                                        takes_self = true;
                                                                                        if r.mutability.is_some() { takes_mut_self = true; }
+                                                                                       if r.reference.is_none() { takes_owned_self = true; }
                                                                                }
                                                                        }
                                                                        if !takes_mut_self && !takes_self {
@@ -999,7 +1001,9 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                                match &declared_type {
                                                                                        DeclType::MirroredEnum => write!(w, "this_arg.to_native().{}(", m.sig.ident).unwrap(),
                                                                                        DeclType::StructImported => {
-                                                                                               if takes_mut_self {
+                                                                                               if takes_owned_self {
+                                                                                                       write!(w, "(*unsafe {{ Box::from_raw(this_arg.take_inner()) }}).{}(", m.sig.ident).unwrap();
+                                                                                               } else if takes_mut_self {
                                                                                                        write!(w, "unsafe {{ &mut (*(this_arg.inner as *mut native{})) }}.{}(", ident, m.sig.ident).unwrap();
                                                                                                } else {
                                                                                                        write!(w, "unsafe {{ &*this_arg.inner }}.{}(", m.sig.ident).unwrap();