Skip to content

Commit 760cfc3

Browse files
committed
Document the project_replace() method.
1 parent 1db85fa commit 760cfc3

File tree

1 file changed

+58
-0
lines changed
  • pin-project-internal/src

1 file changed

+58
-0
lines changed

pin-project-internal/src/lib.rs

+58
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,63 @@ use utils::{Immutable, Mutable, Owned};
226226
///
227227
/// See also [`pinned_drop`] attribute.
228228
///
229+
/// ### `project_replace()`
230+
///
231+
/// In addition to the `project()` and `project_ref()` methods which are always
232+
/// provided when you use the `#[pin_project]` attribute, there is a third method,
233+
/// `project_replace()` which can be useful in some situations. It is equivalent
234+
/// to [`Pin::set`], except that the unpinned fields are moved and returned,
235+
/// instead of being dropped in-place.
236+
///
237+
/// ```
238+
/// # #[rustversion::since(1.36)]
239+
/// # fn dox() {
240+
/// # use std::pin::Pin;
241+
/// # type ProjectionOwned = ();
242+
/// # trait Dox {
243+
/// fn project_replace(self: Pin<&mut Self>, other: Self) -> ProjectionOwned;
244+
/// # }
245+
/// # }
246+
/// ```
247+
///
248+
/// The `ProjectionOwned` type is identical to the `Self` type, except that
249+
/// all pinned fields have been replaced by equivalent `PhantomData` types.
250+
///
251+
/// This method is opt-in, because it is only supported for `Sized` types, and
252+
/// because it is incompatible with the `#[pinned_drop]` attribute described
253+
/// above. It can be enabled by using `#[pin_project(Replace)]`.
254+
///
255+
/// For example:
256+
///
257+
/// ```rust
258+
/// use pin_project::{pin_project, project_replace};
259+
///
260+
/// #[pin_project(Replace)]
261+
/// pub enum Foo<T> {
262+
/// A {
263+
/// #[pin]
264+
/// pinned_field: i32,
265+
/// unpinned_field: T,
266+
/// },
267+
/// B,
268+
/// }
269+
///
270+
/// #[project_replace]
271+
/// fn main() {
272+
/// let mut x = Box::pin(Foo::A { pinned_field: 42, unpinned_field: "hello" });
273+
///
274+
/// #[project_replace]
275+
/// match x.as_mut().project_replace(Foo::B) {
276+
/// Foo::A { unpinned_field, .. } => assert_eq!(unpinned_field, "hello"),
277+
/// Foo::B => unreachable!(),
278+
/// }
279+
/// }
280+
/// ```
281+
///
282+
/// The [`project_replace`] attributes are necessary whenever destructuring the return
283+
/// type of `project_replace()`, and work in exactly the same way as the
284+
/// [`project`] and [`project_ref`] attributes.
285+
///
229286
/// ## Supported Items
230287
///
231288
/// The current pin-project supports the following types of items.
@@ -320,6 +377,7 @@ use utils::{Immutable, Mutable, Owned};
320377
/// [`UnsafeUnpin`]: https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html
321378
/// [`project`]: ./attr.project.html
322379
/// [`project_ref`]: ./attr.project_ref.html
380+
/// [`project_replace`]: ./attr.project_replace.html
323381
/// [`pinned_drop`]: ./attr.pinned_drop.html
324382
#[proc_macro_attribute]
325383
pub fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream {

0 commit comments

Comments
 (0)