And I need to pass it to the function that requires also 'static bound (sure, allocating on heap is easy, but it is also wasteful)
Is there a way to add 'static bound to both F and F::Output without resolving to heap allocations?
My code guarantees that F will live long enough.
in this context variable is owned and let's say worker, that is going to use it, will not be able to outlive it.
Requiring 'static there affects any Future that borrows (e.g. generated from async method)
I sure wish I could just use transmute, but there is a problem is that I cannot really do: let f: F + 'static = unsafe { mem::transmute(self) }
It doesn't make much sense to compiler and using transmute together with await doesn't work because type will be ambigious unless I manually specify it (mostly because I also used in async block)
You can create a function that returns your transmuted data with an extended lifetime. I think it will be inlined by the compiler, so there won't be any overhead.
It is what I have right now.
And I pass it to tokio::runtime::Runtime::spawn
The problem is that if I pass future that gets created from <MyObject>::async_method() where async method borrows object, it will extend lifetime of borrow to static.
But I specifically want to spawn and await for completetion without extending lifetime (I do so with pseudo condvar)
Easiest solution would be to use block_on but then I would need to prevent concurrent calls to it...
Which I think now might be easier rather than hacking this 'static bug
P.s. as this is C library, I have to make Runtime static
This sadly adds Unpin requirement as any reference to Future require it and unchecked Pin doesn't help much as it still requires static (I tried static reference already )
In this case do you think you could desugar the async method to this,
impl MyObject {
fn async_method(&self, args: Args) -> impl Future<Output = ???> + 'static {
async move {
// here move what you need into the future, without extending the lifetime of self
}
}
}
I wish it would be so simple... but that would require boxing parts of self which I'd prefer to avoid as this is just work-around for compiler bugs (there is no actual need for that)
Worst case I'll just have to make API more ugly to not borrow at all...
There are three ways of assigning a 'static lifetime:
Declaring a variable with the static keyword
Allocating and memory on the heap
Closures, that don't capture variables by reference (use the move keyword) and function pointers
Not even
fn main() {
let a: usize = 1;
let b: &'static usize = &a;
}
works. You'll get an error message, that tells you "a does not live long enough", because it is dropped at the end of main while b is still borrowed, because the end of main is technically not the end of program.
async-std provides a different implementation of block_on if you can't use it directly, then at least you can model this off of async-std's implementation.
This is giving me a headache. You cannot consume a static value, i.e. self must be a reference and in conclusion you have to implement Future for the reference of one of your types and that type must be static, because functions and closures cannot implement traits.
You'd need something like this:
// It doesn't make sense to implement it for &mut MyType, because you cannot safely mutate static values.
impl Future for &MyType {
// [...]
}
static MY_TYPE: MyType = /* [...] */;
fn some_function() {
let result = MY_TYPE.wait();
// [...]
}
I can't imagine that this is what you want, though. It just looks so weird to me.