Upgrade rust/crates/pin-project-lite to 0.2.4

Test: make
Change-Id: I0a14e3f5a90d3f1eaf6b8659300b2260402b536f
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index f892109..32ae14a 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "f1a711f00677639a51118cc4f31ea4ec59220f0e"
+    "sha1": "416be96f7777862c68b567c92a91887f69a8c2b3"
   }
 }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc1b7d1..e9d1276 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,13 +10,25 @@
 
 ## [Unreleased]
 
+## [0.2.4] - 2021-01-11
+
+- [Add `project_replace`.](https://github.com/taiki-e/pin-project-lite/pull/43)
+
+## [0.2.3] - 2021-01-09
+
+- [Suppress `clippy::unknown_clippy_lints` lint in generated code.](https://github.com/taiki-e/pin-project-lite/pull/47)
+
+## [0.2.2] - 2021-01-09
+
+- [Suppress `clippy::ref_option_ref` lint in generated code.](https://github.com/taiki-e/pin-project-lite/pull/45)
+
 ## [0.2.1] - 2021-01-05
 
 - Exclude unneeded files from crates.io.
 
 ## [0.2.0] - 2020-11-13
 
-- [`pin_project!` macro now supports enums.][28]
+- [`pin_project!` macro now supports enums.](https://github.com/taiki-e/pin-project-lite/pull/28)
 
   To use `pin_project!` on enums, you need to name the projection type returned from the method.
 
@@ -43,7 +55,7 @@
   }
   ```
 
-- [Support naming the projection types.][28]
+- [Support naming the projection types.](https://github.com/taiki-e/pin-project-lite/pull/28)
 
   By passing an attribute with the same name as the method, you can name the projection type returned from the method:
 
@@ -65,8 +77,6 @@
   }
   ```
 
-[28]: https://github.com/taiki-e/pin-project-lite/pull/28
-
 ## [0.1.11] - 2020-10-20
 
 - Suppress `clippy::redundant_pub_crate` lint in generated code.
@@ -79,71 +89,59 @@
 
 ## [0.1.9] - 2020-09-29
 
-- Fix trailing comma support in generics
+- [Fix trailing comma support in generics.](https://github.com/taiki-e/pin-project-lite/pull/32)
 
 ## [0.1.8] - 2020-09-26
 
-- Fix compatibility of generated code with `forbid(future_incompatible)`
+- [Fix compatibility of generated code with `forbid(future_incompatible)`.](https://github.com/taiki-e/pin-project-lite/pull/30)
 
   Note: This does not guarantee compatibility with `forbid(future_incompatible)` in the future.
   If rustc adds a new lint, we may not be able to keep this.
 
 ## [0.1.7] - 2020-06-04
 
-- [Support `?Sized` bounds in where clauses.][22]
+- [Support `?Sized` bounds in where clauses.](https://github.com/taiki-e/pin-project-lite/pull/22)
 
-- [Fix lifetime inference error when an associated type is used in fields.][20]
+- [Fix lifetime inference error when an associated type is used in fields.](https://github.com/taiki-e/pin-project-lite/pull/20)
 
 - Suppress `clippy::used_underscore_binding` lint in generated code.
 
 - Documentation improvements.
 
-[20]: https://github.com/taiki-e/pin-project-lite/pull/20
-[22]: https://github.com/taiki-e/pin-project-lite/pull/22
-
 ## [0.1.6] - 2020-05-31
 
-- [Support lifetime bounds in where clauses.][18]
+- [Support lifetime bounds in where clauses.](https://github.com/taiki-e/pin-project-lite/pull/18)
 
 - Documentation improvements.
 
-[18]: https://github.com/taiki-e/pin-project-lite/pull/18
-
 ## [0.1.5] - 2020-05-07
 
-- [Support overwriting the name of core crate.][14]
-
-[14]: https://github.com/taiki-e/pin-project-lite/pull/14
+- [Support overwriting the name of `core` crate.](https://github.com/taiki-e/pin-project-lite/pull/14)
 
 ## [0.1.4] - 2020-01-20
 
-- [Support ?Sized bounds in generic parameters.][9]
-
-[9]: https://github.com/taiki-e/pin-project-lite/pull/9
+- [Support ?Sized bounds in generic parameters.](https://github.com/taiki-e/pin-project-lite/pull/9)
 
 ## [0.1.3] - 2020-01-20
 
-- [Support lifetime bounds in generic parameters.][7]
-
-[7]: https://github.com/taiki-e/pin-project-lite/pull/7
+- [Support lifetime bounds in generic parameters.](https://github.com/taiki-e/pin-project-lite/pull/7)
 
 ## [0.1.2] - 2020-01-05
 
-- [Support recognizing default generic parameters.][6]
-
-[6]: https://github.com/taiki-e/pin-project-lite/pull/6
+- [Support recognizing default generic parameters.](https://github.com/taiki-e/pin-project-lite/pull/6)
 
 ## [0.1.1] - 2019-11-15
 
-- [`pin_project!` macro now determines the visibility of the projection type/method is based on the original type.][5]
-
-[5]: https://github.com/taiki-e/pin-project-lite/pull/5
+- [`pin_project!` macro now determines the visibility of the projection type/method is based on the original type.](https://github.com/taiki-e/pin-project-lite/pull/5)
 
 ## [0.1.0] - 2019-10-22
 
 Initial release
 
-[Unreleased]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.1...HEAD
+[Unreleased]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.4...HEAD
+[0.2.4]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.3...v0.2.4
+[0.2.3]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.2...v0.2.3
+[0.2.2]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.1...v0.2.2
 [0.2.1]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.0...v0.2.1
 [0.2.0]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.11...v0.2.0
 [0.1.11]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.10...v0.1.11
diff --git a/Cargo.toml b/Cargo.toml
index 7538f02..92774c9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "pin-project-lite"
-version = "0.2.1"
+version = "0.2.4"
 authors = ["Taiki Endo <te316e89@gmail.com>"]
 exclude = ["/.github", "/scripts"]
 description = "A lightweight version of pin-project written with declarative macros.\n"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 539de51..a909043 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "pin-project-lite"
-version = "0.2.1"
+version = "0.2.4"
 authors = ["Taiki Endo <te316e89@gmail.com>"]
 edition = "2018"
 license = "Apache-2.0 OR MIT"
diff --git a/METADATA b/METADATA
index 4d7b0bc..24edb01 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/pin-project-lite/pin-project-lite-0.2.1.crate"
+    value: "https://static.crates.io/crates/pin-project-lite/pin-project-lite-0.2.4.crate"
   }
-  version: "0.2.1"
+  version: "0.2.4"
   license_type: NOTICE
   last_upgrade_date {
     year: 2021
     month: 1
-    day: 5
+    day: 11
   }
 }
diff --git a/src/lib.rs b/src/lib.rs
index b56c71f..3e3ef70 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -105,7 +105,6 @@
         allow(dead_code, unused_variables)
     )
 ))]
-#![warn(unsafe_code)]
 #![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
 #![warn(clippy::all, clippy::default_trait_access)]
 
@@ -157,6 +156,18 @@
 /// }
 /// ```
 ///
+/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional
+/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving
+/// out all unpinned fields in `Self`.
+///
+/// ```rust
+/// # use std::pin::Pin;
+/// # type MyProjReplace = ();
+/// # trait Dox {
+/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace;
+/// # }
+/// ```
+///
 /// The `#[project]` (and `#[project_ref]`) attribute must precede the other
 /// attributes except for `#[doc]`. For example, the following code will not be compiled:
 ///
@@ -302,10 +313,47 @@
         $(#[doc $($doc:tt)*])*
         #[project = $proj_mut_ident:ident]
         #[project_ref = $proj_ref_ident:ident]
+        #[project_replace = $proj_replace_ident:ident]
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [$proj_mut_ident][$proj_ref_ident]
+            [$proj_mut_ident][$proj_ref_ident][$proj_replace_ident]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project = $proj_mut_ident:ident]
+        #[project_ref = $proj_ref_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$proj_mut_ident][$proj_ref_ident][]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project = $proj_mut_ident:ident]
+        #[project_replace = $proj_replace_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$proj_mut_ident][][$proj_replace_ident]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project_ref = $proj_ref_ident:ident]
+        #[project_replace = $proj_replace_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [][$proj_ref_ident][$proj_replace_ident]
             $(#[doc $($doc)*])*
             $($tt)*
         }
@@ -316,7 +364,7 @@
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [$proj_mut_ident][]
+            [$proj_mut_ident][][]
             $(#[doc $($doc)*])*
             $($tt)*
         }
@@ -327,7 +375,18 @@
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [][$proj_ref_ident]
+            [][$proj_ref_ident][]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project_replace = $proj_replace_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [][][$proj_replace_ident]
             $(#[doc $($doc)*])*
             $($tt)*
         }
@@ -336,7 +395,7 @@
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [][]
+            [][][]
             $($tt)*
         }
     };
@@ -360,6 +419,7 @@
     (@struct=>internal;
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
         [$proj_vis:vis]
         [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
         [$($def_generics:tt)*]
@@ -407,10 +467,26 @@
                 ),+
             }
         }
+        $crate::__pin_project_internal! { @struct=>make_proj_replace_ty=>named;
+            [$proj_vis]
+            [$($proj_replace_ident)?]
+            [make_proj_field_replace]
+            [$ident]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $(
+                    $(#[$pin])?
+                    $field_vis $field: $field_ty
+                ),+
+            }
+        }
 
-        #[allow(explicit_outlives_requirements)]
+        #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
-        #[allow(clippy::redundant_pub_crate)]
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
         #[allow(clippy::used_underscore_binding)]
         const _: () = {
             $crate::__pin_project_internal! { @struct=>make_proj_ty=>unnamed;
@@ -439,6 +515,19 @@
                     ),+
                 }
             }
+            $crate::__pin_project_internal! { @struct=>make_proj_replace_ty=>unnamed;
+                [$proj_vis]
+                [$($proj_replace_ident)?][ProjectionReplace]
+                [make_proj_field_replace]
+                [$ident]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                {
+                    $(
+                        $(#[$pin])?
+                        $field_vis $field: $field_ty
+                    ),+
+                }
+            }
 
             impl <$($impl_generics)*> $ident <$($ty_generics)*>
             $(where
@@ -468,6 +557,17 @@
                         ),+
                     }
                 }
+                $crate::__pin_project_internal! { @struct=>make_proj_replace_method;
+                    [$proj_vis]
+                    [$($proj_replace_ident)?][ProjectionReplace]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field_vis $field
+                        ),+
+                    }
+                }
             }
 
             $crate::__pin_project_internal! { @make_unpin_impl;
@@ -514,6 +614,7 @@
     (@enum=>internal;
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
         [$proj_vis:vis]
         [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
         [$($def_generics:tt)*]
@@ -579,8 +680,28 @@
                 ),+
             }
         }
+        $crate::__pin_project_internal! { @enum=>make_proj_replace_ty;
+            [$proj_vis]
+            [$($proj_replace_ident)?]
+            [make_proj_field_replace]
+            [$ident]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $(
+                    $variant $({
+                        $(
+                            $(#[$pin])?
+                            $field: $field_ty
+                        ),+
+                    })?
+                ),+
+            }
+        }
 
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
         #[allow(clippy::used_underscore_binding)]
         const _: () = {
             impl <$($impl_generics)*> $ident <$($ty_generics)*>
@@ -619,6 +740,21 @@
                         ),+
                     }
                 }
+                $crate::__pin_project_internal! { @enum=>make_proj_replace_method;
+                    [$proj_vis]
+                    [$($proj_replace_ident)?]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $variant $({
+                                $(
+                                    $(#[$pin])?
+                                    $field
+                                ),+
+                            })?
+                        ),+
+                    }
+                }
             }
 
             $crate::__pin_project_internal! { @make_unpin_impl;
@@ -687,8 +823,12 @@
     ) => {
         #[allow(dead_code)] // This lint warns unused fields/variants.
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
         #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
-        #[allow(clippy::redundant_pub_crate)]
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
         #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
         $proj_vis struct $proj_ty_ident <'__pin, $($impl_generics)*>
         where
@@ -710,6 +850,61 @@
         [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
         $($field:tt)*
     ) => {};
+
+    (@struct=>make_proj_replace_ty=>unnamed;
+        [$proj_vis:vis]
+        [$_proj_ty_ident:ident][$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($field:tt)*
+    ) => {};
+    (@struct=>make_proj_replace_ty=>unnamed;
+        [$proj_vis:vis]
+        [][$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($field:tt)*
+    ) => {
+    };
+    (@struct=>make_proj_replace_ty=>named;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident: $field_ty:ty
+            ),+
+        }
+    ) => {
+        #[allow(dead_code)] // This lint warns unused fields/variants.
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+        $proj_vis struct $proj_ty_ident <$($impl_generics)*>
+        where
+            $($($where_clause)*)?
+        {
+            $(
+                $field_vis $field: $crate::__pin_project_internal!(@$make_proj_field;
+                    $(#[$pin])? $field_ty
+                )
+            ),+
+        }
+    };
+    (@struct=>make_proj_replace_ty=>named;
+        [$proj_vis:vis]
+        []
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($field:tt)*
+    ) => {};
     // =============================================================================================
     // enum:make_proj_ty
     (@enum=>make_proj_ty;
@@ -731,8 +926,12 @@
     ) => {
         #[allow(dead_code)] // This lint warns unused fields/variants.
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
         #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
-        #[allow(clippy::redundant_pub_crate)]
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
         #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
         $proj_vis enum $proj_ty_ident <'__pin, $($impl_generics)*>
         where
@@ -759,6 +958,86 @@
         $($variant:tt)*
     ) => {};
 
+    (@enum=>make_proj_replace_ty;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        {
+            $(
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident: $field_ty:ty
+                    ),+
+                })?
+            ),+
+        }
+    ) => {
+        #[allow(dead_code)] // This lint warns unused fields/variants.
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+        $proj_vis enum $proj_ty_ident <$($impl_generics)*>
+        where
+            $($($where_clause)*)?
+        {
+            $(
+                $variant $({
+                    $(
+                        $field: $crate::__pin_project_internal!(@$make_proj_field;
+                            $(#[$pin])? $field_ty
+                        )
+                    ),+
+                })?
+            ),+
+        }
+    };
+    (@enum=>make_proj_replace_ty;
+        [$proj_vis:vis]
+        []
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($variant:tt)*
+    ) => {};
+
+    // =============================================================================================
+    (@make_proj_replace_block;
+        [$($proj_path: tt)+]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident
+            ),+
+        }
+    ) => {
+        let result = $($proj_path)* {
+            $(
+                $field: $crate::__pin_project_internal!(@make_replace_field_proj;
+                    $(#[$pin])? $field
+                )
+            ),+
+        };
+
+        {
+            ( $(
+                $crate::__pin_project_internal!(@make_unsafe_drop_in_place_guard;
+                    $(#[$pin])? $field
+                ),
+            )* );
+        }
+
+        result
+    };
+    (@make_proj_replace_block;
+        [$($proj_path: tt)+]
+    ) => {
+        $($proj_path)*
+    };
+
     // =============================================================================================
     // struct:make_proj_method
     (@struct=>make_proj_method;
@@ -803,6 +1082,54 @@
             $($variant)*
         }
     };
+
+    (@struct=>make_proj_replace_method;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident][$_proj_ty_ident:ident]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident
+            ),+
+        }
+    ) => {
+        $proj_vis fn project_replace(
+            self: $crate::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> $proj_ty_ident <$($ty_generics)*> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+                // Destructors will run in reverse order, so next create a guard to overwrite
+                // `self` with the replacement value without calling destructors.
+                let __guard = $crate::__private::UnsafeOverwriteGuard {
+                    target: __self_ptr,
+                    value: $crate::__private::ManuallyDrop::new(replacement),
+                };
+
+                let Self { $($field),* } = &mut *__self_ptr;
+
+                $crate::__pin_project_internal!{@make_proj_replace_block;
+                    [$proj_ty_ident]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field
+                        ),+
+                    }
+                }
+            }
+        }
+    };
+    (@struct=>make_proj_replace_method;
+        [$proj_vis:vis]
+        [][$proj_ty_ident:ident]
+        [$($ty_generics:tt)*]
+        $($variant:tt)*
+    ) => {
+    };
+
     // =============================================================================================
     // enum:make_proj_method
     (@enum=>make_proj_method;
@@ -852,6 +1179,62 @@
         $($variant:tt)*
     ) => {};
 
+    (@enum=>make_proj_replace_method;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident
+                    ),+
+                })?
+            ),+
+        }
+    ) => {
+        $proj_vis fn project_replace(
+            self: $crate::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> $proj_ty_ident <$($ty_generics)*> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+                // Destructors will run in reverse order, so next create a guard to overwrite
+                // `self` with the replacement value without calling destructors.
+                let __guard = $crate::__private::UnsafeOverwriteGuard {
+                    target: __self_ptr,
+                    value: $crate::__private::ManuallyDrop::new(replacement),
+                };
+
+                match &mut *__self_ptr {
+                    $(
+                        Self::$variant $({
+                            $($field),+
+                        })? => {
+                            $crate::__pin_project_internal!{@make_proj_replace_block;
+                                [$proj_ty_ident :: $variant]
+                                $({
+                                    $(
+                                        $(#[$pin])?
+                                        $field
+                                    ),+
+                                })?
+                            }
+                        }
+                    ),+
+                }
+            }
+        }
+    };
+    (@enum=>make_proj_replace_method;
+        [$proj_vis:vis]
+        []
+        [$($ty_generics:tt)*]
+        $($variant:tt)*
+    ) => {};
+
     // =============================================================================================
     // make_unpin_impl
     (@make_unpin_impl;
@@ -954,6 +1337,35 @@
     };
 
     // =============================================================================================
+    // make_replace_field_proj
+    (@make_replace_field_proj;
+        #[pin]
+        $field:ident
+    ) => {
+        $crate::__private::PhantomData
+    };
+    (@make_replace_field_proj;
+        $field:ident
+    ) => {
+        $crate::__private::ptr::read($field)
+    };
+
+
+    // =============================================================================================
+    // make_unsafe_drop_in_place_guard
+    (@make_unsafe_drop_in_place_guard;
+        #[pin]
+        $field:ident
+    ) => {
+        $crate::__private::UnsafeDropInPlaceGuard($field)
+    };
+    (@make_unsafe_drop_in_place_guard;
+        $field:ident
+    ) => {
+        ()
+    };
+
+    // =============================================================================================
     // make_proj_field
     (@make_proj_field_mut;
         #[pin]
@@ -978,12 +1390,25 @@
         &'__pin ($field_ty)
     };
 
+    (@make_proj_field_replace;
+        #[pin]
+        $field_ty:ty
+    ) => {
+        $crate::__private::PhantomData<$field_ty>
+    };
+    (@make_proj_field_replace;
+        $field_ty:ty
+    ) => {
+        $field_ty
+    };
+
     // =============================================================================================
     // Parses input and determines visibility
     // struct
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         pub struct $ident:ident $(<
@@ -1012,6 +1437,7 @@
         $crate::__pin_project_internal! { @struct=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [pub(crate)]
             [$(#[$attrs])* pub struct $ident]
             [$(<
@@ -1048,6 +1474,7 @@
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         $vis:vis struct $ident:ident $(<
@@ -1076,6 +1503,7 @@
         $crate::__pin_project_internal! { @struct=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [$vis]
             [$(#[$attrs])* $vis struct $ident]
             [$(<
@@ -1113,6 +1541,7 @@
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         pub enum $ident:ident $(<
@@ -1146,6 +1575,7 @@
         $crate::__pin_project_internal! { @enum=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [pub(crate)]
             [$(#[$attrs])* pub enum $ident]
             [$(<
@@ -1187,6 +1617,7 @@
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         $vis:vis enum $ident:ident $(<
@@ -1220,6 +1651,7 @@
         $crate::__pin_project_internal! { @enum=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [$vis]
             [$(#[$attrs])* $vis enum $ident]
             [$(<
@@ -1266,8 +1698,10 @@
     #[doc(hidden)]
     pub use core::{
         marker::{PhantomData, Unpin},
+        mem::ManuallyDrop,
         ops::Drop,
         pin::Pin,
+        ptr,
     };
 
     // This is an internal helper struct used by `pin_project!`.
@@ -1275,4 +1709,32 @@
     pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);
 
     impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
+
+    // This is an internal helper used to ensure a value is dropped.
+    #[doc(hidden)]
+    pub struct UnsafeDropInPlaceGuard<T: ?Sized>(pub *mut T);
+
+    impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
+        fn drop(&mut self) {
+            unsafe {
+                ptr::drop_in_place(self.0);
+            }
+        }
+    }
+
+    // This is an internal helper used to ensure a value is overwritten without
+    // its destructor being called.
+    #[doc(hidden)]
+    pub struct UnsafeOverwriteGuard<T> {
+        pub value: ManuallyDrop<T>,
+        pub target: *mut T,
+    }
+
+    impl<T> Drop for UnsafeOverwriteGuard<T> {
+        fn drop(&mut self) {
+            unsafe {
+                ptr::write(self.target, ptr::read(&*self.value));
+            }
+        }
+    }
 }
diff --git a/src/lib.rs.orig b/src/lib.rs.orig
index 8b2283f..ff1e3bf 100644
--- a/src/lib.rs.orig
+++ b/src/lib.rs.orig
@@ -105,7 +105,6 @@
         allow(dead_code, unused_variables)
     )
 ))]
-#![warn(unsafe_code)]
 #![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
 #![warn(clippy::all, clippy::default_trait_access)]
 
@@ -154,6 +153,18 @@
 /// }
 /// ```
 ///
+/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional
+/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving
+/// out all unpinned fields in `Self`.
+///
+/// ```rust
+/// # use std::pin::Pin;
+/// # type MyProjReplace = ();
+/// # trait Dox {
+/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace;
+/// # }
+/// ```
+///
 /// The `#[project]` (and `#[project_ref]`) attribute must precede the other
 /// attributes except for `#[doc]`. For example, the following code will not be compiled:
 ///
@@ -299,10 +310,47 @@
         $(#[doc $($doc:tt)*])*
         #[project = $proj_mut_ident:ident]
         #[project_ref = $proj_ref_ident:ident]
+        #[project_replace = $proj_replace_ident:ident]
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [$proj_mut_ident][$proj_ref_ident]
+            [$proj_mut_ident][$proj_ref_ident][$proj_replace_ident]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project = $proj_mut_ident:ident]
+        #[project_ref = $proj_ref_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$proj_mut_ident][$proj_ref_ident][]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project = $proj_mut_ident:ident]
+        #[project_replace = $proj_replace_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$proj_mut_ident][][$proj_replace_ident]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project_ref = $proj_ref_ident:ident]
+        #[project_replace = $proj_replace_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [][$proj_ref_ident][$proj_replace_ident]
             $(#[doc $($doc)*])*
             $($tt)*
         }
@@ -313,7 +361,7 @@
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [$proj_mut_ident][]
+            [$proj_mut_ident][][]
             $(#[doc $($doc)*])*
             $($tt)*
         }
@@ -324,7 +372,18 @@
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [][$proj_ref_ident]
+            [][$proj_ref_ident][]
+            $(#[doc $($doc)*])*
+            $($tt)*
+        }
+    };
+    (
+        $(#[doc $($doc:tt)*])*
+        #[project_replace = $proj_replace_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [][][$proj_replace_ident]
             $(#[doc $($doc)*])*
             $($tt)*
         }
@@ -333,7 +392,7 @@
         $($tt:tt)*
     ) => {
         $crate::__pin_project_internal! {
-            [][]
+            [][][]
             $($tt)*
         }
     };
@@ -357,6 +416,7 @@
     (@struct=>internal;
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
         [$proj_vis:vis]
         [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
         [$($def_generics:tt)*]
@@ -404,10 +464,26 @@
                 ),+
             }
         }
+        $crate::__pin_project_internal! { @struct=>make_proj_replace_ty=>named;
+            [$proj_vis]
+            [$($proj_replace_ident)?]
+            [make_proj_field_replace]
+            [$ident]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $(
+                    $(#[$pin])?
+                    $field_vis $field: $field_ty
+                ),+
+            }
+        }
 
-        #[allow(explicit_outlives_requirements)]
+        #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
-        #[allow(clippy::redundant_pub_crate)]
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
         #[allow(clippy::used_underscore_binding)]
         const _: () = {
             $crate::__pin_project_internal! { @struct=>make_proj_ty=>unnamed;
@@ -436,6 +512,19 @@
                     ),+
                 }
             }
+            $crate::__pin_project_internal! { @struct=>make_proj_replace_ty=>unnamed;
+                [$proj_vis]
+                [$($proj_replace_ident)?][ProjectionReplace]
+                [make_proj_field_replace]
+                [$ident]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                {
+                    $(
+                        $(#[$pin])?
+                        $field_vis $field: $field_ty
+                    ),+
+                }
+            }
 
             impl <$($impl_generics)*> $ident <$($ty_generics)*>
             $(where
@@ -465,6 +554,17 @@
                         ),+
                     }
                 }
+                $crate::__pin_project_internal! { @struct=>make_proj_replace_method;
+                    [$proj_vis]
+                    [$($proj_replace_ident)?][ProjectionReplace]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field_vis $field
+                        ),+
+                    }
+                }
             }
 
             $crate::__pin_project_internal! { @make_unpin_impl;
@@ -511,6 +611,7 @@
     (@enum=>internal;
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
         [$proj_vis:vis]
         [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
         [$($def_generics:tt)*]
@@ -576,8 +677,28 @@
                 ),+
             }
         }
+        $crate::__pin_project_internal! { @enum=>make_proj_replace_ty;
+            [$proj_vis]
+            [$($proj_replace_ident)?]
+            [make_proj_field_replace]
+            [$ident]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $(
+                    $variant $({
+                        $(
+                            $(#[$pin])?
+                            $field: $field_ty
+                        ),+
+                    })?
+                ),+
+            }
+        }
 
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
         #[allow(clippy::used_underscore_binding)]
         const _: () = {
             impl <$($impl_generics)*> $ident <$($ty_generics)*>
@@ -616,6 +737,21 @@
                         ),+
                     }
                 }
+                $crate::__pin_project_internal! { @enum=>make_proj_replace_method;
+                    [$proj_vis]
+                    [$($proj_replace_ident)?]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $variant $({
+                                $(
+                                    $(#[$pin])?
+                                    $field
+                                ),+
+                            })?
+                        ),+
+                    }
+                }
             }
 
             $crate::__pin_project_internal! { @make_unpin_impl;
@@ -684,8 +820,12 @@
     ) => {
         #[allow(dead_code)] // This lint warns unused fields/variants.
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
         #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
-        #[allow(clippy::redundant_pub_crate)]
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
         #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
         $proj_vis struct $proj_ty_ident <'__pin, $($impl_generics)*>
         where
@@ -707,6 +847,61 @@
         [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
         $($field:tt)*
     ) => {};
+
+    (@struct=>make_proj_replace_ty=>unnamed;
+        [$proj_vis:vis]
+        [$_proj_ty_ident:ident][$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($field:tt)*
+    ) => {};
+    (@struct=>make_proj_replace_ty=>unnamed;
+        [$proj_vis:vis]
+        [][$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($field:tt)*
+    ) => {
+    };
+    (@struct=>make_proj_replace_ty=>named;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident: $field_ty:ty
+            ),+
+        }
+    ) => {
+        #[allow(dead_code)] // This lint warns unused fields/variants.
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+        $proj_vis struct $proj_ty_ident <$($impl_generics)*>
+        where
+            $($($where_clause)*)?
+        {
+            $(
+                $field_vis $field: $crate::__pin_project_internal!(@$make_proj_field;
+                    $(#[$pin])? $field_ty
+                )
+            ),+
+        }
+    };
+    (@struct=>make_proj_replace_ty=>named;
+        [$proj_vis:vis]
+        []
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($field:tt)*
+    ) => {};
     // =============================================================================================
     // enum:make_proj_ty
     (@enum=>make_proj_ty;
@@ -728,8 +923,12 @@
     ) => {
         #[allow(dead_code)] // This lint warns unused fields/variants.
         #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
         #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
-        #[allow(clippy::redundant_pub_crate)]
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
         #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
         $proj_vis enum $proj_ty_ident <'__pin, $($impl_generics)*>
         where
@@ -756,6 +955,86 @@
         $($variant:tt)*
     ) => {};
 
+    (@enum=>make_proj_replace_ty;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident]
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        {
+            $(
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident: $field_ty:ty
+                    ),+
+                })?
+            ),+
+        }
+    ) => {
+        #[allow(dead_code)] // This lint warns unused fields/variants.
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+        $proj_vis enum $proj_ty_ident <$($impl_generics)*>
+        where
+            $($($where_clause)*)?
+        {
+            $(
+                $variant $({
+                    $(
+                        $field: $crate::__pin_project_internal!(@$make_proj_field;
+                            $(#[$pin])? $field_ty
+                        )
+                    ),+
+                })?
+            ),+
+        }
+    };
+    (@enum=>make_proj_replace_ty;
+        [$proj_vis:vis]
+        []
+        [$make_proj_field:ident]
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)* )?]
+        $($variant:tt)*
+    ) => {};
+
+    // =============================================================================================
+    (@make_proj_replace_block;
+        [$($proj_path: tt)+]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident
+            ),+
+        }
+    ) => {
+        let result = $($proj_path)* {
+            $(
+                $field: $crate::__pin_project_internal!(@make_replace_field_proj;
+                    $(#[$pin])? $field
+                )
+            ),+
+        };
+
+        {
+            ( $(
+                $crate::__pin_project_internal!(@make_unsafe_drop_in_place_guard;
+                    $(#[$pin])? $field
+                ),
+            )* );
+        }
+
+        result
+    };
+    (@make_proj_replace_block;
+        [$($proj_path: tt)+]
+    ) => {
+        $($proj_path)*
+    };
+
     // =============================================================================================
     // struct:make_proj_method
     (@struct=>make_proj_method;
@@ -800,6 +1079,54 @@
             $($variant)*
         }
     };
+
+    (@struct=>make_proj_replace_method;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident][$_proj_ty_ident:ident]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident
+            ),+
+        }
+    ) => {
+        $proj_vis fn project_replace(
+            self: $crate::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> $proj_ty_ident <$($ty_generics)*> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+                // Destructors will run in reverse order, so next create a guard to overwrite
+                // `self` with the replacement value without calling destructors.
+                let __guard = $crate::__private::UnsafeOverwriteGuard {
+                    target: __self_ptr,
+                    value: $crate::__private::ManuallyDrop::new(replacement),
+                };
+
+                let Self { $($field),* } = &mut *__self_ptr;
+
+                $crate::__pin_project_internal!{@make_proj_replace_block;
+                    [$proj_ty_ident]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field
+                        ),+
+                    }
+                }
+            }
+        }
+    };
+    (@struct=>make_proj_replace_method;
+        [$proj_vis:vis]
+        [][$proj_ty_ident:ident]
+        [$($ty_generics:tt)*]
+        $($variant:tt)*
+    ) => {
+    };
+
     // =============================================================================================
     // enum:make_proj_method
     (@enum=>make_proj_method;
@@ -849,6 +1176,62 @@
         $($variant:tt)*
     ) => {};
 
+    (@enum=>make_proj_replace_method;
+        [$proj_vis:vis]
+        [$proj_ty_ident:ident]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident
+                    ),+
+                })?
+            ),+
+        }
+    ) => {
+        $proj_vis fn project_replace(
+            self: $crate::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> $proj_ty_ident <$($ty_generics)*> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+                // Destructors will run in reverse order, so next create a guard to overwrite
+                // `self` with the replacement value without calling destructors.
+                let __guard = $crate::__private::UnsafeOverwriteGuard {
+                    target: __self_ptr,
+                    value: $crate::__private::ManuallyDrop::new(replacement),
+                };
+
+                match &mut *__self_ptr {
+                    $(
+                        Self::$variant $({
+                            $($field),+
+                        })? => {
+                            $crate::__pin_project_internal!{@make_proj_replace_block;
+                                [$proj_ty_ident :: $variant]
+                                $({
+                                    $(
+                                        $(#[$pin])?
+                                        $field
+                                    ),+
+                                })?
+                            }
+                        }
+                    ),+
+                }
+            }
+        }
+    };
+    (@enum=>make_proj_replace_method;
+        [$proj_vis:vis]
+        []
+        [$($ty_generics:tt)*]
+        $($variant:tt)*
+    ) => {};
+
     // =============================================================================================
     // make_unpin_impl
     (@make_unpin_impl;
@@ -951,6 +1334,35 @@
     };
 
     // =============================================================================================
+    // make_replace_field_proj
+    (@make_replace_field_proj;
+        #[pin]
+        $field:ident
+    ) => {
+        $crate::__private::PhantomData
+    };
+    (@make_replace_field_proj;
+        $field:ident
+    ) => {
+        $crate::__private::ptr::read($field)
+    };
+
+
+    // =============================================================================================
+    // make_unsafe_drop_in_place_guard
+    (@make_unsafe_drop_in_place_guard;
+        #[pin]
+        $field:ident
+    ) => {
+        $crate::__private::UnsafeDropInPlaceGuard($field)
+    };
+    (@make_unsafe_drop_in_place_guard;
+        $field:ident
+    ) => {
+        ()
+    };
+
+    // =============================================================================================
     // make_proj_field
     (@make_proj_field_mut;
         #[pin]
@@ -975,12 +1387,25 @@
         &'__pin ($field_ty)
     };
 
+    (@make_proj_field_replace;
+        #[pin]
+        $field_ty:ty
+    ) => {
+        $crate::__private::PhantomData<$field_ty>
+    };
+    (@make_proj_field_replace;
+        $field_ty:ty
+    ) => {
+        $field_ty
+    };
+
     // =============================================================================================
     // Parses input and determines visibility
     // struct
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         pub struct $ident:ident $(<
@@ -1009,6 +1434,7 @@
         $crate::__pin_project_internal! { @struct=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [pub(crate)]
             [$(#[$attrs])* pub struct $ident]
             [$(<
@@ -1045,6 +1471,7 @@
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         $vis:vis struct $ident:ident $(<
@@ -1073,6 +1500,7 @@
         $crate::__pin_project_internal! { @struct=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [$vis]
             [$(#[$attrs])* $vis struct $ident]
             [$(<
@@ -1110,6 +1538,7 @@
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         pub enum $ident:ident $(<
@@ -1143,6 +1572,7 @@
         $crate::__pin_project_internal! { @enum=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [pub(crate)]
             [$(#[$attrs])* pub enum $ident]
             [$(<
@@ -1184,6 +1614,7 @@
     (
         [$($proj_mut_ident:ident)?]
         [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
 
         $(#[$attrs:meta])*
         $vis:vis enum $ident:ident $(<
@@ -1217,6 +1648,7 @@
         $crate::__pin_project_internal! { @enum=>internal;
             [$($proj_mut_ident)?]
             [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
             [$vis]
             [$(#[$attrs])* $vis enum $ident]
             [$(<
@@ -1263,8 +1695,10 @@
     #[doc(hidden)]
     pub use core::{
         marker::{PhantomData, Unpin},
+        mem::ManuallyDrop,
         ops::Drop,
         pin::Pin,
+        ptr,
     };
 
     // This is an internal helper struct used by `pin_project!`.
@@ -1272,4 +1706,32 @@
     pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);
 
     impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
+
+    // This is an internal helper used to ensure a value is dropped.
+    #[doc(hidden)]
+    pub struct UnsafeDropInPlaceGuard<T: ?Sized>(pub *mut T);
+
+    impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
+        fn drop(&mut self) {
+            unsafe {
+                ptr::drop_in_place(self.0);
+            }
+        }
+    }
+
+    // This is an internal helper used to ensure a value is overwritten without
+    // its destructor being called.
+    #[doc(hidden)]
+    pub struct UnsafeOverwriteGuard<T> {
+        pub value: ManuallyDrop<T>,
+        pub target: *mut T,
+    }
+
+    impl<T> Drop for UnsafeOverwriteGuard<T> {
+        fn drop(&mut self) {
+            unsafe {
+                ptr::write(self.target, ptr::read(&*self.value));
+            }
+        }
+    }
 }
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
index af75bc5..5a91b20 100644
--- a/tests/compiletest.rs
+++ b/tests/compiletest.rs
@@ -1,3 +1,4 @@
+#![cfg(not(miri))]
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 
 use std::env;
diff --git a/tests/drop_order.rs b/tests/drop_order.rs
new file mode 100644
index 0000000..d84c324
--- /dev/null
+++ b/tests/drop_order.rs
@@ -0,0 +1,168 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+// Refs: https://doc.rust-lang.org/reference/destructors.html
+
+use pin_project_lite::pin_project;
+use std::{cell::Cell, panic, pin::Pin, thread};
+
+struct D<'a>(&'a Cell<usize>, usize);
+
+impl Drop for D<'_> {
+    fn drop(&mut self) {
+        if !thread::panicking() {
+            let old = self.0.replace(self.1);
+            assert_eq!(old, self.1 - 1);
+        }
+    }
+}
+
+pin_project! {
+#[project = StructPinnedProj]
+#[project_ref = StructPinnedProjRef]
+#[project_replace = StructPinnedProjReplace]
+struct StructPinned<'a> {
+    #[pin]
+    f1: D<'a>,
+    #[pin]
+    f2: D<'a>,
+}
+}
+
+pin_project! {
+#[project = StructUnpinnedProj]
+#[project_ref = StructUnpinnedProjRef]
+#[project_replace = StructUnpinnedProjReplace]
+struct StructUnpinned<'a> {
+    f1: D<'a>,
+    f2: D<'a>,
+}
+}
+
+pin_project! {
+#[project_replace = EnumProjReplace]
+enum Enum<'a> {
+    #[allow(dead_code)] // false positive that fixed in Rust 1.38
+    StructPinned {
+        #[pin]
+        f1: D<'a>,
+        #[pin]
+        f2: D<'a>,
+    },
+    #[allow(dead_code)] // false positive that fixed in Rust 1.38
+    StructUnpinned {
+        f1: D<'a>,
+        f2: D<'a>,
+    },
+}
+}
+
+#[test]
+fn struct_pinned() {
+    {
+        let c = Cell::new(0);
+        let _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+#[test]
+fn struct_unpinned() {
+    {
+        let c = Cell::new(0);
+        let _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+#[test]
+fn enum_struct() {
+    {
+        let c = Cell::new(0);
+        let _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+
+    {
+        let c = Cell::new(0);
+        let _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+// https://github.com/rust-lang/rust/issues/47949
+// https://github.com/taiki-e/pin-project/pull/194#discussion_r419098111
+#[allow(clippy::many_single_char_names)]
+#[test]
+fn project_replace_panic() {
+    pin_project! {
+    #[project_replace = SProjReplace]
+    struct S<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+    }
+
+    struct D<'a>(&'a mut bool, bool);
+    impl Drop for D<'_> {
+        fn drop(&mut self) {
+            *self.0 = true;
+            if self.1 {
+                panic!()
+            }
+        }
+    }
+
+    let (mut a, mut b, mut c, mut d) = (false, false, false, false);
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        let mut x = S { pinned: D(&mut a, true), unpinned: D(&mut b, false) };
+        let _y = Pin::new(&mut x)
+            .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
+        // Previous `x.pinned` was dropped and panicked when `project_replace` is
+        // called, so this is unreachable.
+        unreachable!();
+    }));
+    assert!(res.is_err());
+    assert!(a);
+    assert!(b);
+    assert!(c);
+    assert!(d);
+
+    let (mut a, mut b, mut c, mut d) = (false, false, false, false);
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        let mut x = S { pinned: D(&mut a, false), unpinned: D(&mut b, true) };
+        {
+            let _y = Pin::new(&mut x)
+                .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
+            // `_y` (previous `x.unpinned`) live to the end of this scope, so
+            // this is not unreachable.
+            // unreachable!();
+        }
+        unreachable!();
+    }));
+    assert!(res.is_err());
+    assert!(a);
+    assert!(b);
+    assert!(c);
+    assert!(d);
+}
diff --git a/tests/lint.rs b/tests/lint.rs
index bbc3033..46ec1df 100644
--- a/tests/lint.rs
+++ b/tests/lint.rs
@@ -40,8 +40,6 @@
 
 // Check interoperability with rustc and clippy lints.
 
-mod auxiliary;
-
 pub mod basic {
     include!("include/basic.rs");
 }
@@ -238,3 +236,27 @@
         }
     }
 }
+
+pub mod clippy_ref_option_ref {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        pub struct Struct<'a> {
+            #[pin]
+            pub _pinned: Option<&'a ()>,
+            pub _unpinned: Option<&'a ()>,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        pub enum Enum<'a> {
+            Struct {
+                #[pin]
+                _pinned: Option<&'a ()>,
+                _unpinned: Option<&'a ()>,
+            },
+        }
+    }
+}
diff --git a/tests/test.rs b/tests/test.rs
index cd4f48b..f4c29ee 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -4,7 +4,10 @@
 #[macro_use]
 mod auxiliary;
 
-use core::{marker::PhantomPinned, pin::Pin};
+use core::{
+    marker::{PhantomData, PhantomPinned},
+    pin::Pin,
+};
 use pin_project_lite::pin_project;
 
 #[test]
@@ -12,6 +15,8 @@
     pin_project! {
         #[project = StructProj]
         #[project_ref = StructProjRef]
+        #[project_replace = StructProjReplace]
+        #[derive(Default)]
         struct Struct<T, U> {
             #[pin]
             f1: T,
@@ -44,9 +49,19 @@
         let _: &i32 = f2;
     }
 
+    {
+        let StructProjReplace { f1: PhantomData, f2 } =
+            s.as_mut().project_replace(Default::default());
+        assert_eq!(f2, 2);
+        let StructProj { f1, f2 } = s.project();
+        assert_eq!(*f1, 0);
+        assert_eq!(*f2, 0);
+    }
+
     pin_project! {
         #[project = EnumProj]
         #[project_ref = EnumProjRef]
+        #[project_replace = EnumProjReplace]
         #[derive(Eq, PartialEq, Debug)]
         enum Enum<C, D> {
             Struct {
@@ -79,6 +94,11 @@
         let _: &mut i32 = f2;
         assert_eq!(*f2, 2);
     }
+
+    if let EnumProjReplace::Struct { f1: PhantomData, f2 } = e.as_mut().project_replace(Enum::Unit)
+    {
+        assert_eq!(f2, 2);
+    }
 }
 
 #[test]