Skip to main content

diskann_utils/
future.rs

1/*
2 * Copyright (c) Microsoft Corporation.
3 * Licensed under the MIT license.
4 */
5
6////////////////
7// SendFuture //
8////////////////
9
10/// A simplified type alias for `Future<Output = T> + Send`.
11pub trait SendFuture<T>: core::future::Future<Output = T> + Send {}
12impl<T, U> SendFuture<T> for U where U: core::future::Future<Output = T> + Send {}
13
14///////////////////
15// AsyncFriendly //
16///////////////////
17
18/// The bounds `Send + Sync + 'static` are often required by type parameters to make Futures
19/// `Send + Sync + 'static`.
20///
21/// This trait bundles these into a single super-trait for convenience.
22pub trait AsyncFriendly: Send + Sync + 'static {}
23impl<T> AsyncFriendly for T where T: Send + Sync + 'static {}
24
25////////////////
26// AssertSend //
27////////////////
28
29/// If your future is not `Send` enough, try this.
30///
31/// Async functions (i.e., those with the keyword async) rely on type inference to
32/// automatically derive `Send` and `Sync` bounds for the returned `Future`s. Unfortunately,
33/// `rustc` seems to throw away quite a bit of information when building large futures like
34/// we have in `diskann_async`, which can result in large futures failing to be `Send`
35/// due to the bound on an inner `Future` being forgotten.
36///
37/// The [`AssertSend`] is a hack that helps `rustc` realize that interior `Future`s are
38/// indeed `Send` and helps when proving the auto trait for larger `Future`s.
39///
40/// This is mainly helpful when async functions take closures.
41pub trait AssertSend: core::future::Future {
42    fn send(self) -> impl core::future::Future<Output = Self::Output> + Send
43    where
44        Self: Sized + Send,
45    {
46        self
47    }
48}
49
50impl<T: core::future::Future> AssertSend for T {}
51
52///////////
53// boxit //
54///////////
55
56/// Type erase the provided future by boxing it.
57///
58/// THis can potentially help with compilation time and future size bloat by factoring out
59/// pieces of larger futures into opaque chunks.
60pub fn boxit<'a, T>(
61    fut: impl core::future::Future<Output = T> + Send + 'a,
62) -> core::pin::Pin<Box<dyn core::future::Future<Output = T> + Send + 'a>> {
63    Box::pin(fut)
64}