@@ -226,6 +226,63 @@ use utils::{Immutable, Mutable, Owned};
226
226
///
227
227
/// See also [`pinned_drop`] attribute.
228
228
///
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
+ ///
229
286
/// ## Supported Items
230
287
///
231
288
/// The current pin-project supports the following types of items.
@@ -320,6 +377,7 @@ use utils::{Immutable, Mutable, Owned};
320
377
/// [`UnsafeUnpin`]: https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html
321
378
/// [`project`]: ./attr.project.html
322
379
/// [`project_ref`]: ./attr.project_ref.html
380
+ /// [`project_replace`]: ./attr.project_replace.html
323
381
/// [`pinned_drop`]: ./attr.pinned_drop.html
324
382
#[ proc_macro_attribute]
325
383
pub fn pin_project ( args : TokenStream , input : TokenStream ) -> TokenStream {
0 commit comments