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