diff options
Diffstat (limited to 'third_party/rust/pin-project-internal/src/lib.rs')
-rw-r--r-- | third_party/rust/pin-project-internal/src/lib.rs | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/third_party/rust/pin-project-internal/src/lib.rs b/third_party/rust/pin-project-internal/src/lib.rs new file mode 100644 index 0000000000..ba7abbb3d4 --- /dev/null +++ b/third_party/rust/pin-project-internal/src/lib.rs @@ -0,0 +1,552 @@ +//! An internal crate to support pin_project - **do not use directly** + +#![recursion_limit = "256"] +#![doc(html_root_url = "https://docs.rs/pin-project-internal/0.4.9")] +#![doc(test( + no_crate_inject, + attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code)) +))] +#![warn(unsafe_code)] +#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)] +#![warn(clippy::all)] +// mem::take requires Rust 1.40 +#![allow(clippy::mem_replace_with_default)] +#![allow(clippy::needless_doctest_main)] +// While this crate supports stable Rust, it currently requires +// nightly Rust in order for rustdoc to correctly document auto-generated +// `Unpin` impls. This does not affect the runtime functionality of this crate, +// nor does it affect the safety of the api provided by this crate. +// +// This is disabled by default and can be enabled using +// `--cfg pin_project_show_unpin_struct` in RUSTFLAGS. +// +// Refs: +// * https://github.com/taiki-e/pin-project/pull/53#issuecomment-525906867 +// * https://github.com/taiki-e/pin-project/pull/70 +// * https://github.com/rust-lang/rust/issues/63281 +#![cfg_attr(pin_project_show_unpin_struct, feature(proc_macro_def_site))] + +// older compilers require explicit `extern crate`. +#[allow(unused_extern_crates)] +extern crate proc_macro; + +#[macro_use] +mod utils; + +mod pin_project; +mod pinned_drop; +mod project; + +use proc_macro::TokenStream; + +use utils::{Immutable, Mutable}; + +/// An attribute that creates a projection struct covering all the fields. +/// +/// This attribute creates a projection struct according to the following rules: +/// +/// - For the field that uses `#[pin]` attribute, makes the pinned reference to +/// the field. +/// - For the other fields, makes the unpinned reference to the field. +/// +/// The following methods are implemented on the original `#[pin_project]` type: +/// +/// ``` +/// # #[rustversion::since(1.36)] +/// # fn dox() { +/// # use std::pin::Pin; +/// # type Projection<'a> = &'a (); +/// # type ProjectionRef<'a> = &'a (); +/// # trait Dox { +/// fn project(self: Pin<&mut Self>) -> Projection<'_>; +/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>; +/// # } +/// # } +/// ``` +/// +/// The visibility of the projected type and projection method is based on the +/// original type. However, if the visibility of the original type is `pub`, +/// the visibility of the projected type and the projection method is `pub(crate)`. +/// +/// If you want to call the `project` method multiple times or later use the +/// original Pin type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid +/// consuming the `Pin`. +/// +/// ## Safety +/// +/// This attribute is completely safe. In the absence of other `unsafe` code *that you write*, +/// it is impossible to cause undefined behavior with this attribute. +/// +/// This is accomplished by enforcing the four requirements for pin projection +/// stated in [the Rust documentation](https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning): +/// +/// 1. The struct must only be Unpin if all the structural fields are Unpin. +/// +/// To enforce this, this attribute will automatically generate an `Unpin` implementation +/// for you, which will require that all structurally pinned fields be `Unpin` +/// If you wish to provide an manual `Unpin` impl, you can do so via the +/// `UnsafeUnpin` argument. +/// +/// 2. The destructor of the struct must not move structural fields out of its argument. +/// +/// To enforce this, this attribute will generate code like this: +/// +/// ```rust +/// struct MyStruct {} +/// trait MyStructMustNotImplDrop {} +/// impl<T: Drop> MyStructMustNotImplDrop for T {} +/// impl MyStructMustNotImplDrop for MyStruct {} +/// ``` +/// +/// If you attempt to provide an Drop impl, the blanket impl will +/// then apply to your type, causing a compile-time error due to +/// the conflict with the second impl. +/// +/// If you wish to provide a custom `Drop` impl, you can annotate a function +/// with `#[pinned_drop]`. This function takes a pinned version of your struct - +/// that is, `Pin<&mut MyStruct>` where `MyStruct` is the type of your struct. +/// +/// You can call `project()` on this type as usual, along with any other +/// methods you have defined. Because your code is never provided with +/// a `&mut MyStruct`, it is impossible to move out of pin-projectable +/// fields in safe code in your destructor. +/// +/// 3. You must make sure that you uphold the Drop guarantee: once your struct is pinned, +/// the memory that contains the content is not overwritten or deallocated without calling the content's destructors. +/// +/// Safe code doesn't need to worry about this - the only wait to violate this requirement +/// is to manually deallocate memory (which is `unsafe`), or to overwrite a field with something else. +/// Because your custom destructor takes `Pin<&mut MyStruct`, it's impossible to obtain +/// a mutable reference to a pin-projected field in safe code. +/// +/// 4. You must not offer any other operations that could lead to data being moved out of the structural fields when your type is pinned. +/// +/// As with requirement 3, it is impossible for safe code to violate this. This crate ensures that safe code can never +/// obtain a mutable reference to `#[pin]` fields, which prevents you from ever moving out of them in safe code. +/// +/// Pin projections are also incompatible with `#[repr(packed)]` structs. Attempting to use this attribute +/// on a `#[repr(packed)]` struct results in a compile-time error. +/// +/// +/// ## Examples +/// +/// Using `#[pin_project]` will automatically create the appropriate +/// conditional [`Unpin`] implementation: +/// +/// ```rust +/// use pin_project::pin_project; +/// use std::pin::Pin; +/// +/// #[pin_project] +/// struct Foo<T, U> { +/// #[pin] +/// future: T, +/// field: U, +/// } +/// +/// impl<T, U> Foo<T, U> { +/// fn baz(self: Pin<&mut Self>) { +/// let this = self.project(); +/// let _: Pin<&mut T> = this.future; // Pinned reference to the field +/// let _: &mut U = this.field; // Normal reference to the field +/// } +/// } +/// ``` +/// +/// Note that borrowing the field where `#[pin]` attribute is used multiple +/// times requires using [`.as_mut()`][`Pin::as_mut`] to avoid +/// consuming the `Pin`. +/// +/// If you want to implement [`Unpin`] manually, you must use the `UnsafeUnpin` +/// argument to `#[pin_project]`. +/// +/// ```rust +/// use pin_project::{pin_project, UnsafeUnpin}; +/// use std::pin::Pin; +/// +/// #[pin_project(UnsafeUnpin)] +/// struct Foo<T, U> { +/// #[pin] +/// future: T, +/// field: U, +/// } +/// +/// impl<T, U> Foo<T, U> { +/// fn baz(self: Pin<&mut Self>) { +/// let this = self.project(); +/// let _: Pin<&mut T> = this.future; // Pinned reference to the field +/// let _: &mut U = this.field; // Normal reference to the field +/// } +/// } +/// +/// unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {} // Conditional Unpin impl +/// ``` +/// +/// Note the usage of the unsafe [`UnsafeUnpin`] trait, instead of the usual +/// [`Unpin`] trait. [`UnsafeUnpin`] behaves exactly like [`Unpin`], except that is +/// unsafe to implement. This unsafety comes from the fact that pin projections +/// are being used. If you implement [`UnsafeUnpin`], you must ensure that it is +/// only implemented when all pin-projected fields implement [`Unpin`]. +/// +/// See [`UnsafeUnpin`] trait for more details. +/// +/// ### `#[pinned_drop]` +/// +/// In order to correctly implement pin projections, a type's `Drop` impl must +/// not move out of any structurally pinned fields. Unfortunately, [`Drop::drop`] +/// takes `&mut Self`, not `Pin<&mut Self>`. +/// +/// To ensure that this requirement is upheld, the `#[pin_project]` attribute will +/// provide a [`Drop`] impl for you. This `Drop` impl will delegate to an impl +/// block annotated with `#[pinned_drop]` if you use the `PinnedDrop` argument +/// to `#[pin_project]`. This impl block acts just like a normal [`Drop`] impl, +/// except for the following two: +/// +/// * `drop` method takes `Pin<&mut Self>` +/// * Name of the trait is `PinnedDrop`. +/// +/// `#[pin_project]` implements the actual [`Drop`] trait via `PinnedDrop` you +/// implemented. To drop a type that implements `PinnedDrop`, use the [`drop`] +/// function just like dropping a type that directly implements [`Drop`]. +/// +/// In particular, it will never be called more than once, just like [`Drop::drop`]. +/// +/// For example: +/// +/// ```rust +/// use pin_project::{pin_project, pinned_drop}; +/// use std::{fmt::Debug, pin::Pin}; +/// +/// #[pin_project(PinnedDrop)] +/// pub struct Foo<T: Debug, U: Debug> { +/// #[pin] +/// pinned_field: T, +/// unpin_field: U, +/// } +/// +/// #[pinned_drop] +/// impl<T: Debug, U: Debug> PinnedDrop for Foo<T, U> { +/// fn drop(self: Pin<&mut Self>) { +/// println!("Dropping pinned field: {:?}", self.pinned_field); +/// println!("Dropping unpin field: {:?}", self.unpin_field); +/// } +/// } +/// +/// fn main() { +/// let _x = Foo { pinned_field: true, unpin_field: 40 }; +/// } +/// ``` +/// +/// See also [`pinned_drop`] attribute. +/// +/// ## Supported Items +/// +/// The current pin-project supports the following types of items. +/// +/// ### Structs (structs with named fields): +/// +/// ```rust +/// use pin_project::pin_project; +/// use std::pin::Pin; +/// +/// #[pin_project] +/// struct Foo<T, U> { +/// #[pin] +/// future: T, +/// field: U, +/// } +/// +/// impl<T, U> Foo<T, U> { +/// fn baz(self: Pin<&mut Self>) { +/// let this = self.project(); +/// let _: Pin<&mut T> = this.future; +/// let _: &mut U = this.field; +/// } +/// } +/// ``` +/// +/// ### Tuple structs (structs with unnamed fields): +/// +/// ```rust +/// use pin_project::pin_project; +/// use std::pin::Pin; +/// +/// #[pin_project] +/// struct Foo<T, U>(#[pin] T, U); +/// +/// impl<T, U> Foo<T, U> { +/// fn baz(self: Pin<&mut Self>) { +/// let this = self.project(); +/// let _: Pin<&mut T> = this.0; +/// let _: &mut U = this.1; +/// } +/// } +/// ``` +/// +/// Structs without fields (unit-like struct and zero fields struct) are not +/// supported. +/// +/// ### Enums +/// +/// `pin_project` also supports enums, but to use it, you need to use with the +/// [`project`] attribute. +/// +/// The attribute at the expression position is not stable, so you need to use +/// a dummy `#[project]` attribute for the function. +/// +/// ```rust +/// use pin_project::{pin_project, project}; +/// use std::pin::Pin; +/// +/// #[pin_project] +/// enum Foo<A, B, C> { +/// Tuple(#[pin] A, B), +/// Struct { field: C }, +/// Unit, +/// } +/// +/// impl<A, B, C> Foo<A, B, C> { +/// #[project] // Nightly does not need a dummy attribute to the function. +/// fn baz(self: Pin<&mut Self>) { +/// #[project] +/// match self.project() { +/// Foo::Tuple(x, y) => { +/// let _: Pin<&mut A> = x; +/// let _: &mut B = y; +/// } +/// Foo::Struct { field } => { +/// let _: &mut C = field; +/// } +/// Foo::Unit => {} +/// } +/// } +/// } +/// ``` +/// +/// Enums without variants (zero-variant enums) are not supported. +/// +/// See also [`project`] and [`project_ref`] attributes. +/// +/// [`Pin::as_mut`]: core::pin::Pin::as_mut +/// [`Pin::set`]: core::pin::Pin::set +/// [`drop`]: Drop::drop +/// [`UnsafeUnpin`]: https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html +/// [`project`]: ./attr.project.html +/// [`project_ref`]: ./attr.project_ref.html +/// [`pinned_drop`]: ./attr.pinned_drop.html +#[proc_macro_attribute] +pub fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream { + pin_project::attribute(&args.into(), input.into()).into() +} + +/// An attribute for annotating an impl block that implements [`Drop`]. +/// +/// This attribute is only needed when you wish to provide a [`Drop`] +/// impl for your type. The impl block annotated with `#[pinned_drop]` acts just +/// like a normal [`Drop`] impl, except for the fact that `drop` method takes +/// `Pin<&mut Self>`. In particular, it will never be called more than once, +/// just like [`Drop::drop`]. +/// +/// ## Example +/// +/// ```rust +/// use pin_project::{pin_project, pinned_drop}; +/// use std::pin::Pin; +/// +/// #[pin_project(PinnedDrop)] +/// struct Foo { +/// #[pin] +/// field: u8, +/// } +/// +/// #[pinned_drop] +/// impl PinnedDrop for Foo { +/// fn drop(self: Pin<&mut Self>) { +/// println!("Dropping: {}", self.field); +/// } +/// } +/// +/// fn main() { +/// let _x = Foo { field: 50 }; +/// } +/// ``` +/// +/// See ["pinned-drop" section of `pin_project` attribute][pinned-drop] for more details. +/// +/// [pinned-drop]: ./attr.pin_project.html#pinned_drop +#[proc_macro_attribute] +pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(input); + pinned_drop::attribute(&args.into(), input).into() +} + +/// An attribute to provide way to refer to the projected type returned by +/// `project` method. +/// +/// The following syntaxes are supported. +/// +/// ## `impl` blocks +/// +/// All methods (and associated functions) in `#[project] impl` block become +/// methods of the projected type. If you want to implement methods on the +/// original type, you need to create another (non-`#[project]`) `impl` block. +/// +/// To call a method implemented in `#[project] impl` block, you need to first +/// get the projected-type with `let this = self.project();`. +/// +/// ### Examples +/// +/// ```rust +/// use pin_project::{pin_project, project}; +/// use std::pin::Pin; +/// +/// #[pin_project] +/// struct Foo<T, U> { +/// #[pin] +/// future: T, +/// field: U, +/// } +/// +/// // impl for the original type +/// impl<T, U> Foo<T, U> { +/// fn bar(self: Pin<&mut Self>) { +/// self.project().baz() +/// } +/// } +/// +/// // impl for the projected type +/// #[project] +/// impl<T, U> Foo<T, U> { +/// fn baz(self) { +/// let Self { future, field } = self; +/// +/// let _: Pin<&mut T> = future; +/// let _: &mut U = field; +/// } +/// } +/// ``` +/// +/// ## `let` bindings +/// +/// *The attribute at the expression position is not stable, so you need to use +/// a dummy `#[project]` attribute for the function.* +/// +/// ### Examples +/// +/// ```rust +/// use pin_project::{pin_project, project}; +/// use std::pin::Pin; +/// +/// #[pin_project] +/// struct Foo<T, U> { +/// #[pin] +/// future: T, +/// field: U, +/// } +/// +/// impl<T, U> Foo<T, U> { +/// #[project] // Nightly does not need a dummy attribute to the function. +/// fn baz(self: Pin<&mut Self>) { +/// #[project] +/// let Foo { future, field } = self.project(); +/// +/// let _: Pin<&mut T> = future; +/// let _: &mut U = field; +/// } +/// } +/// ``` +/// +/// ## `match` expressions +/// +/// *The attribute at the expression position is not stable, so you need to use +/// a dummy `#[project]` attribute for the function.* +/// +/// ### Examples +/// +/// ```rust +/// use pin_project::{pin_project, project}; +/// use std::pin::Pin; +/// +/// #[pin_project] +/// enum Foo<A, B, C> { +/// Tuple(#[pin] A, B), +/// Struct { field: C }, +/// Unit, +/// } +/// +/// impl<A, B, C> Foo<A, B, C> { +/// #[project] // Nightly does not need a dummy attribute to the function. +/// fn baz(self: Pin<&mut Self>) { +/// #[project] +/// match self.project() { +/// Foo::Tuple(x, y) => { +/// let _: Pin<&mut A> = x; +/// let _: &mut B = y; +/// } +/// Foo::Struct { field } => { +/// let _: &mut C = field; +/// } +/// Foo::Unit => {} +/// } +/// } +/// } +/// ``` +/// +/// ## `use` statements +/// +/// ### Examples +/// +/// ```rust +/// # mod dox { +/// use pin_project::pin_project; +/// +/// #[pin_project] +/// struct Foo<A> { +/// #[pin] +/// field: A, +/// } +/// +/// mod bar { +/// use super::Foo; +/// use pin_project::project; +/// use std::pin::Pin; +/// +/// #[project] +/// use super::Foo; +/// +/// #[project] +/// fn baz<A>(foo: Pin<&mut Foo<A>>) { +/// #[project] +/// let Foo { field } = foo.project(); +/// let _: Pin<&mut A> = field; +/// } +/// } +/// # } +/// ``` +#[proc_macro_attribute] +pub fn project(args: TokenStream, input: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(input); + project::attribute(&args.into(), input, Mutable).into() +} + +/// An attribute to provide way to refer to the projected type returned by +/// `project_ref` method. +/// +/// This is the same as [`project`] attribute except it refers to the projected +/// type returned by `project_ref` method. +/// +/// See [`project`] attribute for more details. +/// +/// [`project`]: ./attr.project.html +#[proc_macro_attribute] +pub fn project_ref(args: TokenStream, input: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(input); + project::attribute(&args.into(), input, Immutable).into() +} + +/// An internal helper macro. +#[doc(hidden)] +#[proc_macro_derive(__PinProjectInternalDerive, attributes(pin))] +pub fn __pin_project_internal_derive(input: TokenStream) -> TokenStream { + pin_project::derive(input.into()).into() +} |