-
Notifications
You must be signed in to change notification settings - Fork 1
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
Return references from map_ref
?
#2
Comments
I'm afraid this is a bit hard. When you hold a
I just found that both of them are not achievable since there's no |
Sadly, it seems to me that there's no feasible solution to this. |
Maybe we can implement something like struct Ref<'a, T> {
inner: ManuallyDrop<T>,
marker: PhantomData<&'a T>,
}
impl<T: Deref> Deref for Ref<'_, T> {
type Target = <T as Deref>::Target;
fn deref(&self) -> &Self::Target {
self.inner.deref()
}
} And then generate: #[repr(C, usize)]
enum FooRef {
A(Ref<Box<Bar>>),
B(Ref<Box<u64>>),
} Thinking for a while... Personally I don't like generating structs in user code. That's somewhat invasive. |
I tried to implement the However, the use enum_ptr::{Compact, EnumPtr};
// used to specify lifetime
unsafe fn take_ref_helper<'a, T, U>(
compact: &'a Compact<T>,
f: impl FnOnce(&T) -> Option<&'a U>,
) -> Option<&'a U>
where
T: From<Compact<T>>,
Compact<T>: From<T>,
{
compact.map_ref(f)
}
macro_rules! take_ref {
($compact:expr, $($variant:tt)*) => {
unsafe {
take_ref_helper($compact, |extracted| match extracted {
$($variant)*(inner) => Some(&*(::std::ops::Deref::deref(inner) as *const _)),
_ => None,
})
}
};
}
#[test]
fn main() {
#[derive(Debug, EnumPtr)]
#[repr(C, usize)]
enum Foo<'a> {
A(&'a i32),
B(Box<i64>),
}
let compact_foo = Compact::from(Foo::A(&42));
dbg!(take_ref!(&compact_foo, Foo::A));
let compact_foo = Compact::from(Foo::B(Box::new(43)));
dbg!(take_ref!(&compact_foo, Foo::B));
} One drawback of this solution is that it cannot handle named variants. But I have already decided to remove named variant support since 0.2.0. So it's not a big problem. Another drawback is that this API is troublesome when you deal with multiple branches at once. I'm still searching for a better solution. I won't put this API into my crate any time soon. I need more time to think. |
I'm sorry to find that I have come up with a solution that might work for all pointers excluding |
Finally, I made it. I released a beta version, check it out. https://crates.io/crates/enum-ptr/0.2.0-beta.0 |
Hi, thank you for making this crate.
I'd find it very useful to return refernces from
map_ref
, like this:I don't know if this is possible to achieve without UB, but it would be nice for sure.
The text was updated successfully, but these errors were encountered: