1 #![stable(feature = "futures_api", since = "1.36.0")]
3 //! Asynchronous values.
6 ops
::{Generator, GeneratorState}
,
18 #[stable(feature = "futures_api", since = "1.36.0")]
19 pub use self::future
::Future
;
21 #[unstable(feature = "into_future", issue = "67644")]
22 pub use into_future
::IntoFuture
;
24 #[unstable(feature = "future_readiness_fns", issue = "70921")]
25 pub use pending
::{pending, Pending}
;
26 #[unstable(feature = "future_readiness_fns", issue = "70921")]
27 pub use ready
::{ready, Ready}
;
29 #[unstable(feature = "future_poll_fn", issue = "72302")]
30 pub use poll_fn
::{poll_fn, PollFn}
;
32 /// This type is needed because:
34 /// a) Generators cannot implement `for<'a, 'b> Generator<&'a mut Context<'b>>`, so we need to pass
35 /// a raw pointer (see https://github.com/rust-lang/rust/issues/68923).
36 /// b) Raw pointers and `NonNull` aren't `Send` or `Sync`, so that would make every single future
37 /// non-Send/Sync as well, and we don't want that.
39 /// It also simplifies the HIR lowering of `.await`.
41 #[unstable(feature = "gen_future", issue = "50547")]
42 #[derive(Debug, Copy, Clone)]
43 pub struct ResumeTy(NonNull
<Context
<'
static>>);
45 #[unstable(feature = "gen_future", issue = "50547")]
46 unsafe impl Send
for ResumeTy {}
48 #[unstable(feature = "gen_future", issue = "50547")]
49 unsafe impl Sync
for ResumeTy {}
51 /// Wrap a generator in a future.
53 /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
54 /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
55 // This is `const` to avoid extra errors after we recover from `const async fn`
57 #[unstable(feature = "gen_future", issue = "50547")]
59 pub const fn from_generator
<T
>(gen
: T
) -> impl Future
<Output
= T
::Return
>
61 T
: Generator
<ResumeTy
, Yield
= ()>,
63 #[rustc_diagnostic_item = "gen_future"]
64 struct GenFuture
<T
: Generator
<ResumeTy
, Yield
= ()>>(T
);
66 // We rely on the fact that async/await futures are immovable in order to create
67 // self-referential borrows in the underlying generator.
68 impl<T
: Generator
<ResumeTy
, Yield
= ()>> !Unpin
for GenFuture
<T
> {}
70 impl<T
: Generator
<ResumeTy
, Yield
= ()>> Future
for GenFuture
<T
> {
71 type Output
= T
::Return
;
72 fn poll(self: Pin
<&mut Self>, cx
: &mut Context
<'_
>) -> Poll
<Self::Output
> {
73 // Safety: Safe because we're !Unpin + !Drop, and this is just a field projection.
74 let gen
= unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) }
;
76 // Resume the generator, turning the `&mut Context` into a `NonNull` raw pointer. The
77 // `.await` lowering will safely cast that back to a `&mut Context`.
78 match gen
.resume(ResumeTy(NonNull
::from(cx
).cast
::<Context
<'
static>>())) {
79 GeneratorState
::Yielded(()) => Poll
::Pending
,
80 GeneratorState
::Complete(x
) => Poll
::Ready(x
),
89 #[unstable(feature = "gen_future", issue = "50547")]
91 pub unsafe fn get_context
<'a
, 'b
>(cx
: ResumeTy
) -> &'a
mut Context
<'b
> {
92 // SAFETY: the caller must guarantee that `cx.0` is a valid pointer
93 // that fulfills all the requirements for a mutable reference.
94 unsafe { &mut *cx.0.as_ptr().cast() }