Future::boxed in Asynchronous Programming in Rust

I'm reading Applied: Build an Executor, and there is a code snippet:

use futures::{
    future::{BoxFuture, FutureExt},
    task::{waker_ref, ArcWake},
};
use std::{
    future::Future,
    sync::mpsc::{sync_channel, Receiver, SyncSender},
    sync::{Arc, Mutex},
    task::Context,
    time::Duration,
};
// The timer we wrote in the previous section:
use timer_future::TimerFuture;

impl Spawner {
    fn spawn(&self, future: impl Future<Output = ()> + 'static + Send) {
        let future = future.boxed(); // <----- this line !
        let task = Arc::new(Task {
            future: Mutex::new(Some(future)),
            task_sender: self.task_sender.clone(),
        });
        self.task_sender.send(task).expect("too many tasks queued");
    }
}

The type of future in the method spawn is impl std::future::Future<Output = ()>, but std::future::Future doesn't have a method called boxed.

However the code can be compiled and run, and I don't know how this could be possible.

I believe boxed is brought into scope through either BoxFuture or FutureExt.

1 Like

It's FutureExt

But I'm still confused.

To use the method boxed from the trait FutureExt, why does the signature of method spawn need not to be:

fn spawn(&self, future: impl Future<Output = ()> + FutureExt + 'static + Send)

FutureExt has a blanket impl for all types that implement Future. So when the trait is in scope all Futures are implicitly also FutureExts.

2 Likes