Handle `self: [&*] Self` as argument rather than just `[*&]self`
authorMatt Corallo <git@bluematt.me>
Thu, 29 Feb 2024 14:55:39 +0000 (14:55 +0000)
committerMatt Corallo <git@bluematt.me>
Thu, 25 Apr 2024 20:52:49 +0000 (20:52 +0000)
c-bindings-gen/src/blocks.rs
c-bindings-gen/src/main.rs

index 664ca44b42414e142d4c5be4893646ebacdacddc..7ee216a6774a2498c46814333760233cf796fc85 100644 (file)
@@ -540,22 +540,32 @@ pub fn write_method_params<W: std::io::Write>(w: &mut W, sig: &syn::Signature, t
        let mut first_arg = true;
        let mut num_unused = 0;
        for inp in sig.inputs.iter() {
+               let mut handle_self = |is_ref: bool, is_mut: bool| {
+                       write!(w, "{}this_arg: {}{}", if !is_ref { "mut " } else { "" },
+                               if is_ref {
+                                       match (self_ptr, is_mut) {
+                                               (true, true) => "*mut ",
+                                               (true, false) => "*const ",
+                                               (false, true) => "&mut ",
+                                               (false, false) => "&",
+                                       }
+                               } else { "" }, this_param).unwrap();
+                       assert!(first_arg);
+                       first_arg = false;
+               };
                match inp {
                        syn::FnArg::Receiver(recv) => {
                                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;
+                               handle_self(recv.reference.is_some(), recv.mutability.is_some());
                        },
                        syn::FnArg::Typed(arg) => {
+                               if let syn::Pat::Ident(id) = &*arg.pat {
+                                       if format!("{}", id.ident) == "self" {
+                                               handle_self(id.by_ref.is_some(), id.mutability.is_some());
+                                               continue;
+                                       }
+                               }
+
                                if types.skip_arg(&*arg.ty, generics) { continue; }
                                if !arg.attrs.is_empty() { unimplemented!(); }
                                // First get the c type so that we can check if it ends up being a reference:
@@ -606,6 +616,12 @@ pub fn write_method_var_decl_body<W: std::io::Write>(w: &mut W, sig: &syn::Signa
                match inp {
                        syn::FnArg::Receiver(_) => {},
                        syn::FnArg::Typed(arg) => {
+                               if let syn::Pat::Ident(id) = &*arg.pat {
+                                       if format!("{}", id.ident) == "self" {
+                                               continue;
+                                       }
+                               }
+
                                if types.skip_arg(&*arg.ty, generics) { continue; }
                                if !arg.attrs.is_empty() { unimplemented!(); }
                                macro_rules! write_new_var {
@@ -666,6 +682,17 @@ pub fn write_method_call_params<W: std::io::Write>(w: &mut W, sig: &syn::Signatu
                                }
                        },
                        syn::FnArg::Typed(arg) => {
+                               if let syn::Pat::Ident(id) = &*arg.pat {
+                                       if format!("{}", id.ident) == "self" {
+                                               if to_c {
+                                                       if id.by_ref.is_none() && !matches!(&*arg.ty, syn::Type::Reference(_)) { unimplemented!(); }
+                                                       write!(w, "self.this_arg").unwrap();
+                                                       first_arg = false;
+                                               }
+                                               continue;
+                                       }
+                               }
+
                                if types.skip_arg(&*arg.ty, generics) {
                                        if !to_c {
                                                if !first_arg {
index 4572f7d921d405256d67b50d7616cacf8461aa7f..358e30beead1b34e5ee04f1bda1dbac56cf1b11d 100644 (file)
@@ -1185,8 +1185,19 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, w_uses: &mut HashSet<String, NonRa
                                                                        write_method_var_decl_body(w, &$trait_meth.sig, "", &mut trait_resolver, Some(&meth_gen_types), false);
                                                                        let mut takes_self = false;
                                                                        for inp in $m.sig.inputs.iter() {
-                                                                               if let syn::FnArg::Receiver(_) = inp {
-                                                                                       takes_self = true;
+                                                                               match inp {
+                                                                                       syn::FnArg::Receiver(_) => {
+                                                                                               takes_self = true;
+                                                                                               break;
+                                                                                       },
+                                                                                       syn::FnArg::Typed(ty) => {
+                                                                                               if let syn::Pat::Ident(id) = &*ty.pat {
+                                                                                                       if format!("{}", id.ident) == "self" {
+                                                                                                               takes_self = true;
+                                                                                                               break;
+                                                                                                       }
+                                                                                               }
+                                                                                       }
                                                                                }
                                                                        }
 
@@ -1456,10 +1467,23 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, w_uses: &mut HashSet<String, NonRa
                                                                        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; }
+                                                                               match inp {
+                                                                                       syn::FnArg::Receiver(r) => {
+                                                                                               takes_self = true;
+                                                                                               if r.mutability.is_some() { takes_mut_self = true; }
+                                                                                               if r.reference.is_none() { takes_owned_self = true; }
+                                                                                               break;
+                                                                                       },
+                                                                                       syn::FnArg::Typed(ty) => {
+                                                                                               if let syn::Pat::Ident(id) = &*ty.pat {
+                                                                                                       if format!("{}", id.ident) == "self" {
+                                                                                                               takes_self = true;
+                                                                                                               if id.mutability.is_some() { takes_mut_self = true; }
+                                                                                                               if id.by_ref.is_none() { takes_owned_self = true; }
+                                                                                                               break;
+                                                                                                       }
+                                                                                               }
+                                                                                       }
                                                                                }
                                                                        }
                                                                        if !takes_mut_self && !takes_self {