I am trying to store a tokio::Timeout struct within a structure. My intent is for the structure to own it. I see that Timeout<T> is bounded with Sized, but my thought was Timeout would have already satisfied the compiler.
use std::future::Future;
use tokio::time::{error::Elapsed, timeout, Timeout};
struct SockTimeout {
pub timeout: Timeout<dyn Future<Output = ()>>,
}
#[tokio::main]
async fn main() {
let when = Duration::from_millis(2000);
let my_struct = SockTimeout {
timeout: timeout(when, async {}),
};
}
error[E0277]: the size for values of type `(dyn Future<Output = ()> + 'static)` cannot be known at compilation time
--> src/main.rs:30:18
|
30 | pub timeout: Timeout<dyn Future<Output = ()>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn Future<Output = ()> + 'static)`
note: required by a bound in `tokio::time::Timeout`
--> /Users/steve/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.19.2/src/time/timeout.rs:135:24
|
135 | pub struct Timeout<T> {
| ^ required by this bound in `tokio::time::Timeout`
The only way I have found around this issue is to turn SockTimeout into a template. I have tried Box‘ing Timeout, but the same issue persists. What am I fundamentally missing here?
>Solution :
Boxing the Timeout won’t help because Timeout<T> requires that T: Sized, not just that Timeout<T>: Sized. Instead you need to box the future.
You may also need to pin it:
struct SockTimeout {
pub timeout: Timeout<Pin<Box<dyn Future<Output = ()>>>>,
}
#[tokio::main]
async fn main() {
let when = Duration::from_millis(2000);
let my_struct = SockTimeout {
timeout: timeout(when, Box::pin(async {})),
};
}