VirtualAddressSpaceIndpendent: use trait bounds in derive macro#2772
VirtualAddressSpaceIndpendent: use trait bounds in derive macro#2772sporksmith merged 6 commits intoshadow:mainfrom
Conversation
|
Oops, was supposed to be a Draft. It looks like there's no way to make a PR into a Draft once it's non-Draft? |
|
An alternative approach I'm tinkering with is to add a method to the Vasi trait, and access the fields by name in the body instead of trying to name the (possibly generic) types of the fields. It looks like this could actually work but requires additional complexity to deal with unnamed fields, enum variants, union fields (which need unsafe access), ... Anyway the idea is to change the vasi trait declaration to: and then in the macro, for |
|
@stevenengler if you get a chance to look at this, maybe you have a better idea how to do this? |
|
I'm still not sure I understand completely, but could you do something more like the So something like: #[derive(VirtualAddressSpaceIndependent)]
struct MyWrapper<T, K> {
foo: Option<T>,
bar: u32,
asdf: K
}becomes: struct MyWrapper<T, K> {
foo: Option<T>,
bar: u32,
asdf: K
}
assert_impl_all!(u32: vasi::VirtualAddressSpaceIndependent);
unsafe impl<T, K> VirtualAddressSpaceIndependent for MyWrapper<T, K>
where
Option<T>: VirtualAddressSpaceIndependent,
K: VirtualAddressSpaceIndependent,
{} |
|
My understanding is that the derive macro for According to https://stegosaurusdormant.com/understanding-derive-clone/#do-we-have-to-inspect-the-fields this is because making the constraints on the field types can leak private types into the public interface, which results in compilation errors. Maybe we could live with that limitation, though. |
|
Ah okay, I wondered then what happens if |
|
Here's another idea to avoid requiring a method in the trait. It still needs to access each field though: |
|
Or maybe one of these so that you don't need to access each field: https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=3a0c36ad9b478208d194d6762dab095a |
a11abbb to
84d308c
Compare
|
I think we're miscommunicating. My understanding (and I think this matches what you're saying) is that e.g. for:
OTOH for a struct definition is then there will be a compilation failure since i.e. this is different from your earlier example that would emit Anyways, I think I've gotten something working, and the ideas in your gist were definitely helpful - particularly using a trait const instead of a trait method seems a little nicer, and facilitates ensuring the code is never called at runtime (and probably dropped from the final binary). It's currently checking the field values, though I may revisit your idea that uses the types instead. I'll take another look at that and clean up a bit before marking it for review. |
11a6a6f to
74d8290
Compare
74d8290 to
435c24f
Compare
|
I think this is ready now! Thanks for the help and ideas! |
This extends the macro to handle types with generic type parameters. It takes the same approach as e.g. `Copy` and `Clone` in std: the type will *conditionally* implement the trait if all of the generic type parameters do, and will fail to compile if any field isn't actually VirtualAddressSpaceIndependent.
435c24f to
6158f15
Compare
Extends the VirtualAddressSpaceIndependent Derive macro to handle generics, and replaces manual implementation of the trait by using the derive macro.
(Previously:)