-
Notifications
You must be signed in to change notification settings - Fork 60
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
When, if ever, are extern "Rust"
ABIs compatible with each other?
#280
Comments
See also: When can function pointers be transmuted? But in general, this is not guaranteed. The default Instead, I suggest creating a wrapper function: unsafe fn poll_wrap<'r, 's, 't0, F: Future + 'r>(this: Pin<&'r mut ()>, ctx: &'s mut Context<'t0>) -> Poll<F::Output> {
let f_raw: *mut F = Pin::into_inner_unchecked(this) as *mut _ as *mut _;
let f_pin: Pin<&'r mut F> = Pin::new_unchecked(&mut *f_raw);
f_pin.poll(ctx)
} Then you can convert that into a function pointer, since its signature doesn't depend on the future type. |
If
No, |
I don't think that's quite right. If |
I am pretty sure that the moment you write |
yeah that sure sounds like a miri error. you shouldn't have a reference with access to more span than the size of its type (as far as i know). |
Great idea! Ran into some lifetime issues, so we ended up getting rid of unsafe fn poll_wrap<'s, 't0, F: Future>(this: Pin<&mut Buffer>, ctx: &'s mut Context<'t0>) -> Poll<F::Output> {
let pin : Pin<&mut F> = this.map_unchecked_mut(|slf| transmute::<&mut Buffer, &mut F>(slf));
pin.poll(ctx)
} To address @bjorn3 's concern, we do (note: this is joint work with @jswrenn) AppendixWe use our own custom #[inline(always)]
unsafe fn transmute<Src, Dst>(src: Src) -> Dst
{
use core::mem::ManuallyDrop;
#[repr(C)]
union Transmute<Src, Dst> {
src: ManuallyDrop<Src>,
dst: ManuallyDrop<Dst>,
}
ManuallyDrop::into_inner(Transmute { src: ManuallyDrop::new(src) }.dst)
} |
Well, you shouldn't need Edit: But I think it is sound with or without |
OK great, thanks! |
What concrete example is a Miri error? When you transmute a fn ptr, what effectively happens is that on a call, the argument is transmuted from the caller type to the callee type. In this case the argument seem to not be a reference but a |
extern "Rust"
ABIs compatible with each other?
This question was originally discussed on Twitter here.
I'm trying to write a library to stack-allocate
dyn Future
objects. The core of this code is the following:When a
DynamicFuture
is created, the static type of the future is known, andpoll_fn
is set to<F as Future>::poll
. Then, in the implementation ofFuture for DynamicFuture
, thedata
field is converted to aPin<&mut ()>
, andpoll_fn
is called on it.My question is: Is the ABI of
<F as Future>::poll
(type signature:for<'r, 's, 't0> fn(Pin<&'r mut F>, &'s mut Context<'t0>) -> Poll<_>
guaranteed to be the same as the ABI ofpoll_fn
(identical type signature except forPin<&'r mut ()>
instead ofPin<&'r mut F>
)? If so, is it sound to callpoll_fn
by constructing aPin<&mut ()>
from thedata
field?The text was updated successfully, but these errors were encountered: