futures_lite/
future.rs

1//! Combinators for the [`Future`] trait.
2//!
3//! # Examples
4//!
5//! ```
6//! use futures_lite::future;
7//!
8//! # spin_on::spin_on(async {
9//! for step in 0..3 {
10//!     println!("step {}", step);
11//!
12//!     // Give other tasks a chance to run.
13//!     future::yield_now().await;
14//! }
15//! # });
16//! ```
17
18#[doc(no_inline)]
19pub use core::future::{pending, ready, Future, Pending, Ready};
20
21use core::fmt;
22use core::pin::Pin;
23use core::task::{Context, Poll};
24
25#[cfg(feature = "alloc")]
26use alloc::boxed::Box;
27
28#[cfg(feature = "std")]
29use std::{
30    any::Any,
31    panic::{catch_unwind, AssertUnwindSafe, UnwindSafe},
32    thread_local,
33};
34
35#[cfg(feature = "race")]
36use fastrand::Rng;
37use pin_project_lite::pin_project;
38
39/// Blocks the current thread on a future.
40///
41/// # Examples
42///
43/// ```
44/// use futures_lite::future;
45///
46/// let val = future::block_on(async {
47///     1 + 2
48/// });
49///
50/// assert_eq!(val, 3);
51/// ```
52#[cfg(feature = "std")]
53pub fn block_on<T>(future: impl Future<Output = T>) -> T {
54    use core::cell::RefCell;
55    use core::task::Waker;
56
57    use parking::Parker;
58
59    // Pin the future on the stack.
60    crate::pin!(future);
61
62    // Creates a parker and an associated waker that unparks it.
63    fn parker_and_waker() -> (Parker, Waker) {
64        let parker = Parker::new();
65        let unparker = parker.unparker();
66        let waker = Waker::from(unparker);
67        (parker, waker)
68    }
69
70    thread_local! {
71        // Cached parker and waker for efficiency.
72        static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker());
73    }
74
75    CACHE.with(|cache| {
76        // Try grabbing the cached parker and waker.
77        let tmp_cached;
78        let tmp_fresh;
79        let (parker, waker) = match cache.try_borrow_mut() {
80            Ok(cache) => {
81                // Use the cached parker and waker.
82                tmp_cached = cache;
83                &*tmp_cached
84            }
85            Err(_) => {
86                // Looks like this is a recursive `block_on()` call.
87                // Create a fresh parker and waker.
88                tmp_fresh = parker_and_waker();
89                &tmp_fresh
90            }
91        };
92
93        let cx = &mut Context::from_waker(waker);
94        // Keep polling until the future is ready.
95        loop {
96            match future.as_mut().poll(cx) {
97                Poll::Ready(output) => return output,
98                Poll::Pending => parker.park(),
99            }
100        }
101    })
102}
103
104/// Polls a future just once and returns an [`Option`] with the result.
105///
106/// # Examples
107///
108/// ```
109/// use futures_lite::future;
110///
111/// # spin_on::spin_on(async {
112/// assert_eq!(future::poll_once(future::pending::<()>()).await, None);
113/// assert_eq!(future::poll_once(future::ready(42)).await, Some(42));
114/// # })
115/// ```
116pub fn poll_once<T, F>(f: F) -> PollOnce<F>
117where
118    F: Future<Output = T>,
119{
120    PollOnce { f }
121}
122
123pin_project! {
124    /// Future for the [`poll_once()`] function.
125    #[must_use = "futures do nothing unless you `.await` or poll them"]
126    pub struct PollOnce<F> {
127        #[pin]
128        f: F,
129    }
130}
131
132impl<F> fmt::Debug for PollOnce<F> {
133    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134        f.debug_struct("PollOnce").finish()
135    }
136}
137
138impl<T, F> Future for PollOnce<F>
139where
140    F: Future<Output = T>,
141{
142    type Output = Option<T>;
143
144    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
145        match self.project().f.poll(cx) {
146            Poll::Ready(t) => Poll::Ready(Some(t)),
147            Poll::Pending => Poll::Ready(None),
148        }
149    }
150}
151
152/// Creates a future from a function returning [`Poll`].
153///
154/// # Examples
155///
156/// ```
157/// use futures_lite::future;
158/// use std::task::{Context, Poll};
159///
160/// # spin_on::spin_on(async {
161/// fn f(_: &mut Context<'_>) -> Poll<i32> {
162///     Poll::Ready(7)
163/// }
164///
165/// assert_eq!(future::poll_fn(f).await, 7);
166/// # })
167/// ```
168pub fn poll_fn<T, F>(f: F) -> PollFn<F>
169where
170    F: FnMut(&mut Context<'_>) -> Poll<T>,
171{
172    PollFn { f }
173}
174
175pin_project! {
176    /// Future for the [`poll_fn()`] function.
177    #[must_use = "futures do nothing unless you `.await` or poll them"]
178    pub struct PollFn<F> {
179        f: F,
180    }
181}
182
183impl<F> fmt::Debug for PollFn<F> {
184    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185        f.debug_struct("PollFn").finish()
186    }
187}
188
189impl<T, F> Future for PollFn<F>
190where
191    F: FnMut(&mut Context<'_>) -> Poll<T>,
192{
193    type Output = T;
194
195    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
196        let this = self.project();
197        (this.f)(cx)
198    }
199}
200
201/// Wakes the current task and returns [`Poll::Pending`] once.
202///
203/// This function is useful when we want to cooperatively give time to the task scheduler. It is
204/// generally a good idea to yield inside loops because that way we make sure long-running tasks
205/// don't prevent other tasks from running.
206///
207/// # Examples
208///
209/// ```
210/// use futures_lite::future;
211///
212/// # spin_on::spin_on(async {
213/// future::yield_now().await;
214/// # })
215/// ```
216pub fn yield_now() -> YieldNow {
217    YieldNow(false)
218}
219
220/// Future for the [`yield_now()`] function.
221#[derive(Debug)]
222#[must_use = "futures do nothing unless you `.await` or poll them"]
223pub struct YieldNow(bool);
224
225impl Future for YieldNow {
226    type Output = ();
227
228    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
229        if !self.0 {
230            self.0 = true;
231            cx.waker().wake_by_ref();
232            Poll::Pending
233        } else {
234            Poll::Ready(())
235        }
236    }
237}
238
239/// Joins two futures, waiting for both to complete.
240///
241/// # Examples
242///
243/// ```
244/// use futures_lite::future;
245///
246/// # spin_on::spin_on(async {
247/// let a = async { 1 };
248/// let b = async { 2 };
249///
250/// assert_eq!(future::zip(a, b).await, (1, 2));
251/// # })
252/// ```
253pub fn zip<F1, F2>(future1: F1, future2: F2) -> Zip<F1, F2>
254where
255    F1: Future,
256    F2: Future,
257{
258    Zip {
259        future1: Some(future1),
260        future2: Some(future2),
261        output1: None,
262        output2: None,
263    }
264}
265
266pin_project! {
267    /// Future for the [`zip()`] function.
268    #[derive(Debug)]
269    #[must_use = "futures do nothing unless you `.await` or poll them"]
270    pub struct Zip<F1, F2>
271    where
272        F1: Future,
273        F2: Future,
274    {
275        #[pin]
276        future1: Option<F1>,
277        output1: Option<F1::Output>,
278        #[pin]
279        future2: Option<F2>,
280        output2: Option<F2::Output>,
281    }
282}
283
284/// Extracts the contents of two options and zips them, handling `(Some(_), None)` cases
285fn take_zip_from_parts<T1, T2>(o1: &mut Option<T1>, o2: &mut Option<T2>) -> Poll<(T1, T2)> {
286    match (o1.take(), o2.take()) {
287        (Some(t1), Some(t2)) => Poll::Ready((t1, t2)),
288        (o1x, o2x) => {
289            *o1 = o1x;
290            *o2 = o2x;
291            Poll::Pending
292        }
293    }
294}
295
296impl<F1, F2> Future for Zip<F1, F2>
297where
298    F1: Future,
299    F2: Future,
300{
301    type Output = (F1::Output, F2::Output);
302
303    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
304        let mut this = self.project();
305
306        if let Some(future) = this.future1.as_mut().as_pin_mut() {
307            if let Poll::Ready(out) = future.poll(cx) {
308                *this.output1 = Some(out);
309                this.future1.set(None);
310            }
311        }
312
313        if let Some(future) = this.future2.as_mut().as_pin_mut() {
314            if let Poll::Ready(out) = future.poll(cx) {
315                *this.output2 = Some(out);
316                this.future2.set(None);
317            }
318        }
319
320        take_zip_from_parts(this.output1, this.output2)
321    }
322}
323
324/// Joins two fallible futures, waiting for both to complete or one of them to error.
325///
326/// # Examples
327///
328/// ```
329/// use futures_lite::future;
330///
331/// # spin_on::spin_on(async {
332/// let a = async { Ok::<i32, i32>(1) };
333/// let b = async { Err::<i32, i32>(2) };
334///
335/// assert_eq!(future::try_zip(a, b).await, Err(2));
336/// # })
337/// ```
338pub fn try_zip<T1, T2, E, F1, F2>(future1: F1, future2: F2) -> TryZip<F1, T1, F2, T2>
339where
340    F1: Future<Output = Result<T1, E>>,
341    F2: Future<Output = Result<T2, E>>,
342{
343    TryZip {
344        future1: Some(future1),
345        future2: Some(future2),
346        output1: None,
347        output2: None,
348    }
349}
350
351pin_project! {
352    /// Future for the [`try_zip()`] function.
353    #[derive(Debug)]
354    #[must_use = "futures do nothing unless you `.await` or poll them"]
355    pub struct TryZip<F1, T1, F2, T2> {
356        #[pin]
357        future1: Option<F1>,
358        output1: Option<T1>,
359        #[pin]
360        future2: Option<F2>,
361        output2: Option<T2>,
362    }
363}
364
365impl<T1, T2, E, F1, F2> Future for TryZip<F1, T1, F2, T2>
366where
367    F1: Future<Output = Result<T1, E>>,
368    F2: Future<Output = Result<T2, E>>,
369{
370    type Output = Result<(T1, T2), E>;
371
372    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
373        let mut this = self.project();
374
375        if let Some(future) = this.future1.as_mut().as_pin_mut() {
376            if let Poll::Ready(out) = future.poll(cx) {
377                match out {
378                    Ok(t) => {
379                        *this.output1 = Some(t);
380                        this.future1.set(None);
381                    }
382                    Err(err) => return Poll::Ready(Err(err)),
383                }
384            }
385        }
386
387        if let Some(future) = this.future2.as_mut().as_pin_mut() {
388            if let Poll::Ready(out) = future.poll(cx) {
389                match out {
390                    Ok(t) => {
391                        *this.output2 = Some(t);
392                        this.future2.set(None);
393                    }
394                    Err(err) => return Poll::Ready(Err(err)),
395                }
396            }
397        }
398
399        take_zip_from_parts(this.output1, this.output2).map(Ok)
400    }
401}
402
403/// Returns the result of the future that completes first, preferring `future1` if both are ready.
404///
405/// If you need to treat the two futures fairly without a preference for either, use the [`race()`]
406/// function or the [`FutureExt::race()`] method.
407///
408/// # Examples
409///
410/// ```
411/// use futures_lite::future::{self, pending, ready};
412///
413/// # spin_on::spin_on(async {
414/// assert_eq!(future::or(ready(1), pending()).await, 1);
415/// assert_eq!(future::or(pending(), ready(2)).await, 2);
416///
417/// // The first future wins.
418/// assert_eq!(future::or(ready(1), ready(2)).await, 1);
419/// # })
420/// ```
421pub fn or<T, F1, F2>(future1: F1, future2: F2) -> Or<F1, F2>
422where
423    F1: Future<Output = T>,
424    F2: Future<Output = T>,
425{
426    Or { future1, future2 }
427}
428
429pin_project! {
430    /// Future for the [`or()`] function and the [`FutureExt::or()`] method.
431    #[derive(Debug)]
432    #[must_use = "futures do nothing unless you `.await` or poll them"]
433    pub struct Or<F1, F2> {
434        #[pin]
435        future1: F1,
436        #[pin]
437        future2: F2,
438    }
439}
440
441impl<T, F1, F2> Future for Or<F1, F2>
442where
443    F1: Future<Output = T>,
444    F2: Future<Output = T>,
445{
446    type Output = T;
447
448    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
449        let this = self.project();
450
451        if let Poll::Ready(t) = this.future1.poll(cx) {
452            return Poll::Ready(t);
453        }
454        if let Poll::Ready(t) = this.future2.poll(cx) {
455            return Poll::Ready(t);
456        }
457        Poll::Pending
458    }
459}
460
461/// Fuse a future such that `poll` will never again be called once it has
462/// completed. This method can be used to turn any `Future` into a
463/// `FusedFuture`.
464///
465/// Normally, once a future has returned `Poll::Ready` from `poll`,
466/// any further calls could exhibit bad behavior such as blocking
467/// forever, panicking, never returning, etc. If it is known that `poll`
468/// may be called too often then this method can be used to ensure that it
469/// has defined semantics.
470///
471/// If a `fuse`d future is `poll`ed after having returned `Poll::Ready`
472/// previously, it will return `Poll::Pending`, from `poll` again (and will
473/// continue to do so for all future calls to `poll`).
474///
475/// This combinator will drop the underlying future as soon as it has been
476/// completed to ensure resources are reclaimed as soon as possible.
477pub fn fuse<F>(future: F) -> Fuse<F>
478where
479    F: Future + Sized,
480{
481    Fuse::new(future)
482}
483
484pin_project! {
485    /// [`Future`] for the [`fuse`] method.
486    #[derive(Debug)]
487    #[must_use = "futures do nothing unless you `.await` or poll them"]
488    pub struct Fuse<Fut> {
489        #[pin]
490        inner: Option<Fut>,
491    }
492}
493
494impl<Fut> Fuse<Fut> {
495    fn new(f: Fut) -> Self {
496        Self { inner: Some(f) }
497    }
498}
499
500impl<Fut: Future> Future for Fuse<Fut> {
501    type Output = Fut::Output;
502
503    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Fut::Output> {
504        match self
505            .as_mut()
506            .project()
507            .inner
508            .as_pin_mut()
509            .map(|f| f.poll(cx))
510        {
511            Some(Poll::Ready(output)) => {
512                self.project().inner.set(None);
513                Poll::Ready(output)
514            }
515
516            Some(Poll::Pending) | None => Poll::Pending,
517        }
518    }
519}
520
521/// Returns the result of the future that completes first, with no preference if both are ready.
522///
523/// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore, no
524/// future takes precedence over the other if both can complete at the same time.
525///
526/// If you have preference for one of the futures, use the [`or()`] function or the
527/// [`FutureExt::or()`] method.
528///
529/// # Examples
530///
531/// ```
532/// use futures_lite::future::{self, pending, ready};
533///
534/// # spin_on::spin_on(async {
535/// assert_eq!(future::race(ready(1), pending()).await, 1);
536/// assert_eq!(future::race(pending(), ready(2)).await, 2);
537///
538/// // One of the two futures is randomly chosen as the winner.
539/// let res = future::race(ready(1), ready(2)).await;
540/// # })
541/// ```
542#[cfg(all(feature = "race", feature = "std"))]
543pub fn race<T, F1, F2>(future1: F1, future2: F2) -> Race<F1, F2>
544where
545    F1: Future<Output = T>,
546    F2: Future<Output = T>,
547{
548    Race {
549        future1,
550        future2,
551        rng: Rng::new(),
552    }
553}
554
555/// Race two futures but with a predefined random seed.
556///
557/// This function is identical to [`race`], but instead of using a random seed from a thread-local
558/// RNG, it allows the user to provide a seed. It is useful for when you already have a source of
559/// randomness available, or if you want to use a fixed seed.
560///
561/// See documentation of the [`race`] function for features and caveats.
562///
563/// # Examples
564///
565/// ```
566/// use futures_lite::future::{self, pending, ready};
567///
568/// // A fixed seed is used, so the result is deterministic.
569/// const SEED: u64 = 0x42;
570///
571/// # spin_on::spin_on(async {
572/// assert_eq!(future::race_with_seed(ready(1), pending(), SEED).await, 1);
573/// assert_eq!(future::race_with_seed(pending(), ready(2), SEED).await, 2);
574///
575/// // One of the two futures is randomly chosen as the winner.
576/// let res = future::race_with_seed(ready(1), ready(2), SEED).await;
577/// # })
578/// ```
579#[cfg(feature = "race")]
580pub fn race_with_seed<T, F1, F2>(future1: F1, future2: F2, seed: u64) -> Race<F1, F2>
581where
582    F1: Future<Output = T>,
583    F2: Future<Output = T>,
584{
585    Race {
586        future1,
587        future2,
588        rng: Rng::with_seed(seed),
589    }
590}
591
592#[cfg(feature = "race")]
593pin_project! {
594    /// Future for the [`race()`] function and the [`FutureExt::race()`] method.
595    #[derive(Debug)]
596    #[must_use = "futures do nothing unless you `.await` or poll them"]
597    pub struct Race<F1, F2> {
598        #[pin]
599        future1: F1,
600        #[pin]
601        future2: F2,
602        rng: Rng,
603    }
604}
605
606#[cfg(feature = "race")]
607impl<T, F1, F2> Future for Race<F1, F2>
608where
609    F1: Future<Output = T>,
610    F2: Future<Output = T>,
611{
612    type Output = T;
613
614    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
615        let this = self.project();
616
617        if this.rng.bool() {
618            if let Poll::Ready(t) = this.future1.poll(cx) {
619                return Poll::Ready(t);
620            }
621            if let Poll::Ready(t) = this.future2.poll(cx) {
622                return Poll::Ready(t);
623            }
624        } else {
625            if let Poll::Ready(t) = this.future2.poll(cx) {
626                return Poll::Ready(t);
627            }
628            if let Poll::Ready(t) = this.future1.poll(cx) {
629                return Poll::Ready(t);
630            }
631        }
632        Poll::Pending
633    }
634}
635
636#[cfg(feature = "std")]
637pin_project! {
638    /// Future for the [`FutureExt::catch_unwind()`] method.
639    #[derive(Debug)]
640    #[must_use = "futures do nothing unless you `.await` or poll them"]
641    pub struct CatchUnwind<F> {
642        #[pin]
643        inner: F,
644    }
645}
646
647#[cfg(feature = "std")]
648impl<F: Future + UnwindSafe> Future for CatchUnwind<F> {
649    type Output = Result<F::Output, Box<dyn Any + Send>>;
650
651    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
652        let this = self.project();
653        catch_unwind(AssertUnwindSafe(|| this.inner.poll(cx)))?.map(Ok)
654    }
655}
656
657/// Type alias for `Pin<Box<dyn Future<Output = T> + Send + 'static>>`.
658///
659/// # Examples
660///
661/// ```
662/// use futures_lite::future::{self, FutureExt};
663///
664/// // These two lines are equivalent:
665/// let f1: future::Boxed<i32> = async { 1 + 2 }.boxed();
666/// let f2: future::Boxed<i32> = Box::pin(async { 1 + 2 });
667/// ```
668#[cfg(feature = "alloc")]
669pub type Boxed<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
670
671/// Type alias for `Pin<Box<dyn Future<Output = T> + 'static>>`.
672///
673/// # Examples
674///
675/// ```
676/// use futures_lite::future::{self, FutureExt};
677///
678/// // These two lines are equivalent:
679/// let f1: future::BoxedLocal<i32> = async { 1 + 2 }.boxed_local();
680/// let f2: future::BoxedLocal<i32> = Box::pin(async { 1 + 2 });
681/// ```
682#[cfg(feature = "alloc")]
683pub type BoxedLocal<T> = Pin<Box<dyn Future<Output = T> + 'static>>;
684
685/// Extension trait for [`Future`].
686pub trait FutureExt: Future {
687    /// A convenience for calling [`Future::poll()`] on `!`[`Unpin`] types.
688    fn poll(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
689    where
690        Self: Unpin,
691    {
692        Future::poll(Pin::new(self), cx)
693    }
694
695    /// Returns the result of `self` or `other` future, preferring `self` if both are ready.
696    ///
697    /// If you need to treat the two futures fairly without a preference for either, use the
698    /// [`race()`] function or the [`FutureExt::race()`] method.
699    ///
700    /// # Examples
701    ///
702    /// ```
703    /// use futures_lite::future::{pending, ready, FutureExt};
704    ///
705    /// # spin_on::spin_on(async {
706    /// assert_eq!(ready(1).or(pending()).await, 1);
707    /// assert_eq!(pending().or(ready(2)).await, 2);
708    ///
709    /// // The first future wins.
710    /// assert_eq!(ready(1).or(ready(2)).await, 1);
711    /// # })
712    /// ```
713    fn or<F>(self, other: F) -> Or<Self, F>
714    where
715        Self: Sized,
716        F: Future<Output = Self::Output>,
717    {
718        Or {
719            future1: self,
720            future2: other,
721        }
722    }
723
724    /// Returns the result of `self` or `other` future, with no preference if both are ready.
725    ///
726    /// Each time [`Race`] is polled, the two inner futures are polled in random order. Therefore,
727    /// no future takes precedence over the other if both can complete at the same time.
728    ///
729    /// If you have preference for one of the futures, use the [`or()`] function or the
730    /// [`FutureExt::or()`] method.
731    ///
732    /// # Examples
733    ///
734    /// ```
735    /// use futures_lite::future::{pending, ready, FutureExt};
736    ///
737    /// # spin_on::spin_on(async {
738    /// assert_eq!(ready(1).race(pending()).await, 1);
739    /// assert_eq!(pending().race(ready(2)).await, 2);
740    ///
741    /// // One of the two futures is randomly chosen as the winner.
742    /// let res = ready(1).race(ready(2)).await;
743    /// # })
744    /// ```
745    #[cfg(all(feature = "std", feature = "race"))]
746    fn race<F>(self, other: F) -> Race<Self, F>
747    where
748        Self: Sized,
749        F: Future<Output = Self::Output>,
750    {
751        Race {
752            future1: self,
753            future2: other,
754            rng: Rng::new(),
755        }
756    }
757
758    /// Catches panics while polling the future.
759    ///
760    /// # Examples
761    ///
762    /// ```
763    /// use futures_lite::future::FutureExt;
764    ///
765    /// # spin_on::spin_on(async {
766    /// let fut1 = async {}.catch_unwind();
767    /// let fut2 = async { panic!() }.catch_unwind();
768    ///
769    /// assert!(fut1.await.is_ok());
770    /// assert!(fut2.await.is_err());
771    /// # })
772    /// ```
773    #[cfg(feature = "std")]
774    fn catch_unwind(self) -> CatchUnwind<Self>
775    where
776        Self: Sized + UnwindSafe,
777    {
778        CatchUnwind { inner: self }
779    }
780
781    /// Boxes the future and changes its type to `dyn Future + Send + 'a`.
782    ///
783    /// # Examples
784    ///
785    /// ```
786    /// use futures_lite::future::{self, FutureExt};
787    ///
788    /// # spin_on::spin_on(async {
789    /// let a = future::ready('a');
790    /// let b = future::pending();
791    ///
792    /// // Futures of different types can be stored in
793    /// // the same collection when they are boxed:
794    /// let futures = vec![a.boxed(), b.boxed()];
795    /// # })
796    /// ```
797    #[cfg(feature = "alloc")]
798    fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
799    where
800        Self: Sized + Send + 'a,
801    {
802        Box::pin(self)
803    }
804
805    /// Boxes the future and changes its type to `dyn Future + 'a`.
806    ///
807    /// # Examples
808    ///
809    /// ```
810    /// use futures_lite::future::{self, FutureExt};
811    ///
812    /// # spin_on::spin_on(async {
813    /// let a = future::ready('a');
814    /// let b = future::pending();
815    ///
816    /// // Futures of different types can be stored in
817    /// // the same collection when they are boxed:
818    /// let futures = vec![a.boxed_local(), b.boxed_local()];
819    /// # })
820    /// ```
821    #[cfg(feature = "alloc")]
822    fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
823    where
824        Self: Sized + 'a,
825    {
826        Box::pin(self)
827    }
828}
829
830impl<F: Future + ?Sized> FutureExt for F {}