I don't seem to understand the compiler error message here. For the following snippet
use std::pin::Pin;
use std::future::Future;
fn give_future<'a>(x : &'a i32) -> Pin<impl Future<Output=&'a i32> + 'a> {
Box::pin(async move { x })
}
it says the following
error[E0277]: `[async block@src/lib.rs]` cannot be unpinned
--> src/lib.rs:7:47
|
| fn give_future<'a>(x : &'a i32) -> Pin<impl Future<Output=&'a i32> + 'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `[async block@src/lib.rs]`
|
= note: consider using the `pin!` macro
consider using `Box::pin` if you need to access the pinned value outside of the current scope
= note: required for `Box<[async block@src/lib.rs]>` to implement `Future`
For more information about this error, try `rustc --explain E0277`.
From what I understand, Pinx<Box<impl Future>>
is being returned as Pin<impl Future>
. Why isn't the compiler just saying that?
From what I understand,
Pin<Box<impl Future>>
is being returned asPin<impl Future>
. Why isn't the compiler just saying that?
The basis for what you've written could be a perfectly viable thing to do. Probably not with Pin
in particular (since it is quite narrow and nuanced in its functionality) but masquerading Box<T>
as impl Trait
is a thing that is done all the time to avoid leaking internal details and can work because traits are commonly implemented on Box<T>
s where T: Trait
.
So the compiler is simply trying to satisfy your request. To do so it only needs to verify that Box<T>
implements Future
, and it has an implementation but only if that T
implements Unpin
. And thus you get the error.