Is it possible to access the structure element type for function signatures or declarations?

When defining implementations in macros, it may be useful to access the type of structure elements to avoid having to pass it as an additional argument. (see this question )

impl PartialEq<u32> for MyStruct { ... } 

Is there a way to access the type of a structure element without knowing in advance what type it is?

 impl PartialEq<typeof(MyStruct.member)> for MyStruct { ... } 

In case this is useful, this is a shortened example of why I'm interested in this:

 struct_bitflag_impl!( pub struct MyFlag(u8);, MyFlag, u8); // ^^ how to avoid having this extra arg? // (Used by ``impl PartialEq<$t_internal> for $p``) // couldn't it be discovered from `MyFlag.0` ? // the macro macro_rules! struct_bitflag_impl { ($struct_p_def: item, $p:ident, $t_internal:ty) => { #[derive(PartialEq, Eq, Copy, Clone, Debug)] $struct_p_def impl ::std::ops::BitAnd for $p { type Output = $p; fn bitand(self, _rhs: $p) -> $p { $p(self.0 & _rhs.0) } } impl ::std::ops::BitOr for $p { type Output = $p; fn bitor(self, _rhs: $p) -> $p { $p(self.0 | _rhs.0) } } impl ::std::ops::BitXor for $p { type Output = $p; fn bitxor(self, _rhs: $p) -> $p { $p(self.0 ^ _rhs.0) } } impl ::std::ops::Not for $p { type Output = $p; fn not(self) -> $p { $p(!self.0) } } // support comparison with the base-type. impl PartialEq<$t_internal> for $p { fn eq(&self, other: &t_internal) -> bool { self.0 == *other } } // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // How to avoid using 't_internal' here? } } 
+5
source share
1 answer

No, a generic typeof(Type::field) that can be used in a type position does not exist.


As for the example in the question, it looks like you are expecting a special kind of element: a tuple structure with one field. Thus, instead of accepting the $item snippet, you can simulate the syntax yourself:

 macro_rules! foo { (pub struct $name:ident ( $ty:ident ) ) => { pub struct $name($ty); impl $name { pub fn bar() { println!("{}", stringify!($ty)); } } } } foo!( pub struct Peter(u8) ); fn main() { Peter::bar(); } 

Thus, you only need to specify everything once. However, this obviously only works with the definition of the tuple-struct type, and not with all element types. But your use case suggests that you are more or less interested in this particular case.

If you want to allow different definitions of structures, you just need to add macros to the macro to allow different syntax. To see an example, here is the code that allows you to define a tuple-struct pub and not a pub . But it can be further expanded.

+4
source

Source: https://habr.com/ru/post/1259676/


All Articles