From 46764bbe725a54d92e8cd8f566db3e65bb821c5e Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Tue, 11 Feb 2025 05:59:20 +0300 Subject: [PATCH 1/8] Fixed handling of trait methods containing the unsafe attribute --- src/bindgen/utilities.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bindgen/utilities.rs b/src/bindgen/utilities.rs index 28ae7838..f4058313 100644 --- a/src/bindgen/utilities.rs +++ b/src/bindgen/utilities.rs @@ -50,6 +50,7 @@ impl SynItemHelpers for syn::ImplItemFn { fn exported_name(&self) -> Option { self.attrs .attr_name_value_lookup("export_name") + .or_else(|| self.unsafe_attr_name_value_lookup("export_name")) .or_else(|| { if self.is_no_mangle() { Some(self.sig.ident.unraw().to_string()) From 6f8fa31e48202098d34f8ed7072777252416db2d Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Wed, 12 Feb 2025 14:11:51 +0300 Subject: [PATCH 2/8] Added tests for unsafe methotd's atributs --- .../impl_unsafe_attr_method.c.sym | 3 +++ tests/expectations/impl_unsafe_attr_method.c | 10 ++++++++++ .../impl_unsafe_attr_method.compat.c | 18 ++++++++++++++++++ tests/expectations/impl_unsafe_attr_method.cpp | 15 +++++++++++++++ tests/expectations/impl_unsafe_attr_method.pyx | 12 ++++++++++++ .../impl_unsafe_attr_method_both.c | 10 ++++++++++ .../impl_unsafe_attr_method_both.compat.c | 18 ++++++++++++++++++ .../expectations/impl_unsafe_attr_method_tag.c | 10 ++++++++++ .../impl_unsafe_attr_method_tag.compat.c | 18 ++++++++++++++++++ .../impl_unsafe_attr_method_tag.pyx | 12 ++++++++++++ tests/rust/impl_unsafe_attr_method.rs | 14 ++++++++++++++ 11 files changed, 140 insertions(+) create mode 100644 tests/expectations-symbols/impl_unsafe_attr_method.c.sym create mode 100644 tests/expectations/impl_unsafe_attr_method.c create mode 100644 tests/expectations/impl_unsafe_attr_method.compat.c create mode 100644 tests/expectations/impl_unsafe_attr_method.cpp create mode 100644 tests/expectations/impl_unsafe_attr_method.pyx create mode 100644 tests/expectations/impl_unsafe_attr_method_both.c create mode 100644 tests/expectations/impl_unsafe_attr_method_both.compat.c create mode 100644 tests/expectations/impl_unsafe_attr_method_tag.c create mode 100644 tests/expectations/impl_unsafe_attr_method_tag.compat.c create mode 100644 tests/expectations/impl_unsafe_attr_method_tag.pyx create mode 100644 tests/rust/impl_unsafe_attr_method.rs diff --git a/tests/expectations-symbols/impl_unsafe_attr_method.c.sym b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym new file mode 100644 index 00000000..6feb48ef --- /dev/null +++ b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym @@ -0,0 +1,3 @@ +{ +new_dummy; +}; \ No newline at end of file diff --git a/tests/expectations/impl_unsafe_attr_method.c b/tests/expectations/impl_unsafe_attr_method.c new file mode 100644 index 00000000..5e9467c3 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +typedef struct { + int32_t dummy_field; +} DummyStruct; + +DummyStruct new_dummy(void); diff --git a/tests/expectations/impl_unsafe_attr_method.compat.c b/tests/expectations/impl_unsafe_attr_method.compat.c new file mode 100644 index 00000000..26aaf31b --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.compat.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +typedef struct { + int32_t dummy_field; +} DummyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +DummyStruct new_dummy(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method.cpp b/tests/expectations/impl_unsafe_attr_method.cpp new file mode 100644 index 00000000..f1e8ea90 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +extern "C" { + +DummyStruct new_dummy(); + +} // extern "C" diff --git a/tests/expectations/impl_unsafe_attr_method.pyx b/tests/expectations/impl_unsafe_attr_method.pyx new file mode 100644 index 00000000..0d39e71d --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method.pyx @@ -0,0 +1,12 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + ctypedef struct DummyStruct: + int32_t dummy_field; + + DummyStruct new_dummy(); diff --git a/tests/expectations/impl_unsafe_attr_method_both.c b/tests/expectations/impl_unsafe_attr_method_both.c new file mode 100644 index 00000000..175f7f19 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_both.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +typedef struct DummyStruct { + int32_t dummy_field; +} DummyStruct; + +struct DummyStruct new_dummy(void); diff --git a/tests/expectations/impl_unsafe_attr_method_both.compat.c b/tests/expectations/impl_unsafe_attr_method_both.compat.c new file mode 100644 index 00000000..ca5396ec --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_both.compat.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +typedef struct DummyStruct { + int32_t dummy_field; +} DummyStruct; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct DummyStruct new_dummy(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.c b/tests/expectations/impl_unsafe_attr_method_tag.c new file mode 100644 index 00000000..31492fd5 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.c @@ -0,0 +1,10 @@ +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +struct DummyStruct new_dummy(void); diff --git a/tests/expectations/impl_unsafe_attr_method_tag.compat.c b/tests/expectations/impl_unsafe_attr_method_tag.compat.c new file mode 100644 index 00000000..16a8962a --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.compat.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +struct DummyStruct { + int32_t dummy_field; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct DummyStruct new_dummy(void); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.pyx b/tests/expectations/impl_unsafe_attr_method_tag.pyx new file mode 100644 index 00000000..2ef4bd85 --- /dev/null +++ b/tests/expectations/impl_unsafe_attr_method_tag.pyx @@ -0,0 +1,12 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + cdef struct DummyStruct: + int32_t dummy_field; + + DummyStruct new_dummy(); diff --git a/tests/rust/impl_unsafe_attr_method.rs b/tests/rust/impl_unsafe_attr_method.rs new file mode 100644 index 00000000..4ab7e8c0 --- /dev/null +++ b/tests/rust/impl_unsafe_attr_method.rs @@ -0,0 +1,14 @@ +#[repr(C)] +pub struct DummyStruct { + dummy_field: i32, +} + + +impl DummyStruct { + #[unsafe(export_name = "new_dummy")] + pub const extern "C" fn new() -> Self { + Self { + dummy_field: 0, + } + } +} From 602172d0db4315372f1ad84a12db96dbf753f1b6 Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Wed, 12 Feb 2025 14:18:52 +0300 Subject: [PATCH 3/8] Added test for unsafe(no_mangle) attribute --- tests/expectations-symbols/impl_unsafe_attr_method.c.sym | 1 + tests/expectations/impl_unsafe_attr_method.c | 2 ++ tests/expectations/impl_unsafe_attr_method.compat.c | 2 ++ tests/expectations/impl_unsafe_attr_method.cpp | 2 ++ tests/expectations/impl_unsafe_attr_method.pyx | 2 ++ tests/expectations/impl_unsafe_attr_method_both.c | 2 ++ tests/expectations/impl_unsafe_attr_method_both.compat.c | 2 ++ tests/expectations/impl_unsafe_attr_method_tag.c | 2 ++ tests/expectations/impl_unsafe_attr_method_tag.compat.c | 2 ++ tests/expectations/impl_unsafe_attr_method_tag.pyx | 2 ++ tests/rust/impl_unsafe_attr_method.rs | 7 +++++++ 11 files changed, 26 insertions(+) diff --git a/tests/expectations-symbols/impl_unsafe_attr_method.c.sym b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym index 6feb48ef..271f7251 100644 --- a/tests/expectations-symbols/impl_unsafe_attr_method.c.sym +++ b/tests/expectations-symbols/impl_unsafe_attr_method.c.sym @@ -1,3 +1,4 @@ { new_dummy; +new_dummy_param; }; \ No newline at end of file diff --git a/tests/expectations/impl_unsafe_attr_method.c b/tests/expectations/impl_unsafe_attr_method.c index 5e9467c3..822c4cea 100644 --- a/tests/expectations/impl_unsafe_attr_method.c +++ b/tests/expectations/impl_unsafe_attr_method.c @@ -8,3 +8,5 @@ typedef struct { } DummyStruct; DummyStruct new_dummy(void); + +DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method.compat.c b/tests/expectations/impl_unsafe_attr_method.compat.c index 26aaf31b..a4752756 100644 --- a/tests/expectations/impl_unsafe_attr_method.compat.c +++ b/tests/expectations/impl_unsafe_attr_method.compat.c @@ -13,6 +13,8 @@ extern "C" { DummyStruct new_dummy(void); +DummyStruct new_dummy_param(int32_t dummy_field); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method.cpp b/tests/expectations/impl_unsafe_attr_method.cpp index f1e8ea90..1f12ee89 100644 --- a/tests/expectations/impl_unsafe_attr_method.cpp +++ b/tests/expectations/impl_unsafe_attr_method.cpp @@ -12,4 +12,6 @@ extern "C" { DummyStruct new_dummy(); +DummyStruct new_dummy_param(int32_t dummy_field); + } // extern "C" diff --git a/tests/expectations/impl_unsafe_attr_method.pyx b/tests/expectations/impl_unsafe_attr_method.pyx index 0d39e71d..c502b519 100644 --- a/tests/expectations/impl_unsafe_attr_method.pyx +++ b/tests/expectations/impl_unsafe_attr_method.pyx @@ -10,3 +10,5 @@ cdef extern from *: int32_t dummy_field; DummyStruct new_dummy(); + + DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_both.c b/tests/expectations/impl_unsafe_attr_method_both.c index 175f7f19..9c6a0d7d 100644 --- a/tests/expectations/impl_unsafe_attr_method_both.c +++ b/tests/expectations/impl_unsafe_attr_method_both.c @@ -8,3 +8,5 @@ typedef struct DummyStruct { } DummyStruct; struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_both.compat.c b/tests/expectations/impl_unsafe_attr_method_both.compat.c index ca5396ec..c933e17d 100644 --- a/tests/expectations/impl_unsafe_attr_method_both.compat.c +++ b/tests/expectations/impl_unsafe_attr_method_both.compat.c @@ -13,6 +13,8 @@ extern "C" { struct DummyStruct new_dummy(void); +struct DummyStruct new_dummy_param(int32_t dummy_field); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.c b/tests/expectations/impl_unsafe_attr_method_tag.c index 31492fd5..d0db9853 100644 --- a/tests/expectations/impl_unsafe_attr_method_tag.c +++ b/tests/expectations/impl_unsafe_attr_method_tag.c @@ -8,3 +8,5 @@ struct DummyStruct { }; struct DummyStruct new_dummy(void); + +struct DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/expectations/impl_unsafe_attr_method_tag.compat.c b/tests/expectations/impl_unsafe_attr_method_tag.compat.c index 16a8962a..40e53fa8 100644 --- a/tests/expectations/impl_unsafe_attr_method_tag.compat.c +++ b/tests/expectations/impl_unsafe_attr_method_tag.compat.c @@ -13,6 +13,8 @@ extern "C" { struct DummyStruct new_dummy(void); +struct DummyStruct new_dummy_param(int32_t dummy_field); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/tests/expectations/impl_unsafe_attr_method_tag.pyx b/tests/expectations/impl_unsafe_attr_method_tag.pyx index 2ef4bd85..23c9f172 100644 --- a/tests/expectations/impl_unsafe_attr_method_tag.pyx +++ b/tests/expectations/impl_unsafe_attr_method_tag.pyx @@ -10,3 +10,5 @@ cdef extern from *: int32_t dummy_field; DummyStruct new_dummy(); + + DummyStruct new_dummy_param(int32_t dummy_field); diff --git a/tests/rust/impl_unsafe_attr_method.rs b/tests/rust/impl_unsafe_attr_method.rs index 4ab7e8c0..4f604bfb 100644 --- a/tests/rust/impl_unsafe_attr_method.rs +++ b/tests/rust/impl_unsafe_attr_method.rs @@ -11,4 +11,11 @@ impl DummyStruct { dummy_field: 0, } } + + #[unsafe(no_mangle)] + pub extern "C" fn new_dummy_param(dummy_field: i32) -> Self { + Self { + dummy_field, + } + } } From d3252cfd4627a13ff0dd49cf92157b4043892915 Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Mon, 17 Feb 2025 21:45:33 +0300 Subject: [PATCH 4/8] Added the ability to generate trait methods using types --- src/bindgen/parser.rs | 51 +++++++++++++++++--- tests/expectations-symbols/traits_type.c.sym | 4 ++ tests/expectations/traits_type.c | 16 ++++++ tests/expectations/traits_type.compat.c | 24 +++++++++ tests/expectations/traits_type.cpp | 21 ++++++++ tests/expectations/traits_type.pyx | 17 +++++++ tests/expectations/traits_type_both.c | 16 ++++++ tests/expectations/traits_type_both.compat.c | 24 +++++++++ tests/expectations/traits_type_tag.c | 16 ++++++ tests/expectations/traits_type_tag.compat.c | 24 +++++++++ tests/expectations/traits_type_tag.pyx | 17 +++++++ tests/rust/traits_type.rs | 38 +++++++++++++++ 12 files changed, 260 insertions(+), 8 deletions(-) create mode 100644 tests/expectations-symbols/traits_type.c.sym create mode 100644 tests/expectations/traits_type.c create mode 100644 tests/expectations/traits_type.compat.c create mode 100644 tests/expectations/traits_type.cpp create mode 100644 tests/expectations/traits_type.pyx create mode 100644 tests/expectations/traits_type_both.c create mode 100644 tests/expectations/traits_type_both.compat.c create mode 100644 tests/expectations/traits_type_tag.c create mode 100644 tests/expectations/traits_type_tag.compat.c create mode 100644 tests/expectations/traits_type_tag.pyx create mode 100644 tests/rust/traits_type.rs diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index 13fa3f7e..b3641a90 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -533,13 +533,15 @@ impl Parse { self.load_syn_ty(crate_name, mod_cfg, item); } syn::Item::Impl(ref item_impl) => { - let has_assoc_const = item_impl - .items - .iter() - .any(|item| matches!(item, syn::ImplItem::Const(_))); - if has_assoc_const { - impls_with_assoc_consts.push(item_impl); - } + let mut impls_with_assoc_ty = Vec::new(); + + item_impl.items.iter().for_each(|item| { + if matches!(item, syn::ImplItem::Const(_)) { + impls_with_assoc_consts.push(item_impl); + } else if let syn::ImplItem::Type(t) = item { + impls_with_assoc_ty.push((&t.ident, &t.ty)); + } + }); if let syn::Type::Path(ref path) = *item_impl.self_ty { if let Some(type_name) = path.path.get_ident() { @@ -549,13 +551,46 @@ impl Parse { } _ => None, }) { + let mut method = method.clone(); + let out = match Type::load_from_output(&method.sig.output) { + Ok((out, ..)) => out, + Err(..) => continue, + }; + + for (ident, ty) in &impls_with_assoc_ty { + let ident = ident.to_string(); + + if let (Some(out_name), syn::ReturnType::Type(_, t)) = + (out.get_root_path(), &mut method.sig.output) + { + if ident == out_name.to_string() { + *t = Box::new((*ty).clone()); + } + } + + method.sig.inputs.iter_mut().for_each(|arg| { + if let syn::FnArg::Typed(t) = arg { + let attr_ty = match Type::load(&t.ty) { + Ok(Some(t)) => t, + _ => return, + }; + + if let Some(attr_ty) = attr_ty.get_root_path() { + if ident == attr_ty.to_string() { + t.ty = Box::new((*ty).clone()); + } + } + } + }); + } + self.load_syn_method( config, binding_crate_name, crate_name, mod_cfg, &Path::new(type_name.unraw().to_string()), - method, + &method, ) } } diff --git a/tests/expectations-symbols/traits_type.c.sym b/tests/expectations-symbols/traits_type.c.sym new file mode 100644 index 00000000..ad36d75d --- /dev/null +++ b/tests/expectations-symbols/traits_type.c.sym @@ -0,0 +1,4 @@ +{ +dummy_Dummy0; +dummy_Dummy1; +}; \ No newline at end of file diff --git a/tests/expectations/traits_type.c b/tests/expectations/traits_type.c new file mode 100644 index 00000000..517cc121 --- /dev/null +++ b/tests/expectations/traits_type.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +typedef struct { + uintptr_t dummy; +} Dummy0; + +typedef struct { + uintptr_t dummy; +} Dummy1; + +Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); + +int32_t dummy_Dummy1(Dummy1 self); diff --git a/tests/expectations/traits_type.compat.c b/tests/expectations/traits_type.compat.c new file mode 100644 index 00000000..de8f43e9 --- /dev/null +++ b/tests/expectations/traits_type.compat.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +typedef struct { + uintptr_t dummy; +} Dummy0; + +typedef struct { + uintptr_t dummy; +} Dummy1; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); + +int32_t dummy_Dummy1(Dummy1 self); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/traits_type.cpp b/tests/expectations/traits_type.cpp new file mode 100644 index 00000000..891c0c6b --- /dev/null +++ b/tests/expectations/traits_type.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +struct Dummy0 { + uintptr_t dummy; +}; + +struct Dummy1 { + uintptr_t dummy; +}; + +extern "C" { + +Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); + +int32_t dummy_Dummy1(Dummy1 self); + +} // extern "C" diff --git a/tests/expectations/traits_type.pyx b/tests/expectations/traits_type.pyx new file mode 100644 index 00000000..da89f6c8 --- /dev/null +++ b/tests/expectations/traits_type.pyx @@ -0,0 +1,17 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + ctypedef struct Dummy0: + uintptr_t dummy; + + ctypedef struct Dummy1: + uintptr_t dummy; + + Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); + + int32_t dummy_Dummy1(Dummy1 self); diff --git a/tests/expectations/traits_type_both.c b/tests/expectations/traits_type_both.c new file mode 100644 index 00000000..839ea0f6 --- /dev/null +++ b/tests/expectations/traits_type_both.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +typedef struct Dummy0 { + uintptr_t dummy; +} Dummy0; + +typedef struct Dummy1 { + uintptr_t dummy; +} Dummy1; + +struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); + +int32_t dummy_Dummy1(struct Dummy1 self); diff --git a/tests/expectations/traits_type_both.compat.c b/tests/expectations/traits_type_both.compat.c new file mode 100644 index 00000000..e1e38fa5 --- /dev/null +++ b/tests/expectations/traits_type_both.compat.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +typedef struct Dummy0 { + uintptr_t dummy; +} Dummy0; + +typedef struct Dummy1 { + uintptr_t dummy; +} Dummy1; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); + +int32_t dummy_Dummy1(struct Dummy1 self); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/traits_type_tag.c b/tests/expectations/traits_type_tag.c new file mode 100644 index 00000000..6dcda6b6 --- /dev/null +++ b/tests/expectations/traits_type_tag.c @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +struct Dummy0 { + uintptr_t dummy; +}; + +struct Dummy1 { + uintptr_t dummy; +}; + +struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); + +int32_t dummy_Dummy1(struct Dummy1 self); diff --git a/tests/expectations/traits_type_tag.compat.c b/tests/expectations/traits_type_tag.compat.c new file mode 100644 index 00000000..026efef5 --- /dev/null +++ b/tests/expectations/traits_type_tag.compat.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +struct Dummy0 { + uintptr_t dummy; +}; + +struct Dummy1 { + uintptr_t dummy; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); + +int32_t dummy_Dummy1(struct Dummy1 self); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/traits_type_tag.pyx b/tests/expectations/traits_type_tag.pyx new file mode 100644 index 00000000..da2728a0 --- /dev/null +++ b/tests/expectations/traits_type_tag.pyx @@ -0,0 +1,17 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + cdef struct Dummy0: + uintptr_t dummy; + + cdef struct Dummy1: + uintptr_t dummy; + + Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); + + int32_t dummy_Dummy1(Dummy1 self); diff --git a/tests/rust/traits_type.rs b/tests/rust/traits_type.rs new file mode 100644 index 00000000..34f45af4 --- /dev/null +++ b/tests/rust/traits_type.rs @@ -0,0 +1,38 @@ +pub trait DummyTrait { + type DummyIn; + type DummyOut; + + extern "C" fn dummy(self, in_: Self::DummyIn) -> Self::DummyOut; +} + +#[repr(C)] +pub struct Dummy0 { + dummy: usize, +} + +impl DummyTrait for Dummy0 { + type DummyIn = usize; + type DummyOut = Self; + + #[unsafe(export_name = "dummy_Dummy0")] + extern "C" fn dummy(self, in_: Self::DummyIn) -> Self::DummyOut { + Self { + dummy: in_, + } + } +} + +#[repr(C)] +pub struct Dummy1 { + dummy: usize +} + +impl DummyTrait for Dummy1 { + type DummyIn = (); + type DummyOut = i32; + + #[unsafe(export_name = "dummy_Dummy1")] + extern "C" fn dummy(self, in_: Self::DummyIn) -> Self::DummyOut { + 0 + } +} From 740f41c6f9f65aaba1777542fa2a37ee464104f8 Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Mon, 17 Feb 2025 22:12:20 +0300 Subject: [PATCH 5/8] Fixed the generation of associated constants --- src/bindgen/parser.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index b3641a90..b5ea2bf2 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -534,10 +534,12 @@ impl Parse { } syn::Item::Impl(ref item_impl) => { let mut impls_with_assoc_ty = Vec::new(); + let mut assoc_const_find = false; item_impl.items.iter().for_each(|item| { - if matches!(item, syn::ImplItem::Const(_)) { + if matches!(item, syn::ImplItem::Const(_)) && !assoc_const_find { impls_with_assoc_consts.push(item_impl); + assoc_const_find = !assoc_const_find; } else if let syn::ImplItem::Type(t) = item { impls_with_assoc_ty.push((&t.ident, &t.ty)); } From 99be358d5710b623cd4c039ff57977c7cd67a3a6 Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Fri, 7 Mar 2025 15:11:59 +0300 Subject: [PATCH 6/8] Now associative types generate typedefs --- src/bindgen/ir/generic_path.rs | 9 + src/bindgen/ir/ty.rs | 32 ++++ src/bindgen/ir/typedef.rs | 51 +++++ src/bindgen/parser.rs | 330 ++++++++++++++++++++++++--------- 4 files changed, 335 insertions(+), 87 deletions(-) diff --git a/src/bindgen/ir/generic_path.rs b/src/bindgen/ir/generic_path.rs index 4610641c..4c986bfd 100644 --- a/src/bindgen/ir/generic_path.rs +++ b/src/bindgen/ir/generic_path.rs @@ -264,6 +264,15 @@ impl GenericPath { // Caller deals with generics. } + pub fn set_assoc_ty(&mut self, assoc_ty_name: T) + where + T: Into, + { + let path = assoc_ty_name.into(); + self.path = Path::new(&path); + self.export_name = path; + } + pub fn path(&self) -> &Path { &self.path } diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index 2d0d692a..f699960e 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -627,6 +627,38 @@ impl Type { } } + pub fn try_set_assoc_name(&mut self, assoc_name: T) -> Result<(), String> + where + T: Into, + { + let mut current = self; + loop { + match current { + Type::Ptr { ref mut ty, .. } => current = ty, + Type::Path(ref mut generic) => { + generic.set_assoc_ty(assoc_name); + + break Ok(()); + } + _ => { + break Err(format!( + "Failed to set path ({}) for type {:?}", + assoc_name.into(), + current + )) + } + } + } + } + + pub fn name_is_self(&self) -> bool { + if let Some(name) = self.get_root_path() { + name.name() == "Self" + } else { + false + } + } + pub fn specialize(&self, mappings: &[(&Path, &GenericArgument)]) -> Type { match *self { Type::Ptr { diff --git a/src/bindgen/ir/typedef.rs b/src/bindgen/ir/typedef.rs index e775a4e8..21eece50 100644 --- a/src/bindgen/ir/typedef.rs +++ b/src/bindgen/ir/typedef.rs @@ -46,6 +46,57 @@ impl Typedef { } } + pub fn load_impl( + item: &syn::ImplItemType, + mod_cfg: Option<&Cfg>, + trait_ident: &syn::Ident, + self_ty: &Type, + ) -> Result { + let ty_path = match Type::load(&item.ty) { + Ok(t) => t, + Err(err) => { + return Err(format!( + "Failed to load the type {}::{} {}", + trait_ident, item.ident, err, + )); + } + }; + + let impl_ty_path = match self_ty.get_root_path() { + Some(path) => path, + None => { + return Err(format!( + "Couldn't find path for {self_ty:?}, skipping associated type" + )); + } + }; + + if let Some(ty_path) = ty_path { + let path = Path::new(format!( + "{}_{}_{}", + impl_ty_path.name(), + trait_ident, + item.ident, + )); + let aliased = if ty_path.name_is_self() { + self_ty.clone() + } else { + ty_path + }; + + Ok(Typedef::new( + path, + GenericParams::load(&item.generics)?, + aliased, + Cfg::append(mod_cfg, Cfg::load(&item.attrs)), + AnnotationSet::load(&item.attrs)?, + Documentation::load(&item.attrs), + )) + } else { + Err("Cannot have a typedef of a zero sized type.".to_owned()) + } + } + pub fn new( path: Path, generic_params: GenericParams, diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index b5ea2bf2..b32891f7 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -495,6 +495,7 @@ impl Parse { items: &'a [syn::Item], ) -> Vec<&'a syn::ItemMod> { let mut impls_with_assoc_consts = Vec::new(); + let mut impls_with_assoc_fn = Vec::new(); let mut nested_modules = Vec::new(); for item in items { @@ -533,70 +534,23 @@ impl Parse { self.load_syn_ty(crate_name, mod_cfg, item); } syn::Item::Impl(ref item_impl) => { - let mut impls_with_assoc_ty = Vec::new(); let mut assoc_const_find = false; + let mut assoc_method_find = false; - item_impl.items.iter().for_each(|item| { + item_impl.items.iter().any(|item| { if matches!(item, syn::ImplItem::Const(_)) && !assoc_const_find { impls_with_assoc_consts.push(item_impl); - assoc_const_find = !assoc_const_find; - } else if let syn::ImplItem::Type(t) = item { - impls_with_assoc_ty.push((&t.ident, &t.ty)); + assoc_const_find = true; + } else if matches!(item, syn::ImplItem::Fn(_)) + && !assoc_method_find + && matches!(*item_impl.self_ty, syn::Type::Path(_)) + { + impls_with_assoc_fn.push(item_impl); + assoc_method_find = true; } - }); - - if let syn::Type::Path(ref path) = *item_impl.self_ty { - if let Some(type_name) = path.path.get_ident() { - for method in item_impl.items.iter().filter_map(|item| match item { - syn::ImplItem::Fn(method) if !method.should_skip_parsing() => { - Some(method) - } - _ => None, - }) { - let mut method = method.clone(); - let out = match Type::load_from_output(&method.sig.output) { - Ok((out, ..)) => out, - Err(..) => continue, - }; - - for (ident, ty) in &impls_with_assoc_ty { - let ident = ident.to_string(); - - if let (Some(out_name), syn::ReturnType::Type(_, t)) = - (out.get_root_path(), &mut method.sig.output) - { - if ident == out_name.to_string() { - *t = Box::new((*ty).clone()); - } - } - method.sig.inputs.iter_mut().for_each(|arg| { - if let syn::FnArg::Typed(t) = arg { - let attr_ty = match Type::load(&t.ty) { - Ok(Some(t)) => t, - _ => return, - }; - - if let Some(attr_ty) = attr_ty.get_root_path() { - if ident == attr_ty.to_string() { - t.ty = Box::new((*ty).clone()); - } - } - } - }); - } - - self.load_syn_method( - config, - binding_crate_name, - crate_name, - mod_cfg, - &Path::new(type_name.unraw().to_string()), - &method, - ) - } - } - } + assoc_const_find && assoc_method_find + }); } syn::Item::Macro(ref item) => { self.load_builtin_macro(config, crate_name, mod_cfg, item); @@ -611,6 +565,15 @@ impl Parse { for item_impl in impls_with_assoc_consts { self.load_syn_assoc_consts_from_impl(crate_name, mod_cfg, item_impl) } + for item_impl in impls_with_assoc_fn { + self.load_syn_assoc_methods_tys_from_impl( + config, + binding_crate_name, + crate_name, + mod_cfg, + item_impl, + ); + } nested_modules } @@ -637,6 +600,55 @@ impl Parse { ); } + fn load_syn_assoc_methods_tys_from_impl( + &mut self, + config: &Config, + binding_crate_name: &str, + crate_name: &str, + mod_cfg: Option<&Cfg>, + item_impl: &syn::ItemImpl, + ) { + let mut associated_tys = Vec::new(); + let mut associated_methods = Vec::new(); + item_impl.items.iter().for_each(|item| match item { + syn::ImplItem::Fn(ref assocciated_method) => { + if !assocciated_method.should_skip_parsing() { + associated_methods.push(assocciated_method) + } + } + syn::ImplItem::Type(ref assoc_ty) => associated_tys.push(assoc_ty), + _ => {} + }); + + let trait_ident = if let Some((_, ref path, _)) = item_impl.trait_ { + if let Some(ident) = path.get_ident() { + self.load_syn_assoc_tys( + crate_name, + mod_cfg, + ident, + &item_impl.self_ty, + &associated_tys, + ); + + Some(ident) + } else { + None + } + } else { + None + }; + self.load_syn_assoc_methods( + config, + binding_crate_name, + crate_name, + mod_cfg, + &item_impl.self_ty, + associated_methods, + associated_tys, + trait_ident, + ); + } + /// Enters a `extern "C" { }` declaration and loads function declarations. fn load_syn_foreign_mod( &mut self, @@ -690,25 +702,119 @@ impl Parse { } /// Loads a `fn` declaration inside an `impl` block, if the type is a simple identifier - fn load_syn_method( + fn load_syn_assoc_methods( &mut self, config: &Config, binding_crate_name: &str, crate_name: &str, mod_cfg: Option<&Cfg>, - self_type: &Path, - item: &syn::ImplItemFn, + self_type: &syn::Type, + items_fn: Vec<&syn::ImplItemFn>, + items_ty: Vec<&syn::ImplItemType>, + trait_ident: Option<&syn::Ident>, ) { - self.load_fn_declaration( - config, - binding_crate_name, - crate_name, - mod_cfg, - item, - Some(self_type), - &item.sig, - &item.attrs, - ) + let self_path = if let syn::Type::Path(ref path) = self_type { + if let Some(type_name) = path.path.get_ident() { + Path::new(type_name.unraw().to_string()) + } else { + info!( + "Skip {}::{:?} - (Path name not found)", + crate_name, path.path + ); + return; + } + } else { + info!("Skip ({:?}) - (Incompatible self type)", self_type); + return; + }; + + for item in items_fn { + if !config + .parse + .should_generate_top_level_item(crate_name, binding_crate_name) + { + info!( + "Skip {}::{} - (fn's outside of the binding crate are not used).", + crate_name, &item.sig.ident + ); + return; + } + + let loggable_item_name = format!("{}::{}::{}", crate_name, self_path, item.sig.ident); + + let is_extern_c = item.sig.abi.is_omitted() || item.sig.abi.is_c(); + let exported_name = item.exported_name(); + + match (is_extern_c, exported_name) { + (true, Some(exported_name)) => { + let path = Path::new(exported_name); + match Function::load( + path, + Some(&self_path), + &item.sig, + false, + &item.attrs, + mod_cfg, + ) { + Ok(mut method) => { + info!("Take method {}.", loggable_item_name); + if let Some(trait_ident) = trait_ident { + let ret_path = match method.ret.get_root_path() { + Some(p) => p, + None => Path::new(""), + }; + // Search and replacement of the type of method with associative + // types + items_ty.iter().for_each(|&ty| { + if ret_path.name() == &ty.ident.to_string() { + match method.ret.try_set_assoc_name(format!("{}_{}_{}", self_path.name(), trait_ident, ty.ident)) { + Err(e) => { + warn!("It is not possible to chage return type for method {}::{} - ({})", crate_name, method.path.name(), e); + return; + } + Ok(..) => {} + } + } + // Removing all arguments with `void` type + method.args.retain(|arg| if let (Some(p), syn::Type::Tuple(syn::TypeTuple { ref elems, .. })) = (arg.ty.get_root_path(), &ty.ty) { + !(elems.is_empty() && p.name() == &ty.ident.to_string()) + } else { + true + }); + if let Some(arg) = method.args.iter_mut().find(|arg| if let Some(p) = arg.ty.get_root_path() { + p.name() == &ty.ident.to_string() + } else { + false + }) { + match arg.ty.try_set_assoc_name(format!("{}_{}_{}", self_path.name(), trait_ident, ty.ident)) { + Err(e) => { + warn!("It is not possible to chage method's argument {}::{} - ({})", crate_name, method.path.name(), e); + return; + } + Ok(..) => {} + } + } + }); + } + self.functions.push(method); + } + Err(msg) => { + error!("Cannot use fn {} ({}).", loggable_item_name, msg); + } + } + } + (true, None) => { + warn!( + "Skipping {} - (not `no_mangle`, and has no `export_name` attribute)", + loggable_item_name + ); + } + (false, Some(_exported_name)) => { + warn!("Skipping {} - (not `extern \"C\"`)", loggable_item_name); + } + (false, None) => {} + } + } } /// Loads a `fn` declaration @@ -726,7 +832,6 @@ impl Parse { crate_name, mod_cfg, item, - None, &item.sig, &item.attrs, ); @@ -740,7 +845,6 @@ impl Parse { crate_name: &str, mod_cfg: Option<&Cfg>, named_symbol: &dyn SynItemHelpers, - self_type: Option<&Path>, sig: &syn::Signature, attrs: &[syn::Attribute], ) { @@ -755,15 +859,7 @@ impl Parse { return; } - let loggable_item_name = || { - let mut items = Vec::with_capacity(3); - items.push(crate_name.to_owned()); - if let Some(ref self_type) = self_type { - items.push(self_type.to_string()); - } - items.push(sig.ident.unraw().to_string()); - items.join("::") - }; + let loggable_item_name = format!("{}::{}", crate_name, sig.ident); let is_extern_c = sig.abi.is_omitted() || sig.abi.is_c(); let exported_name = named_symbol.exported_name(); @@ -771,24 +867,24 @@ impl Parse { match (is_extern_c, exported_name) { (true, Some(exported_name)) => { let path = Path::new(exported_name); - match Function::load(path, self_type, sig, false, attrs, mod_cfg) { + match Function::load(path, None, sig, false, attrs, mod_cfg) { Ok(func) => { - info!("Take {}.", loggable_item_name()); + info!("Take {}.", loggable_item_name); self.functions.push(func); } Err(msg) => { - error!("Cannot use fn {} ({}).", loggable_item_name(), msg); + error!("Cannot use fn {} ({}).", loggable_item_name, msg); } } } (true, None) => { warn!( "Skipping {} - (not `no_mangle`, and has no `export_name` attribute)", - loggable_item_name() + loggable_item_name ); } (false, Some(_exported_name)) => { - warn!("Skipping {} - (not `extern \"C\"`)", loggable_item_name()); + warn!("Skipping {} - (not `extern \"C\"`)", loggable_item_name); } (false, None) => {} } @@ -867,6 +963,66 @@ impl Parse { } } + fn load_syn_assoc_tys( + &mut self, + crate_name: &str, + mod_cfg: Option<&Cfg>, + trait_ident: &syn::Ident, + self_ty: &syn::Type, + items: &Vec<&syn::ImplItemType>, + ) { + let ty = match Type::load(self_ty) { + Ok(ty) => ty, + Err(e) => { + warn!("Skipping associated types for {:?}: {:?}", self_ty, e); + return; + } + }; + + let ty = match ty { + Some(ty) => ty, + None => return, + }; + + let impl_path = match ty.get_root_path() { + Some(p) => p, + None => { + warn!("Couldn't find path for {:?}, skipping associated types", ty); + return; + } + }; + + let self_ty = match Type::load(self_ty) { + Ok(ty) => ty, + Err(e) => { + warn!("Skipping self types for {:?}: {:?}", self_ty, e); + return; + } + }; + + let self_ty = match self_ty { + Some(ty) => ty, + None => return, + }; + + for &item in items { + match Typedef::load_impl(item, mod_cfg, trait_ident, &self_ty) { + Ok(ty) => { + info!("Take {}::{}::{}.", crate_name, impl_path, &item.ident); + if !self.typedefs.try_insert(ty) { + error!( + "Conflicting name for types {}::{}::{}.", + crate_name, impl_path, &item.ident, + ); + } + } + Err(msg) => { + warn!("Skip {}::{} - ({})", crate_name, &item.ident, msg); + } + } + } + } + /// Loads a `const` declaration fn load_syn_const( &mut self, From 847794a6b9aa6fb9cf0c35d40edca1deba996cf1 Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Fri, 7 Mar 2025 15:12:49 +0300 Subject: [PATCH 7/8] Changed tests and test results --- tests/expectations-symbols/swift_name.c.sym | 12 +++++----- tests/expectations/swift_name.c | 24 ++++++++++---------- tests/expectations/swift_name.compat.c | 24 ++++++++++---------- tests/expectations/swift_name.cpp | 24 ++++++++++---------- tests/expectations/swift_name.pyx | 24 ++++++++++---------- tests/expectations/swift_name_both.c | 24 ++++++++++---------- tests/expectations/swift_name_both.compat.c | 24 ++++++++++---------- tests/expectations/swift_name_tag.c | 24 ++++++++++---------- tests/expectations/swift_name_tag.compat.c | 24 ++++++++++---------- tests/expectations/swift_name_tag.pyx | 24 ++++++++++---------- tests/expectations/traits_type.c | 12 ++++++++-- tests/expectations/traits_type.compat.c | 12 ++++++++-- tests/expectations/traits_type.cpp | 12 ++++++++-- tests/expectations/traits_type.pyx | 12 ++++++++-- tests/expectations/traits_type_both.c | 12 ++++++++-- tests/expectations/traits_type_both.compat.c | 12 ++++++++-- tests/expectations/traits_type_tag.c | 12 ++++++++-- tests/expectations/traits_type_tag.compat.c | 12 ++++++++-- tests/expectations/traits_type_tag.pyx | 12 ++++++++-- tests/rust/traits_type.rs | 17 ++++++++------ 20 files changed, 214 insertions(+), 139 deletions(-) diff --git a/tests/expectations-symbols/swift_name.c.sym b/tests/expectations-symbols/swift_name.c.sym index 4b70e6d4..87379f7c 100644 --- a/tests/expectations-symbols/swift_name.c.sym +++ b/tests/expectations-symbols/swift_name.c.sym @@ -1,5 +1,11 @@ { rust_print_hello_world; +free_function_should_exist_ref; +free_function_should_exist_ref_mut; +unnamed_argument; +free_function_should_not_exist_box; +free_function_should_exist_annotated_by_name; +free_function_should_exist_annotated_mut_by_name; SelfTypeTestStruct_should_exist_ref; SelfTypeTestStruct_should_exist_ref_mut; SelfTypeTestStruct_should_not_exist_box; @@ -10,12 +16,6 @@ SelfTypeTestStruct_should_exist_annotated_by_name; SelfTypeTestStruct_should_exist_annotated_mut_by_name; SelfTypeTestStruct_should_exist_unannotated; SelfTypeTestStruct_should_exist_mut_unannotated; -free_function_should_exist_ref; -free_function_should_exist_ref_mut; -unnamed_argument; -free_function_should_not_exist_box; -free_function_should_exist_annotated_by_name; -free_function_should_exist_annotated_mut_by_name; PointerToOpaque_create; PointerToOpaque_sayHello; }; \ No newline at end of file diff --git a/tests/expectations/swift_name.c b/tests/expectations/swift_name.c index 17ec2144..e116ea04 100644 --- a/tests/expectations/swift_name.c +++ b/tests/expectations/swift_name.c @@ -17,6 +17,18 @@ typedef struct { void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world()); +void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); + +void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); + +void unnamed_argument(SelfTypeTestStruct*); + +void free_function_should_not_exist_box(SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); + +void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); + +void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); + void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:)); void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:)); @@ -37,18 +49,6 @@ void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWI void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:)); -void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); - -void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); - -void unnamed_argument(SelfTypeTestStruct*); - -void free_function_should_not_exist_box(SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); - -void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); - -void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); - PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:)); void PointerToOpaque_sayHello(PointerToOpaque self) CF_SWIFT_NAME(PointerToOpaque.sayHello(self:)); diff --git a/tests/expectations/swift_name.compat.c b/tests/expectations/swift_name.compat.c index d018ce83..6bac1a62 100644 --- a/tests/expectations/swift_name.compat.c +++ b/tests/expectations/swift_name.compat.c @@ -21,6 +21,18 @@ extern "C" { void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world()); +void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); + +void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); + +void unnamed_argument(SelfTypeTestStruct*); + +void free_function_should_not_exist_box(SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); + +void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); + +void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); + void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:)); void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:)); @@ -41,18 +53,6 @@ void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWI void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:)); -void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); - -void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); - -void unnamed_argument(SelfTypeTestStruct*); - -void free_function_should_not_exist_box(SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); - -void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); - -void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); - PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:)); void PointerToOpaque_sayHello(PointerToOpaque self) CF_SWIFT_NAME(PointerToOpaque.sayHello(self:)); diff --git a/tests/expectations/swift_name.cpp b/tests/expectations/swift_name.cpp index 56d422c5..2173a344 100644 --- a/tests/expectations/swift_name.cpp +++ b/tests/expectations/swift_name.cpp @@ -23,6 +23,18 @@ extern "C" { void rust_print_hello_world() CF_SWIFT_NAME(rust_print_hello_world()); +void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); + +void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); + +void unnamed_argument(SelfTypeTestStruct*); + +void free_function_should_not_exist_box(Box boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); + +void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); + +void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); + void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:)); void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:)); @@ -43,18 +55,6 @@ void SelfTypeTestStruct_should_exist_unannotated(SelfTypeTestStruct self) CF_SWI void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:)); -void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); - -void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); - -void unnamed_argument(SelfTypeTestStruct*); - -void free_function_should_not_exist_box(Box boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); - -void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); - -void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); - PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:)); void PointerToOpaque_sayHello(PointerToOpaque self) CF_SWIFT_NAME(PointerToOpaque.sayHello(self:)); diff --git a/tests/expectations/swift_name.pyx b/tests/expectations/swift_name.pyx index 3c2435a5..03aa448b 100644 --- a/tests/expectations/swift_name.pyx +++ b/tests/expectations/swift_name.pyx @@ -19,6 +19,18 @@ cdef extern from *: void rust_print_hello_world(); + void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct); + + void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct); + + void unnamed_argument(SelfTypeTestStruct*); + + void free_function_should_not_exist_box(SelfTypeTestStruct *boxed); + + void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct); + + void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct); + void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self); void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self); @@ -39,18 +51,6 @@ cdef extern from *: void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self); - void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct); - - void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct); - - void unnamed_argument(SelfTypeTestStruct*); - - void free_function_should_not_exist_box(SelfTypeTestStruct *boxed); - - void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct); - - void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct); - PointerToOpaque PointerToOpaque_create(uint8_t times); void PointerToOpaque_sayHello(PointerToOpaque self); diff --git a/tests/expectations/swift_name_both.c b/tests/expectations/swift_name_both.c index 4911679f..8dc4016a 100644 --- a/tests/expectations/swift_name_both.c +++ b/tests/expectations/swift_name_both.c @@ -17,6 +17,18 @@ typedef struct PointerToOpaque { void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world()); +void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); + +void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); + +void unnamed_argument(struct SelfTypeTestStruct*); + +void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); + +void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); + +void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); + void SelfTypeTestStruct_should_exist_ref(const struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:)); void SelfTypeTestStruct_should_exist_ref_mut(struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:)); @@ -37,18 +49,6 @@ void SelfTypeTestStruct_should_exist_unannotated(struct SelfTypeTestStruct self) void SelfTypeTestStruct_should_exist_mut_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:)); -void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); - -void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); - -void unnamed_argument(struct SelfTypeTestStruct*); - -void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); - -void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); - -void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); - struct PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:)); void PointerToOpaque_sayHello(struct PointerToOpaque self) CF_SWIFT_NAME(PointerToOpaque.sayHello(self:)); diff --git a/tests/expectations/swift_name_both.compat.c b/tests/expectations/swift_name_both.compat.c index 592a8c7d..dec702ec 100644 --- a/tests/expectations/swift_name_both.compat.c +++ b/tests/expectations/swift_name_both.compat.c @@ -21,6 +21,18 @@ extern "C" { void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world()); +void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); + +void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); + +void unnamed_argument(struct SelfTypeTestStruct*); + +void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); + +void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); + +void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); + void SelfTypeTestStruct_should_exist_ref(const struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:)); void SelfTypeTestStruct_should_exist_ref_mut(struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:)); @@ -41,18 +53,6 @@ void SelfTypeTestStruct_should_exist_unannotated(struct SelfTypeTestStruct self) void SelfTypeTestStruct_should_exist_mut_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:)); -void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); - -void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); - -void unnamed_argument(struct SelfTypeTestStruct*); - -void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); - -void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); - -void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); - struct PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:)); void PointerToOpaque_sayHello(struct PointerToOpaque self) CF_SWIFT_NAME(PointerToOpaque.sayHello(self:)); diff --git a/tests/expectations/swift_name_tag.c b/tests/expectations/swift_name_tag.c index 370b88ae..003cef33 100644 --- a/tests/expectations/swift_name_tag.c +++ b/tests/expectations/swift_name_tag.c @@ -17,6 +17,18 @@ struct PointerToOpaque { void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world()); +void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); + +void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); + +void unnamed_argument(struct SelfTypeTestStruct*); + +void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); + +void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); + +void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); + void SelfTypeTestStruct_should_exist_ref(const struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:)); void SelfTypeTestStruct_should_exist_ref_mut(struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:)); @@ -37,18 +49,6 @@ void SelfTypeTestStruct_should_exist_unannotated(struct SelfTypeTestStruct self) void SelfTypeTestStruct_should_exist_mut_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:)); -void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); - -void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); - -void unnamed_argument(struct SelfTypeTestStruct*); - -void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); - -void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); - -void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); - struct PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:)); void PointerToOpaque_sayHello(struct PointerToOpaque self) CF_SWIFT_NAME(PointerToOpaque.sayHello(self:)); diff --git a/tests/expectations/swift_name_tag.compat.c b/tests/expectations/swift_name_tag.compat.c index 89b1b2bd..2b1bae7e 100644 --- a/tests/expectations/swift_name_tag.compat.c +++ b/tests/expectations/swift_name_tag.compat.c @@ -21,6 +21,18 @@ extern "C" { void rust_print_hello_world(void) CF_SWIFT_NAME(rust_print_hello_world()); +void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); + +void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); + +void unnamed_argument(struct SelfTypeTestStruct*); + +void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); + +void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); + +void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); + void SelfTypeTestStruct_should_exist_ref(const struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref(self:)); void SelfTypeTestStruct_should_exist_ref_mut(struct SelfTypeTestStruct *self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_ref_mut(self:)); @@ -41,18 +53,6 @@ void SelfTypeTestStruct_should_exist_unannotated(struct SelfTypeTestStruct self) void SelfTypeTestStruct_should_exist_mut_unannotated(struct SelfTypeTestStruct self) CF_SWIFT_NAME(SelfTypeTestStruct.should_exist_mut_unannotated(self:)); -void free_function_should_exist_ref(const struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref(test_struct:)); - -void free_function_should_exist_ref_mut(struct SelfTypeTestStruct *test_struct) CF_SWIFT_NAME(free_function_should_exist_ref_mut(test_struct:)); - -void unnamed_argument(struct SelfTypeTestStruct*); - -void free_function_should_not_exist_box(struct SelfTypeTestStruct *boxed) CF_SWIFT_NAME(free_function_should_not_exist_box(boxed:)); - -void free_function_should_exist_annotated_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_by_name(test_struct:)); - -void free_function_should_exist_annotated_mut_by_name(struct SelfTypeTestStruct test_struct) CF_SWIFT_NAME(free_function_should_exist_annotated_mut_by_name(test_struct:)); - struct PointerToOpaque PointerToOpaque_create(uint8_t times) CF_SWIFT_NAME(PointerToOpaque.create(times:)); void PointerToOpaque_sayHello(struct PointerToOpaque self) CF_SWIFT_NAME(PointerToOpaque.sayHello(self:)); diff --git a/tests/expectations/swift_name_tag.pyx b/tests/expectations/swift_name_tag.pyx index 127fb324..7506e0a2 100644 --- a/tests/expectations/swift_name_tag.pyx +++ b/tests/expectations/swift_name_tag.pyx @@ -19,6 +19,18 @@ cdef extern from *: void rust_print_hello_world(); + void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct); + + void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct); + + void unnamed_argument(SelfTypeTestStruct*); + + void free_function_should_not_exist_box(SelfTypeTestStruct *boxed); + + void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct); + + void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct); + void SelfTypeTestStruct_should_exist_ref(const SelfTypeTestStruct *self); void SelfTypeTestStruct_should_exist_ref_mut(SelfTypeTestStruct *self); @@ -39,18 +51,6 @@ cdef extern from *: void SelfTypeTestStruct_should_exist_mut_unannotated(SelfTypeTestStruct self); - void free_function_should_exist_ref(const SelfTypeTestStruct *test_struct); - - void free_function_should_exist_ref_mut(SelfTypeTestStruct *test_struct); - - void unnamed_argument(SelfTypeTestStruct*); - - void free_function_should_not_exist_box(SelfTypeTestStruct *boxed); - - void free_function_should_exist_annotated_by_name(SelfTypeTestStruct test_struct); - - void free_function_should_exist_annotated_mut_by_name(SelfTypeTestStruct test_struct); - PointerToOpaque PointerToOpaque_create(uint8_t times); void PointerToOpaque_sayHello(PointerToOpaque self); diff --git a/tests/expectations/traits_type.c b/tests/expectations/traits_type.c index 517cc121..4320d97a 100644 --- a/tests/expectations/traits_type.c +++ b/tests/expectations/traits_type.c @@ -7,10 +7,18 @@ typedef struct { uintptr_t dummy; } Dummy0; +typedef Dummy0 Dummy0_DummyTrait_DummyOut; + +typedef Dummy0 Dummy0_DummyTrait_DummyIn1; + +typedef int32_t Dummy1_DummyTrait_DummyOut; + typedef struct { uintptr_t dummy; } Dummy1; -Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); +typedef uintptr_t Dummy1_DummyTrait_DummyIn1; + +Dummy0_DummyTrait_DummyOut dummy_Dummy0(Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); -int32_t dummy_Dummy1(Dummy1 self); +Dummy1_DummyTrait_DummyOut dummy_Dummy1(Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); diff --git a/tests/expectations/traits_type.compat.c b/tests/expectations/traits_type.compat.c index de8f43e9..2d26a7cd 100644 --- a/tests/expectations/traits_type.compat.c +++ b/tests/expectations/traits_type.compat.c @@ -7,17 +7,25 @@ typedef struct { uintptr_t dummy; } Dummy0; +typedef Dummy0 Dummy0_DummyTrait_DummyOut; + +typedef Dummy0 Dummy0_DummyTrait_DummyIn1; + +typedef int32_t Dummy1_DummyTrait_DummyOut; + typedef struct { uintptr_t dummy; } Dummy1; +typedef uintptr_t Dummy1_DummyTrait_DummyIn1; + #ifdef __cplusplus extern "C" { #endif // __cplusplus -Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); +Dummy0_DummyTrait_DummyOut dummy_Dummy0(Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); -int32_t dummy_Dummy1(Dummy1 self); +Dummy1_DummyTrait_DummyOut dummy_Dummy1(Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/traits_type.cpp b/tests/expectations/traits_type.cpp index 891c0c6b..c2780c77 100644 --- a/tests/expectations/traits_type.cpp +++ b/tests/expectations/traits_type.cpp @@ -8,14 +8,22 @@ struct Dummy0 { uintptr_t dummy; }; +using Dummy0_DummyTrait_DummyOut = Dummy0; + +using Dummy0_DummyTrait_DummyIn1 = Dummy0; + +using Dummy1_DummyTrait_DummyOut = int32_t; + struct Dummy1 { uintptr_t dummy; }; +using Dummy1_DummyTrait_DummyIn1 = uintptr_t; + extern "C" { -Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); +Dummy0_DummyTrait_DummyOut dummy_Dummy0(Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); -int32_t dummy_Dummy1(Dummy1 self); +Dummy1_DummyTrait_DummyOut dummy_Dummy1(Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); } // extern "C" diff --git a/tests/expectations/traits_type.pyx b/tests/expectations/traits_type.pyx index da89f6c8..2366c978 100644 --- a/tests/expectations/traits_type.pyx +++ b/tests/expectations/traits_type.pyx @@ -9,9 +9,17 @@ cdef extern from *: ctypedef struct Dummy0: uintptr_t dummy; + ctypedef Dummy0 Dummy0_DummyTrait_DummyOut; + + ctypedef Dummy0 Dummy0_DummyTrait_DummyIn1; + + ctypedef int32_t Dummy1_DummyTrait_DummyOut; + ctypedef struct Dummy1: uintptr_t dummy; - Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); + ctypedef uintptr_t Dummy1_DummyTrait_DummyIn1; + + Dummy0_DummyTrait_DummyOut dummy_Dummy0(Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); - int32_t dummy_Dummy1(Dummy1 self); + Dummy1_DummyTrait_DummyOut dummy_Dummy1(Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); diff --git a/tests/expectations/traits_type_both.c b/tests/expectations/traits_type_both.c index 839ea0f6..5ca5836d 100644 --- a/tests/expectations/traits_type_both.c +++ b/tests/expectations/traits_type_both.c @@ -7,10 +7,18 @@ typedef struct Dummy0 { uintptr_t dummy; } Dummy0; +typedef struct Dummy0 Dummy0_DummyTrait_DummyOut; + +typedef struct Dummy0 Dummy0_DummyTrait_DummyIn1; + +typedef int32_t Dummy1_DummyTrait_DummyOut; + typedef struct Dummy1 { uintptr_t dummy; } Dummy1; -struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); +typedef uintptr_t Dummy1_DummyTrait_DummyIn1; + +Dummy0_DummyTrait_DummyOut dummy_Dummy0(struct Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); -int32_t dummy_Dummy1(struct Dummy1 self); +Dummy1_DummyTrait_DummyOut dummy_Dummy1(struct Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); diff --git a/tests/expectations/traits_type_both.compat.c b/tests/expectations/traits_type_both.compat.c index e1e38fa5..97dd55be 100644 --- a/tests/expectations/traits_type_both.compat.c +++ b/tests/expectations/traits_type_both.compat.c @@ -7,17 +7,25 @@ typedef struct Dummy0 { uintptr_t dummy; } Dummy0; +typedef struct Dummy0 Dummy0_DummyTrait_DummyOut; + +typedef struct Dummy0 Dummy0_DummyTrait_DummyIn1; + +typedef int32_t Dummy1_DummyTrait_DummyOut; + typedef struct Dummy1 { uintptr_t dummy; } Dummy1; +typedef uintptr_t Dummy1_DummyTrait_DummyIn1; + #ifdef __cplusplus extern "C" { #endif // __cplusplus -struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); +Dummy0_DummyTrait_DummyOut dummy_Dummy0(struct Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); -int32_t dummy_Dummy1(struct Dummy1 self); +Dummy1_DummyTrait_DummyOut dummy_Dummy1(struct Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/traits_type_tag.c b/tests/expectations/traits_type_tag.c index 6dcda6b6..03069bfb 100644 --- a/tests/expectations/traits_type_tag.c +++ b/tests/expectations/traits_type_tag.c @@ -7,10 +7,18 @@ struct Dummy0 { uintptr_t dummy; }; +typedef struct Dummy0 Dummy0_DummyTrait_DummyOut; + +typedef struct Dummy0 Dummy0_DummyTrait_DummyIn1; + +typedef int32_t Dummy1_DummyTrait_DummyOut; + struct Dummy1 { uintptr_t dummy; }; -struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); +typedef uintptr_t Dummy1_DummyTrait_DummyIn1; + +Dummy0_DummyTrait_DummyOut dummy_Dummy0(struct Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); -int32_t dummy_Dummy1(struct Dummy1 self); +Dummy1_DummyTrait_DummyOut dummy_Dummy1(struct Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); diff --git a/tests/expectations/traits_type_tag.compat.c b/tests/expectations/traits_type_tag.compat.c index 026efef5..31752e27 100644 --- a/tests/expectations/traits_type_tag.compat.c +++ b/tests/expectations/traits_type_tag.compat.c @@ -7,17 +7,25 @@ struct Dummy0 { uintptr_t dummy; }; +typedef struct Dummy0 Dummy0_DummyTrait_DummyOut; + +typedef struct Dummy0 Dummy0_DummyTrait_DummyIn1; + +typedef int32_t Dummy1_DummyTrait_DummyOut; + struct Dummy1 { uintptr_t dummy; }; +typedef uintptr_t Dummy1_DummyTrait_DummyIn1; + #ifdef __cplusplus extern "C" { #endif // __cplusplus -struct Dummy0 dummy_Dummy0(struct Dummy0 self, uintptr_t in_); +Dummy0_DummyTrait_DummyOut dummy_Dummy0(struct Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); -int32_t dummy_Dummy1(struct Dummy1 self); +Dummy1_DummyTrait_DummyOut dummy_Dummy1(struct Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/traits_type_tag.pyx b/tests/expectations/traits_type_tag.pyx index da2728a0..d7bd9ca3 100644 --- a/tests/expectations/traits_type_tag.pyx +++ b/tests/expectations/traits_type_tag.pyx @@ -9,9 +9,17 @@ cdef extern from *: cdef struct Dummy0: uintptr_t dummy; + ctypedef Dummy0 Dummy0_DummyTrait_DummyOut; + + ctypedef Dummy0 Dummy0_DummyTrait_DummyIn1; + + ctypedef int32_t Dummy1_DummyTrait_DummyOut; + cdef struct Dummy1: uintptr_t dummy; - Dummy0 dummy_Dummy0(Dummy0 self, uintptr_t in_); + ctypedef uintptr_t Dummy1_DummyTrait_DummyIn1; + + Dummy0_DummyTrait_DummyOut dummy_Dummy0(Dummy0 self, Dummy0_DummyTrait_DummyIn1 _in1); - int32_t dummy_Dummy1(Dummy1 self); + Dummy1_DummyTrait_DummyOut dummy_Dummy1(Dummy1 self, Dummy1_DummyTrait_DummyIn1 _in1); diff --git a/tests/rust/traits_type.rs b/tests/rust/traits_type.rs index 34f45af4..77648d45 100644 --- a/tests/rust/traits_type.rs +++ b/tests/rust/traits_type.rs @@ -1,8 +1,9 @@ pub trait DummyTrait { - type DummyIn; + type DummyIn0; + type DummyIn1; type DummyOut; - extern "C" fn dummy(self, in_: Self::DummyIn) -> Self::DummyOut; + extern "C" fn dummy(self, in0: Self::DummyIn0, in1: Self::DummyIn1) -> Self::DummyOut; } #[repr(C)] @@ -11,13 +12,14 @@ pub struct Dummy0 { } impl DummyTrait for Dummy0 { - type DummyIn = usize; + type DummyIn0 = (); + type DummyIn1 = Self; type DummyOut = Self; #[unsafe(export_name = "dummy_Dummy0")] - extern "C" fn dummy(self, in_: Self::DummyIn) -> Self::DummyOut { + extern "C" fn dummy(self, in0: Self::DummyIn0, _in1: Self::DummyIn1) -> Self::DummyOut { Self { - dummy: in_, + dummy: in0, } } } @@ -28,11 +30,12 @@ pub struct Dummy1 { } impl DummyTrait for Dummy1 { - type DummyIn = (); + type DummyIn0 = (); + type DummyIn1 = usize; type DummyOut = i32; #[unsafe(export_name = "dummy_Dummy1")] - extern "C" fn dummy(self, in_: Self::DummyIn) -> Self::DummyOut { + extern "C" fn dummy(self, _in0: Self::DummyIn0, _in1: Self::DummyIn1) -> Self::DummyOut { 0 } } From 7bccce6e09a308c3865160eb989dafc58c9e90c7 Mon Sep 17 00:00:00 2001 From: Daniil Klimov Date: Fri, 7 Mar 2025 15:24:59 +0300 Subject: [PATCH 8/8] Clippy fix --- src/bindgen/parser.rs | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index b32891f7..5ed188c2 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -702,6 +702,7 @@ impl Parse { } /// Loads a `fn` declaration inside an `impl` block, if the type is a simple identifier + #[allow(clippy::too_many_arguments)] fn load_syn_assoc_methods( &mut self, config: &Config, @@ -766,32 +767,25 @@ impl Parse { // Search and replacement of the type of method with associative // types items_ty.iter().for_each(|&ty| { - if ret_path.name() == &ty.ident.to_string() { - match method.ret.try_set_assoc_name(format!("{}_{}_{}", self_path.name(), trait_ident, ty.ident)) { - Err(e) => { - warn!("It is not possible to chage return type for method {}::{} - ({})", crate_name, method.path.name(), e); - return; - } - Ok(..) => {} + if ty.ident == ret_path.name() { + if let Err(e) = method.ret.try_set_assoc_name(format!("{}_{}_{}", self_path.name(), trait_ident, ty.ident)) { + warn!("It is not possible to chage return type for method {}::{} - ({})", crate_name, method.path.name(), e); + return; } } // Removing all arguments with `void` type method.args.retain(|arg| if let (Some(p), syn::Type::Tuple(syn::TypeTuple { ref elems, .. })) = (arg.ty.get_root_path(), &ty.ty) { - !(elems.is_empty() && p.name() == &ty.ident.to_string()) + !(elems.is_empty() && ty.ident == p.name()) } else { true }); if let Some(arg) = method.args.iter_mut().find(|arg| if let Some(p) = arg.ty.get_root_path() { - p.name() == &ty.ident.to_string() + ty.ident == p.name() } else { false }) { - match arg.ty.try_set_assoc_name(format!("{}_{}_{}", self_path.name(), trait_ident, ty.ident)) { - Err(e) => { - warn!("It is not possible to chage method's argument {}::{} - ({})", crate_name, method.path.name(), e); - return; - } - Ok(..) => {} + if let Err(e) = arg.ty.try_set_assoc_name(format!("{}_{}_{}", self_path.name(), trait_ident, ty.ident)) { + warn!("It is not possible to chage method's argument {}::{} - ({})", crate_name, method.path.name(), e); } } });