-
Notifications
You must be signed in to change notification settings - Fork 386
The ability to generate trait methods using types #1054
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
46764bb
6f8fa31
602172d
d3252cf
740f41c
99be358
847794a
7bccce6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I'm a bit confused as to what are you trying to do here. Can you add some comments to clarify? Let's see if I get this right... When you see a method, you go through the return and argument types, and try to fix them up by matching with the associated types. I don't think this is quite the right thing to do. I guess this does work for very simple cases, but:
And then
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @emilio in my first trial version, the implementation was approximately the way you described, but I thought that it would be excessive. If you think that it will be better - I will do so |
||
| 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, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| dummy_Dummy0; | ||
| dummy_Dummy1; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #include <stdarg.h> | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| 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); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #include <stdarg.h> | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #include <cstdarg> | ||
| #include <cstdint> | ||
| #include <cstdlib> | ||
| #include <ostream> | ||
| #include <new> | ||
|
|
||
| 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" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #include <stdarg.h> | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| 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); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #include <stdarg.h> | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #include <stdarg.h> | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| 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); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #include <stdarg.h> | ||
| #include <stdbool.h> | ||
| #include <stdint.h> | ||
| #include <stdlib.h> | ||
|
|
||
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This array seems wrong, it's not storing
impls, but ident and types, so maybe just call the vectorassociated_tysor so?