| 1 | #![stable (feature = "futures_api" , since = "1.36.0" )] |
| 2 | |
| 3 | //! Asynchronous basic functionality. |
| 4 | //! |
| 5 | //! Please see the fundamental [`async`] and [`await`] keywords and the [async book] |
| 6 | //! for more information on asynchronous programming in Rust. |
| 7 | //! |
| 8 | //! [`async`]: ../../std/keyword.async.html |
| 9 | //! [`await`]: ../../std/keyword.await.html |
| 10 | //! [async book]: https://rust-lang.github.io/async-book/ |
| 11 | |
| 12 | use crate::ptr::NonNull; |
| 13 | use crate::task::Context; |
| 14 | |
| 15 | mod async_drop; |
| 16 | mod future; |
| 17 | mod into_future; |
| 18 | mod join; |
| 19 | mod pending; |
| 20 | mod poll_fn; |
| 21 | mod ready; |
| 22 | |
| 23 | #[unstable (feature = "async_drop" , issue = "126482" )] |
| 24 | pub use async_drop::{AsyncDrop, async_drop_in_place}; |
| 25 | #[stable (feature = "into_future" , since = "1.64.0" )] |
| 26 | pub use into_future::IntoFuture; |
| 27 | #[stable (feature = "future_readiness_fns" , since = "1.48.0" )] |
| 28 | pub use pending::{Pending, pending}; |
| 29 | #[stable (feature = "future_poll_fn" , since = "1.64.0" )] |
| 30 | pub use poll_fn::{PollFn, poll_fn}; |
| 31 | #[stable (feature = "future_readiness_fns" , since = "1.48.0" )] |
| 32 | pub use ready::{Ready, ready}; |
| 33 | |
| 34 | #[stable (feature = "futures_api" , since = "1.36.0" )] |
| 35 | pub use self::future::Future; |
| 36 | #[unstable (feature = "future_join" , issue = "91642" )] |
| 37 | pub use self::join::join; |
| 38 | |
| 39 | /// This type is needed because: |
| 40 | /// |
| 41 | /// a) Coroutines cannot implement `for<'a, 'b> Coroutine<&'a mut Context<'b>>`, so we need to pass |
| 42 | /// a raw pointer (see <https://github.com/rust-lang/rust/issues/68923>). |
| 43 | /// b) Raw pointers and `NonNull` aren't `Send` or `Sync`, so that would make every single future |
| 44 | /// non-Send/Sync as well, and we don't want that. |
| 45 | /// |
| 46 | /// It also simplifies the HIR lowering of `.await`. |
| 47 | #[lang = "ResumeTy" ] |
| 48 | #[doc (hidden)] |
| 49 | #[unstable (feature = "gen_future" , issue = "none" )] |
| 50 | #[derive (Debug, Copy, Clone)] |
| 51 | pub struct ResumeTy(NonNull<Context<'static>>); |
| 52 | |
| 53 | #[unstable (feature = "gen_future" , issue = "none" )] |
| 54 | unsafe impl Send for ResumeTy {} |
| 55 | |
| 56 | #[unstable (feature = "gen_future" , issue = "none" )] |
| 57 | unsafe impl Sync for ResumeTy {} |
| 58 | |
| 59 | #[lang = "get_context" ] |
| 60 | #[doc (hidden)] |
| 61 | #[unstable (feature = "gen_future" , issue = "none" )] |
| 62 | #[must_use ] |
| 63 | #[inline ] |
| 64 | pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { |
| 65 | // SAFETY: the caller must guarantee that `cx.0` is a valid pointer |
| 66 | // that fulfills all the requirements for a mutable reference. |
| 67 | unsafe { &mut *cx.0.as_ptr().cast() } |
| 68 | } |
| 69 | |