Upgrade rust/crates/pin-project to 0.4.22

* Keep local change in src/lib.rs

Test: make
Change-Id: I63ca4a3f247df2028bcb6cb849823b296865f444
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 816bd88..c11a4ad 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -41,7 +41,7 @@
             rust: nightly
     runs-on: ${{ matrix.os || 'ubuntu' }}-latest
     steps:
-      - uses: actions/checkout@master
+      - uses: actions/checkout@v2
       - name: Install Rust
         run: |
           . ./ci/install-rust.sh ${{ matrix.rust }}
@@ -53,17 +53,19 @@
         if: matrix.rust == 'nightly'
         run: |
           rustup target add thumbv7m-none-eabi
+      - name: cargo test --tests
+        if: matrix.rust == '1.34.0' || matrix.rust == '1.36.0'
+        run: |
+          cargo test --all --all-features --exclude expandtest --tests
       - name: cargo test
+        if: matrix.rust != '1.34.0' && matrix.rust != '1.36.0'
         run: |
           cargo test --all --all-features --exclude expandtest
-      - name: cargo test (compiletest)
-        if: matrix.rust == 'nightly'
-        run: |
-          cargo test -p pin-project --all-features --test compiletest -- --ignored
       - name: cargo check (no-std)
         if: matrix.rust == 'nightly'
         run: |
           cargo check --target thumbv7m-none-eabi --manifest-path tests/no-std/Cargo.toml
+          cargo check --target thumbv7m-none-eabi --manifest-path tests/rust-2015/Cargo.toml
       - name: cargo check (minimal versions)
         if: matrix.rust == 'nightly'
         run: |
@@ -73,7 +75,7 @@
     name: expandtest
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@master
+      - uses: actions/checkout@v2
       - name: Install Rust
         run: |
           . ./ci/install-rust.sh
@@ -84,36 +86,47 @@
         run: |
           cargo test --all-features --manifest-path tests/expand/Cargo.toml
 
-  style:
-    name: style
-    strategy:
-      fail-fast: false
-      matrix:
-        component:
-          - clippy
-          - rustfmt
-          - rustdoc
+  clippy:
+    name: clippy
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@master
+      - uses: actions/checkout@v2
       - name: Install Rust
         run: |
           . ./ci/install-rust.sh
-      - name: Install component
+      - name: Install clippy
         run: |
-          . ./ci/install-component.sh ${{ matrix.component }}
+          . ./ci/install-component.sh clippy
       - name: cargo clippy
-        if: matrix.component == 'clippy'
         run: |
           cargo clippy --all --all-features --all-targets
-      - name: cargo fmt -- --check
-        if: matrix.component == 'rustfmt'
+
+  rustfmt:
+    name: rustfmt
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: |
+          . ./ci/install-rust.sh
+      - name: Install rustfmt
+        run: |
+          . ./ci/install-component.sh rustfmt
+      - name: cargo fmt --check
         run: |
           cargo fmt --all -- --check
+
+  rustdoc:
+    name: rustdoc
+    env:
+      RUSTDOCFLAGS: -Dwarnings
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install Rust
+        run: |
+          . ./ci/install-rust.sh
       - name: cargo doc
-        if: matrix.component == 'rustdoc'
-        env:
-          RUSTDOCFLAGS: -Dwarnings
         run: |
           cargo doc --no-deps --all --all-features
 
@@ -127,8 +140,10 @@
     name: ci
     if: github.event_name == 'push' && success()
     needs:
-      - style
       - test
+      - clippy
+      - rustfmt
+      - rustdoc
       - expandtest
     runs-on: ubuntu-latest
     steps:
@@ -138,8 +153,10 @@
     name: ci
     if: github.event_name == 'push' && !success()
     needs:
-      - style
       - test
+      - clippy
+      - rustfmt
+      - rustdoc
       - expandtest
     runs-on: ubuntu-latest
     steps:
diff --git a/.rustfmt.toml b/.rustfmt.toml
deleted file mode 100644
index dc49733..0000000
--- a/.rustfmt.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-# Rustfmt configuration
-# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
-
-# This is required for bug-fixes, which technically can't be made to the stable
-# first version.
-version = "Two" # Tracking issue: https://github.com/rust-lang/rustfmt/issues/3383
-
-# Refs: https://internals.rust-lang.org/t/running-rustfmt-on-rust-lang-rust-and-other-rust-lang-repositories/8732/72
-use_small_heuristics = "Max"
-
-# Apply rustfmt to more places.
-merge_imports = true # Tracking issue: https://github.com/rust-lang/rustfmt/issues/3362
-format_code_in_doc_comments = true # Tracking issue: https://github.com/rust-lang/rustfmt/issues/3348
-
-# Set the default settings again to always apply the proper formatting without
-# being affected by the editor settings.
-# Refs: https://github.com/rust-lang/rls/issues/501#issuecomment-333717736
-edition = "2018"
-tab_spaces = 4
diff --git a/Android.bp b/Android.bp
index 63eb84a..c7fea1d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,7 +12,7 @@
 }
 
 // dependent_library ["feature_list"]
-//   pin-project-internal-0.4.17
+//   pin-project-internal-0.4.22
 //   proc-macro2-1.0.18 "default,proc-macro"
 //   quote-1.0.7 "default,proc-macro"
 //   syn-1.0.34 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit-mut"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed7cfbc..d40af34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,9 +6,97 @@
 
 ## [Unreleased]
 
+## [0.4.22] - 2020-06-14
+
+* Documentation improvements.
+
+## [0.4.21] - 2020-06-13
+
+* [Deprecated `#[project]`, `#[project_ref]`, and `#[project_replace]` attributes due to some unfixable limitations.][244]
+
+  Consider naming the projected type by passing an argument with the same name as the method to the #[pin_project] attribute instead.
+
+  ```rust
+  use pin_project::pin_project;
+  use std::pin::Pin;
+
+  #[pin_project(project = EnumProj)]
+  enum Enum<T> {
+      Variant(#[pin] T),
+  }
+
+  fn func<T>(x: Pin<&mut Enum<T>>) {
+      match x.project() {
+          EnumProj::Variant(y) => {
+              let _: Pin<&mut T> = y;
+          }
+      }
+  }
+  ```
+
+  See [#225][225] for more details.
+
+* [Support `Self` in fields and generics in type definitions.][245]
+
+* [Fix errors involving *"`self` value is a keyword only available in methods with `self` parameter"* in apparently correct code.][250]
+
+* Diagnostic improvements.
+
+[225]: https://github.com/taiki-e/pin-project/pull/225
+[244]: https://github.com/taiki-e/pin-project/pull/244
+[245]: https://github.com/taiki-e/pin-project/pull/245
+[250]: https://github.com/taiki-e/pin-project/pull/250
+
+## [0.4.20] - 2020-06-07
+
+* [You can now use project_replace argument without Replace argument.][243]
+  This used to require you to specify both.
+
+  ```diff
+  - #[pin_project(Replace, project_replace = EnumProjOwn)]
+  + #[pin_project(project_replace = EnumProjOwn)]
+    enum Enum<T> {
+        Variant(#[pin] T)
+    }
+  ```
+
+* [Makes `project_replace` argument an alias for `Replace` argument so that it can be used without a value.][243]
+
+  ```rust
+  #[pin_project(project_replace)]
+  enum Enum<T> {
+      Variant(#[pin] T)
+  }
+  ```
+
+  *The `Replace` argument will be deprecated in the future.*
+
+* Suppress `unreachable_pub` lint in generated code.
+
+[243]: https://github.com/taiki-e/pin-project/pull/243
+
+## [0.4.19] - 2020-06-04
+
+* [Fix `unused_results` lint in generated code.][239]
+
+[239]: https://github.com/taiki-e/pin-project/pull/239
+
+## [0.4.18] - 2020-06-04
+
+* [Support `Self` in more syntax positions inside `#[pinned_drop]` impl.][230]
+
+* [Suppress `clippy::type_repetition_in_bounds` and `clippy::used_underscore_binding` lints in generated code.][233]
+
+* Documentation improvements.
+
+* Diagnostic improvements.
+
+[230]: https://github.com/taiki-e/pin-project/pull/230
+[233]: https://github.com/taiki-e/pin-project/pull/233
+
 ## [0.4.17] - 2020-05-18
 
-* [Allowed naming the projected types.][202]
+* [Support naming the projection types.][202]
 
   By passing an argument with the same name as the method to the attribute, you can name the projection type returned from the method:
 
@@ -73,11 +161,13 @@
 
 * [Fixed an issue where duplicate `#[project]` attributes were ignored.][218]
 
-* [Fixed compile error and warnings with HRTB.][217]
+* [Suppress `single_use_lifetimes` lint in generated code.][217]
 
-* [Hide generated items from --document-private-items.][211] See [#211][211] for more details.
+* [Support overlapping lifetime names in HRTB.][217]
 
-* Improve documentation
+* [Hide generated items from --document-private-items.][211] See [#211][211] for details.
+
+* Documentation improvements.
 
 [211]: https://github.com/taiki-e/pin-project/pull/211
 [217]: https://github.com/taiki-e/pin-project/pull/217
@@ -94,7 +184,11 @@
 
   * [Support overwriting the name of core crate.][199]
 
-  * Improve documentation
+  * [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.][200]
+
+  * Documentation improvements.
+
+  * Diagnostic improvements.
 
 [207]: https://github.com/taiki-e/pin-project/pull/207
 
@@ -110,10 +204,15 @@
 
 * [Support overwriting the name of core crate.][199]
 
-* Improve documentation
+* [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.][200]
+
+* Documentation improvements.
+
+* Diagnostic improvements.
 
 [197]: https://github.com/taiki-e/pin-project/pull/197
 [199]: https://github.com/taiki-e/pin-project/pull/199
+[200]: https://github.com/taiki-e/pin-project/pull/200
 
 ## [0.4.10] - 2020-05-04
 
@@ -121,6 +220,12 @@
   `project_replace` method is optional and can be enabled by passing the `Replace` argument to `#[pin_project]` attribute.
   See [the documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#project_replace) for more details.
 
+* [Support `Self` and `self` in more syntax positions inside `#[pinned_drop]` impl.][190]
+
+* [Hided all generated items except for projected types from calling code.][192] See [#192][192] for details.
+
+[190]: https://github.com/taiki-e/pin-project/pull/190
+[192]: https://github.com/taiki-e/pin-project/pull/192
 [194]: https://github.com/taiki-e/pin-project/pull/194
 
 ## [0.4.9] - 2020-04-14
@@ -139,6 +244,9 @@
 
 * [Ensured that users cannot implement `PinnedDrop` without proper attribute argument.][180]
 
+* [Fixed use of `Self` in expression position inside `#[pinned_drop]` impl.][177]
+
+[177]: https://github.com/taiki-e/pin-project/pull/180
 [180]: https://github.com/taiki-e/pin-project/pull/180
 
 ## [0.4.7] - 2020-01-20
@@ -173,6 +281,8 @@
 
 * [Fixed support for DSTs(Dynamically Sized Types) on `#[pin_project(UnsafeUnpin)]`][120]
 
+* Diagnostic improvements.
+
 [120]: https://github.com/taiki-e/pin-project/pull/120
 [135]: https://github.com/taiki-e/pin-project/pull/135
 
@@ -262,7 +372,7 @@
 
 * Added some examples and generated code.
 
-* Improve error messages.
+* Diagnostic improvements.
 
 [86]: https://github.com/taiki-e/pin-project/pull/86
 
@@ -270,7 +380,7 @@
 
 * [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
 
-* Improved documentation.
+* Documentation improvements.
 
 [77]: https://github.com/taiki-e/pin-project/pull/77
 
@@ -292,14 +402,14 @@
 
 * [Improved document of generated code.][62]. Also added an option to control the document of generated code. See [#62][62] for more details.
 
-* [Improved error messages][61]
+* [Diagnostic improvements.][61]
 
 [61]: https://github.com/taiki-e/pin-project/pull/61
 [62]: https://github.com/taiki-e/pin-project/pull/62
 
 ## [0.4.0-alpha.7] - 2019-09-02
 
-* [Applied `#[allow(dead_code)]` to generated types.][57]
+* [Suppress `dead_code` lint in generated types.][57]
 
 [57]: https://github.com/taiki-e/pin-project/pull/57
 
@@ -317,7 +427,7 @@
 
 ## [0.4.0-alpha.4] - 2019-08-23
 
-* Avoided clippy::drop_bounds lint in generated code.
+* Suppress `clippy::drop_bounds` lint in generated code.
 
 ## [0.4.0-alpha.3] - 2019-08-23
 
@@ -359,11 +469,11 @@
 
 ## [0.3.4] - 2019-07-21
 
-* Improved error messages.
+* Diagnostic improvements.
 
 ## [0.3.3] - 2019-07-15 - YANKED
 
-* Improved error messages.
+* Diagnostic improvements.
 
 ## [0.3.2] - 2019-03-30
 
@@ -371,7 +481,7 @@
 
 ## [0.3.1] - 2019-03-02
 
-* Improved documentation.
+* Documentation improvements.
 
 * Updated minimum `syn` version to 0.15.22.
 
@@ -393,7 +503,7 @@
 
 * Made `unsafe_fields` optional.
 
-* Improved documentation.
+* Documentation improvements.
 
 ## [0.1.8] - 2019-02-02
 
@@ -427,7 +537,7 @@
 
 ## [0.1.2] - 2019-01-09
 
-* Improved documentation.
+* Documentation improvements.
 
 ## [0.1.1] - 2019-01-08
 
@@ -437,7 +547,12 @@
 
 Initial release
 
-[Unreleased]: https://github.com/taiki-e/pin-project/compare/v0.4.17...HEAD
+[Unreleased]: https://github.com/taiki-e/pin-project/compare/v0.4.22...HEAD
+[0.4.22]: https://github.com/taiki-e/pin-project/compare/v0.4.21...v0.4.22
+[0.4.21]: https://github.com/taiki-e/pin-project/compare/v0.4.20...v0.4.21
+[0.4.20]: https://github.com/taiki-e/pin-project/compare/v0.4.19...v0.4.20
+[0.4.19]: https://github.com/taiki-e/pin-project/compare/v0.4.18...v0.4.19
+[0.4.18]: https://github.com/taiki-e/pin-project/compare/v0.4.17...v0.4.18
 [0.4.17]: https://github.com/taiki-e/pin-project/compare/v0.4.16...v0.4.17
 [0.4.16]: https://github.com/taiki-e/pin-project/compare/v0.4.15...v0.4.16
 [0.4.15]: https://github.com/taiki-e/pin-project/compare/v0.4.14...v0.4.15
diff --git a/Cargo.toml b/Cargo.toml
index df64f70..bca571c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "pin-project"
-version = "0.4.17"
+version = "0.4.22"
 authors = ["Taiki Endo <te316e89@gmail.com>"]
 description = "A crate for safe and ergonomic pin-projection.\n"
 homepage = "https://github.com/taiki-e/pin-project"
@@ -26,5 +26,5 @@
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
 [dependencies.pin-project-internal]
-version = "=0.4.17"
+version = "=0.4.22"
 default-features = false
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 3c43001..86f4cab 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "pin-project"
-version = "0.4.17"
+version = "0.4.22"
 authors = ["Taiki Endo <te316e89@gmail.com>"]
 edition = "2018"
 license = "Apache-2.0 OR MIT"
@@ -23,9 +23,11 @@
     "tests/ui/auxiliary",
     "tests/doc",
     "tests/expand",
-    "tests/rust-2015"
+    "tests/no-core",
+    "tests/no-std",
+    "tests/rust-2015",
 ]
 
 [dependencies]
-pin-project-internal = { version = "=0.4.17", path = "pin-project-internal", default-features = false }
+pin-project-internal = { version = "=0.4.22", path = "pin-project-internal", default-features = false }
 
diff --git a/METADATA b/METADATA
index 09ca0bf..50afc3f 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/taiki-e/pin-project"
   }
-  version: "0.4.17"
+  version: "0.4.22"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 5
-    day: 18
+    month: 7
+    day: 10
   }
 }
diff --git a/README.md b/README.md
index 840d1fa..caee4d3 100644
--- a/README.md
+++ b/README.md
@@ -9,16 +9,12 @@
 [crates-url]: https://crates.io/crates/pin-project
 [docs-badge]: https://docs.rs/pin-project/badge.svg
 [docs-url]: https://docs.rs/pin-project
-[license-badge]: https://img.shields.io/crates/l/pin-project.svg
+[license-badge]: https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg
 [license]: #license
 [rustc-badge]: https://img.shields.io/badge/rustc-1.34+-lightgray.svg
 [rustc-url]: https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html
 
-A crate for safe and ergonomic pin-projection.
-
-[Documentation][docs-url]
-
-[Examples](examples/README.md)
+A crate for safe and ergonomic [pin-projection].
 
 ## Usage
 
@@ -33,7 +29,8 @@
 
 ## Examples
 
-[`pin_project`] attribute creates a projection struct covering all the fields.
+[`#[pin_project]`][`pin_project`] attribute creates projection types
+covering all the fields of struct or enum.
 
 ```rust
 use pin_project::pin_project;
@@ -47,7 +44,7 @@
 }
 
 impl<T, U> Struct<T, U> {
-    fn foo(self: Pin<&mut Self>) {
+    fn method(self: Pin<&mut Self>) {
         let this = self.project();
         let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
         let _: &mut U = this.unpinned; // Normal reference to the field
@@ -55,13 +52,21 @@
 }
 ```
 
-[Code like this will be generated](examples/struct-default-expanded.rs)
+[*code like this will be generated*][struct-default-expanded]
 
-See [API documentation][docs-url] for more details.
-
-Also, there are examples and generated code of each feature in [examples](examples/README.md) directory.
+See [documentation][docs-url] for more details, and
+see [examples] directory for more examples and generated code.
 
 [`pin_project`]: https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html
+[examples]: examples/README.md
+[pin-projection]: https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning
+[struct-default-expanded]: examples/struct-default-expanded.rs
+
+## Related Projects
+
+* [pin-project-lite]: A lightweight version of pin-project written with declarative macros.
+
+[pin-project-lite]: https://github.com/taiki-e/pin-project-lite
 
 ## License
 
diff --git a/ci.sh b/ci.sh
index df0131e..7f82c47 100644
--- a/ci.sh
+++ b/ci.sh
@@ -8,21 +8,18 @@
 # . ./ci.sh
 # ```
 
-echo "Running 'cargo fmt -- --check'"
-cargo +nightly fmt --all -- --check
+echo "Running 'cargo fmt'"
+cargo +nightly fmt --all
 
 echo "Running 'cargo clippy'"
 cargo +nightly clippy --all --all-features --all-targets
 
 echo "Running 'cargo test'"
-cargo +nightly test --all --all-features
+cargo +nightly test --all --all-features --exclude expandtest
 
 echo "Running 'cargo doc'"
 cargo +nightly doc --no-deps --all --all-features
 
-echo "Running 'compiletest'"
-. ./compiletest.sh
-
 echo "Running 'expandtest'"
 # See also https://docs.rs/macrotest/1/macrotest/#updating-expandedrs
 # rm **/*.expanded.rs
diff --git a/ci/check-minimal-versions.sh b/ci/check-minimal-versions.sh
index a11d2cb..6152c15 100644
--- a/ci/check-minimal-versions.sh
+++ b/ci/check-minimal-versions.sh
@@ -1,8 +1,8 @@
 #!/bin/bash
 # Check all public crates with minimal version dependencies.
 #
-# Note that this script modifies Cargo.toml and Cargo.lock and does not restore
-# them after a run.
+# Note that this script modifies Cargo.toml and Cargo.lock while this script is
+# running, and it is an error if there are any unstaged changes.
 #
 # Refs:
 # * minimal versions: https://github.com/rust-lang/cargo/issues/5657
@@ -10,10 +10,18 @@
 
 set -euo pipefail
 
+# This script modifies Cargo.toml and Cargo.lock, so make sure there are no
+# unstaged changes.
+git diff --exit-code
+
 # Remove dev-dependencies from Cargo.toml to prevent the next `cargo update`
 # from determining minimal versions based on dev-dependencies.
 cargo hack --remove-dev-deps --workspace
+
 # Update Cargo.lock to minimal version dependencies.
 cargo update -Zminimal-versions
 # Run check for all public members of the workspace.
 cargo hack check --workspace --all-features --ignore-private -Zfeatures=all
+
+# Restore original Cargo.toml and Cargo.lock.
+git checkout .
diff --git a/ci/install-component.sh b/ci/install-component.sh
index 37ccdfa..9aaa5ce 100644
--- a/ci/install-component.sh
+++ b/ci/install-component.sh
@@ -4,7 +4,7 @@
 
 component="${1}"
 
-if [[ "${component}" != "rustdoc" ]] && ! rustup component add "${component}" 2>/dev/null; then
+if ! rustup component add "${component}" 2>/dev/null; then
     # If the component is unavailable on the latest nightly,
     # use the latest toolchain with the component available.
     # Refs: https://github.com/rust-lang/rustup-components-history#the-web-part
@@ -17,6 +17,6 @@
 fi
 
 case "${component}" in
-    rustfmt | rustdoc) "${component}" -V ;;
+    rustfmt) "${component}" -V ;;
     *) cargo "${component}" -V ;;
 esac
diff --git a/compiletest.sh b/compiletest.sh
deleted file mode 100644
index 9af5a5f..0000000
--- a/compiletest.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-# A script to run compile tests with the same condition of the checks done by CI.
-#
-# Usage
-#
-# ```sh
-# . ./compiletest.sh
-# ```
-
-TRYBUILD=overwrite cargo +nightly test -p pin-project --all-features --test compiletest -- --ignored
-# cargo +nightly test -p pin-project --all-features --test compiletest -- --ignored
diff --git a/examples/enum-default-expanded.rs b/examples/enum-default-expanded.rs
index 845645a..3e7cb3c 100644
--- a/examples/enum-default-expanded.rs
+++ b/examples/enum-default-expanded.rs
@@ -15,7 +15,7 @@
 // ```
 
 #![allow(dead_code, unused_imports, unused_parens)]
-#![allow(clippy::no_effect, clippy::just_underscores_and_digits)]
+#![allow(clippy::just_underscores_and_digits)]
 
 use pin_project::pin_project;
 
@@ -24,51 +24,54 @@
     Unpinned(U),
 }
 
-#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::type_repetition_in_bounds)]
 enum EnumProj<'pin, T, U>
 where
     Enum<T, U>: 'pin,
 {
-    Pinned(::pin_project::__reexport::pin::Pin<&'pin mut (T)>),
+    Pinned(::pin_project::__private::Pin<&'pin mut (T)>),
     Unpinned(&'pin mut (U)),
 }
 #[doc(hidden)]
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::type_repetition_in_bounds)]
 enum __EnumProjectionRef<'pin, T, U>
 where
     Enum<T, U>: 'pin,
 {
-    Pinned(::pin_project::__reexport::pin::Pin<&'pin (T)>),
+    Pinned(::pin_project::__private::Pin<&'pin (T)>),
     Unpinned(&'pin (U)),
 }
 
 #[doc(hidden)]
 #[allow(non_upper_case_globals)]
 #[allow(single_use_lifetimes)]
-const __SCOPE_Enum: () = {
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
     impl<T, U> Enum<T, U> {
         fn project<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin mut Self>,
+            self: ::pin_project::__private::Pin<&'pin mut Self>,
         ) -> EnumProj<'pin, T, U> {
             unsafe {
                 match self.get_unchecked_mut() {
                     Enum::Pinned(_0) => {
-                        EnumProj::Pinned(::pin_project::__reexport::pin::Pin::new_unchecked(_0))
+                        EnumProj::Pinned(::pin_project::__private::Pin::new_unchecked(_0))
                     }
                     Enum::Unpinned(_0) => EnumProj::Unpinned(_0),
                 }
             }
         }
         fn project_ref<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin Self>,
+            self: ::pin_project::__private::Pin<&'pin Self>,
         ) -> __EnumProjectionRef<'pin, T, U> {
             unsafe {
                 match self.get_ref() {
                     Enum::Pinned(_0) => __EnumProjectionRef::Pinned(
-                        ::pin_project::__reexport::pin::Pin::new_unchecked(_0),
+                        ::pin_project::__private::Pin::new_unchecked(_0),
                     ),
                     Enum::Unpinned(_0) => __EnumProjectionRef::Unpinned(_0),
                 }
@@ -84,8 +87,8 @@
         __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
         __field0: T,
     }
-    impl<'pin, T, U> ::pin_project::__reexport::marker::Unpin for Enum<T, U> where
-        __Enum<'pin, T, U>: ::pin_project::__reexport::marker::Unpin
+    impl<'pin, T, U> ::pin_project::__private::Unpin for Enum<T, U> where
+        __Enum<'pin, T, U>: ::pin_project::__private::Unpin
     {
     }
     unsafe impl<T, U> ::pin_project::UnsafeUnpin for Enum<T, U> {}
@@ -95,10 +98,10 @@
     // See ./struct-default-expanded.rs for details.
     trait EnumMustNotImplDrop {}
     #[allow(clippy::drop_bounds)]
-    impl<T: ::pin_project::__reexport::ops::Drop> EnumMustNotImplDrop for T {}
+    impl<T: ::pin_project::__private::Drop> EnumMustNotImplDrop for T {}
     impl<T, U> EnumMustNotImplDrop for Enum<T, U> {}
     impl<T, U> ::pin_project::__private::PinnedDrop for Enum<T, U> {
-        unsafe fn drop(self: ::pin_project::__reexport::pin::Pin<&mut Self>) {}
+        unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
 
     // We don't need to check for `#[repr(packed)]`,
diff --git a/examples/not_unpin-expanded.rs b/examples/not_unpin-expanded.rs
index 45f1321..fdfe5a2 100644
--- a/examples/not_unpin-expanded.rs
+++ b/examples/not_unpin-expanded.rs
@@ -30,50 +30,53 @@
 }
 
 #[doc(hidden)]
-#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::type_repetition_in_bounds)]
 pub(crate) struct __StructProjection<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin mut (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
     unpinned: &'pin mut (U),
 }
 #[doc(hidden)]
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::type_repetition_in_bounds)]
 pub(crate) struct __StructProjectionRef<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin (T)>,
     unpinned: &'pin (U),
 }
 
 #[doc(hidden)]
 #[allow(non_upper_case_globals)]
 #[allow(single_use_lifetimes)]
-const __SCOPE_Struct: () = {
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
     impl<T, U> Struct<T, U> {
         pub(crate) fn project<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin mut Self>,
+            self: ::pin_project::__private::Pin<&'pin mut Self>,
         ) -> __StructProjection<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_unchecked_mut();
                 __StructProjection {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
         }
         pub(crate) fn project_ref<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin Self>,
+            self: ::pin_project::__private::Pin<&'pin Self>,
         ) -> __StructProjectionRef<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_ref();
                 __StructProjectionRef {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
@@ -84,17 +87,17 @@
     //
     // See https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282
     // for details.
-    impl<'pin, T, U> ::pin_project::__reexport::marker::Unpin for Struct<T, U> where
-        ::pin_project::__private::Wrapper<'pin, ::pin_project::__reexport::marker::PhantomPinned>:
-            ::pin_project::__reexport::marker::Unpin
+    impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
+        ::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>:
+            ::pin_project::__private::Unpin
     {
     }
     // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
     //
     // To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
-    // impls, we emit one ourselves. If the user ends up writing a `UnsafeUnpin` impl,
-    // they'll get a "conflicting implementations of trait" error when coherence
-    // checks are run.
+    // impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
+    // impl, they'll get a "conflicting implementations of trait" error when
+    // coherence checks are run.
     unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> {}
 
     // Ensure that struct does not implement `Drop`.
@@ -102,13 +105,14 @@
     // See ./struct-default-expanded.rs for details.
     trait StructMustNotImplDrop {}
     #[allow(clippy::drop_bounds)]
-    impl<T: ::pin_project::__reexport::ops::Drop> StructMustNotImplDrop for T {}
+    impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
     impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
-        unsafe fn drop(self: ::pin_project::__reexport::pin::Pin<&mut Self>) {}
+        unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
 
-    // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+    // Ensure that it's impossible to use pin projections on a #[repr(packed)]
+    // struct.
     //
     // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
     // for details.
diff --git a/examples/pinned_drop-expanded.rs b/examples/pinned_drop-expanded.rs
index 15dde89..8f295e9 100644
--- a/examples/pinned_drop-expanded.rs
+++ b/examples/pinned_drop-expanded.rs
@@ -34,61 +34,64 @@
 }
 
 #[doc(hidden)]
-#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::type_repetition_in_bounds)]
 pub(crate) struct __StructProjection<'pin, 'a, T>
 where
     Struct<'a, T>: 'pin,
 {
     was_dropped: &'pin mut (&'a mut bool),
-    field: ::pin_project::__reexport::pin::Pin<&'pin mut (T)>,
+    field: ::pin_project::__private::Pin<&'pin mut (T)>,
 }
 #[doc(hidden)]
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::type_repetition_in_bounds)]
 pub(crate) struct __StructProjectionRef<'pin, 'a, T>
 where
     Struct<'a, T>: 'pin,
 {
     was_dropped: &'pin (&'a mut bool),
-    field: ::pin_project::__reexport::pin::Pin<&'pin (T)>,
+    field: ::pin_project::__private::Pin<&'pin (T)>,
 }
 
 #[doc(hidden)]
 #[allow(non_upper_case_globals)]
 #[allow(single_use_lifetimes)]
-const __SCOPE_Struct: () = {
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
     impl<'a, T> Struct<'a, T> {
         pub(crate) fn project<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin mut Self>,
+            self: ::pin_project::__private::Pin<&'pin mut Self>,
         ) -> __StructProjection<'pin, 'a, T> {
             unsafe {
                 let Self { was_dropped, field } = self.get_unchecked_mut();
                 __StructProjection {
                     was_dropped,
-                    field: ::pin_project::__reexport::pin::Pin::new_unchecked(field),
+                    field: ::pin_project::__private::Pin::new_unchecked(field),
                 }
             }
         }
         pub(crate) fn project_ref<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin Self>,
+            self: ::pin_project::__private::Pin<&'pin Self>,
         ) -> __StructProjectionRef<'pin, 'a, T> {
             unsafe {
                 let Self { was_dropped, field } = self.get_ref();
                 __StructProjectionRef {
                     was_dropped,
-                    field: ::pin_project::__reexport::pin::Pin::new_unchecked(field),
+                    field: ::pin_project::__private::Pin::new_unchecked(field),
                 }
             }
         }
     }
 
-    impl<'a, T> ::pin_project::__reexport::ops::Drop for Struct<'a, T> {
+    impl<'a, T> ::pin_project::__private::Drop for Struct<'a, T> {
         fn drop(&mut self) {
             // Safety - we're in 'drop', so we know that 'self' will
             // never move again.
-            let pinned_self = unsafe { ::pin_project::__reexport::pin::Pin::new_unchecked(self) };
+            let pinned_self = unsafe { ::pin_project::__private::Pin::new_unchecked(self) };
             // We call `pinned_drop` only once. Since `PinnedDrop::drop`
             // is an unsafe method and a private API, it is never called again in safe
             // code *unless the user uses a maliciously crafted macro*.
@@ -107,13 +110,14 @@
         __field0: T,
         __lifetime0: &'a (),
     }
-    impl<'pin, 'a, T> ::pin_project::__reexport::marker::Unpin for Struct<'a, T> where
-        __Struct<'pin, 'a, T>: ::pin_project::__reexport::marker::Unpin
+    impl<'pin, 'a, T> ::pin_project::__private::Unpin for Struct<'a, T> where
+        __Struct<'pin, 'a, T>: ::pin_project::__private::Unpin
     {
     }
     unsafe impl<'a, T> ::pin_project::UnsafeUnpin for Struct<'a, T> {}
 
-    // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+    // Ensure that it's impossible to use pin projections on a #[repr(packed)]
+    // struct.
     //
     // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
     // for details.
diff --git a/examples/project_replace-expanded.rs b/examples/project_replace-expanded.rs
index ec9f00e..661a0ac 100644
--- a/examples/project_replace-expanded.rs
+++ b/examples/project_replace-expanded.rs
@@ -5,7 +5,7 @@
 //
 // use pin_project::pin_project;
 //
-// #[pin_project(Replace)]
+// #[pin_project(project_replace)]
 // struct Struct<T, U> {
 //     #[pin]
 //     pinned: T,
@@ -27,64 +27,67 @@
 }
 
 #[doc(hidden)]
-#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::type_repetition_in_bounds)]
 struct __StructProjection<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin mut (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
     unpinned: &'pin mut (U),
 }
 #[doc(hidden)]
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::type_repetition_in_bounds)]
 struct __StructProjectionRef<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin (T)>,
     unpinned: &'pin (U),
 }
-
 #[doc(hidden)]
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
+#[allow(unreachable_pub)]
 #[allow(single_use_lifetimes)]
 struct __StructProjectionOwned<T, U> {
-    pinned: ::pin_project::__reexport::marker::PhantomData<T>,
+    pinned: ::pin_project::__private::PhantomData<T>,
     unpinned: U,
 }
 
 #[doc(hidden)]
 #[allow(non_upper_case_globals)]
 #[allow(single_use_lifetimes)]
-const __SCOPE_Struct: () = {
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
     impl<T, U> Struct<T, U> {
         fn project<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin mut Self>,
+            self: ::pin_project::__private::Pin<&'pin mut Self>,
         ) -> __StructProjection<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_unchecked_mut();
                 __StructProjection {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
         }
         fn project_ref<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin Self>,
+            self: ::pin_project::__private::Pin<&'pin Self>,
         ) -> __StructProjectionRef<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_ref();
                 __StructProjectionRef {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
         }
         fn project_replace(
-            self: ::pin_project::__reexport::pin::Pin<&mut Self>,
+            self: ::pin_project::__private::Pin<&mut Self>,
             __replacement: Self,
         ) -> __StructProjectionOwned<T, U> {
             unsafe {
@@ -93,15 +96,15 @@
 
                 // First, extract all the unpinned fields
                 let __result = __StructProjectionOwned {
-                    pinned: ::pin_project::__reexport::marker::PhantomData,
-                    unpinned: ::pin_project::__reexport::ptr::read(unpinned),
+                    pinned: ::pin_project::__private::PhantomData,
+                    unpinned: ::pin_project::__private::ptr::read(unpinned),
                 };
 
                 // Destructors will run in reverse order, so next create a guard to overwrite
                 // `self` with the replacement value without calling destructors.
                 let __guard = ::pin_project::__private::UnsafeOverwriteGuard {
                     target: __self_ptr,
-                    value: ::pin_project::__reexport::mem::ManuallyDrop::new(__replacement),
+                    value: ::pin_project::__private::ManuallyDrop::new(__replacement),
                 };
 
                 // Now create guards to drop all the pinned fields
@@ -127,8 +130,8 @@
         __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
         __field0: T,
     }
-    impl<'pin, T, U> ::pin_project::__reexport::marker::Unpin for Struct<T, U> where
-        __Struct<'pin, T, U>: ::pin_project::__reexport::marker::Unpin
+    impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
+        __Struct<'pin, T, U>: ::pin_project::__private::Unpin
     {
     }
     unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> {}
@@ -138,13 +141,14 @@
     // See ./struct-default-expanded.rs for details.
     trait StructMustNotImplDrop {}
     #[allow(clippy::drop_bounds)]
-    impl<T: ::pin_project::__reexport::ops::Drop> StructMustNotImplDrop for T {}
+    impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
     impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
-        unsafe fn drop(self: ::pin_project::__reexport::pin::Pin<&mut Self>) {}
+        unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
 
-    // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+    // Ensure that it's impossible to use pin projections on a #[repr(packed)]
+    // struct.
     //
     // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
     // for details.
diff --git a/examples/project_replace.rs b/examples/project_replace.rs
index 4482625..99cec18 100644
--- a/examples/project_replace.rs
+++ b/examples/project_replace.rs
@@ -4,7 +4,7 @@
 
 use pin_project::pin_project;
 
-#[pin_project(Replace)]
+#[pin_project(project_replace)]
 struct Struct<T, U> {
     #[pin]
     pinned: T,
diff --git a/examples/struct-default-expanded.rs b/examples/struct-default-expanded.rs
index 2bf7edd..53f00c9 100644
--- a/examples/struct-default-expanded.rs
+++ b/examples/struct-default-expanded.rs
@@ -27,50 +27,53 @@
 }
 
 #[doc(hidden)]
-#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::type_repetition_in_bounds)]
 struct __StructProjection<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin mut (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
     unpinned: &'pin mut (U),
 }
 #[doc(hidden)]
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::type_repetition_in_bounds)]
 struct __StructProjectionRef<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin (T)>,
     unpinned: &'pin (U),
 }
 
 #[doc(hidden)]
 #[allow(non_upper_case_globals)]
 #[allow(single_use_lifetimes)]
-const __SCOPE_Struct: () = {
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
     impl<T, U> Struct<T, U> {
         fn project<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin mut Self>,
+            self: ::pin_project::__private::Pin<&'pin mut Self>,
         ) -> __StructProjection<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_unchecked_mut();
                 __StructProjection {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
         }
         fn project_ref<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin Self>,
+            self: ::pin_project::__private::Pin<&'pin Self>,
         ) -> __StructProjectionRef<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_ref();
                 __StructProjectionRef {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
@@ -91,9 +94,9 @@
     // When RFC 2145 is implemented (rust-lang/rust#48054),
     // this will become a lint, rather then a hard error.
     //
-    // As a workaround for this, we generate a new struct, containing all of the pinned
-    // fields from our #[pin_project] type. This struct is declared within
-    // a function, which makes it impossible to be named by user code.
+    // As a workaround for this, we generate a new struct, containing all of
+    // the pinned fields from our #[pin_project] type. This struct is declared
+    // within a function, which makes it impossible to be named by user code.
     // This guarantees that it will use the default auto-trait impl for Unpin -
     // that is, it will implement Unpin iff all of its fields implement Unpin.
     // This type can be safely declared as 'public', satisfying the privacy
@@ -107,16 +110,16 @@
         __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
         __field0: T,
     }
-    impl<'pin, T, U> ::pin_project::__reexport::marker::Unpin for Struct<T, U> where
-        __Struct<'pin, T, U>: ::pin_project::__reexport::marker::Unpin
+    impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
+        __Struct<'pin, T, U>: ::pin_project::__private::Unpin
     {
     }
     // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
     //
     // To ensure that users don't accidentally write a non-functional `UnsafeUnpin`
-    // impls, we emit one ourselves. If the user ends up writing a `UnsafeUnpin` impl,
-    // they'll get a "conflicting implementations of trait" error when coherence
-    // checks are run.
+    // impls, we emit one ourselves. If the user ends up writing an `UnsafeUnpin`
+    // impl, they'll get a "conflicting implementations of trait" error when
+    // coherence checks are run.
     unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> {}
 
     // Ensure that struct does not implement `Drop`.
@@ -126,15 +129,16 @@
     // the conflict with the second impl.
     trait StructMustNotImplDrop {}
     #[allow(clippy::drop_bounds)]
-    impl<T: ::pin_project::__reexport::ops::Drop> StructMustNotImplDrop for T {}
+    impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
     impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
     // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
     // write a non-functional `PinnedDrop` impls.
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
-        unsafe fn drop(self: ::pin_project::__reexport::pin::Pin<&mut Self>) {}
+        unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
 
-    // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+    // Ensure that it's impossible to use pin projections on a #[repr(packed)]
+    // struct.
     //
     // Taking a reference to a packed field is unsafe, and applying
     // #[deny(safe_packed_borrows)] makes sure that doing this without
diff --git a/examples/unsafe_unpin-expanded.rs b/examples/unsafe_unpin-expanded.rs
index 7d8ad8e..e55b740 100644
--- a/examples/unsafe_unpin-expanded.rs
+++ b/examples/unsafe_unpin-expanded.rs
@@ -29,57 +29,60 @@
 }
 
 #[doc(hidden)]
-#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::type_repetition_in_bounds)]
 pub(crate) struct __StructProjection<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin mut (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
     unpinned: &'pin mut (U),
 }
 #[doc(hidden)]
-#[allow(dead_code)] // This lint warns unused fields/variants.
+#[allow(dead_code)]
 #[allow(single_use_lifetimes)]
+#[allow(clippy::type_repetition_in_bounds)]
 pub(crate) struct __StructProjectionRef<'pin, T, U>
 where
     Struct<T, U>: 'pin,
 {
-    pinned: ::pin_project::__reexport::pin::Pin<&'pin (T)>,
+    pinned: ::pin_project::__private::Pin<&'pin (T)>,
     unpinned: &'pin (U),
 }
 
 #[doc(hidden)]
 #[allow(non_upper_case_globals)]
 #[allow(single_use_lifetimes)]
-const __SCOPE_Struct: () = {
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
     impl<T, U> Struct<T, U> {
         pub(crate) fn project<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin mut Self>,
+            self: ::pin_project::__private::Pin<&'pin mut Self>,
         ) -> __StructProjection<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_unchecked_mut();
                 __StructProjection {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
         }
         pub(crate) fn project_ref<'pin>(
-            self: ::pin_project::__reexport::pin::Pin<&'pin Self>,
+            self: ::pin_project::__private::Pin<&'pin Self>,
         ) -> __StructProjectionRef<'pin, T, U> {
             unsafe {
                 let Self { pinned, unpinned } = self.get_ref();
                 __StructProjectionRef {
-                    pinned: ::pin_project::__reexport::pin::Pin::new_unchecked(pinned),
+                    pinned: ::pin_project::__private::Pin::new_unchecked(pinned),
                     unpinned,
                 }
             }
         }
     }
 
-    impl<'pin, T, U> ::pin_project::__reexport::marker::Unpin for Struct<T, U> where
+    impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
         ::pin_project::__private::Wrapper<'pin, Self>: ::pin_project::UnsafeUnpin
     {
     }
@@ -89,13 +92,14 @@
     // See ./struct-default-expanded.rs for details.
     trait StructMustNotImplDrop {}
     #[allow(clippy::drop_bounds)]
-    impl<T: ::pin_project::__reexport::ops::Drop> StructMustNotImplDrop for T {}
+    impl<T: ::pin_project::__private::Drop> StructMustNotImplDrop for T {}
     impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
-        unsafe fn drop(self: ::pin_project::__reexport::pin::Pin<&mut Self>) {}
+        unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
 
-    // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+    // Ensure that it's impossible to use pin projections on a #[repr(packed)]
+    // struct.
     //
     // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
     // for details.
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 0000000..18c6d2a
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1,27 @@
+# Rustfmt configuration
+# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
+
+# This is required for bug-fixes, which technically can't be made to the stable
+# first version.
+# This is unstable (tracking issue: https://github.com/rust-lang/rustfmt/issues/3383).
+version = "Two"
+# This is unstable (tracking issue: https://github.com/rust-lang/rustfmt/issues/3391)
+error_on_line_overflow = true
+
+# Override the default formatting style.
+# See https://internals.rust-lang.org/t/running-rustfmt-on-rust-lang-rust-and-other-rust-lang-repositories/8732/81.
+use_small_heuristics = "Max"
+# See https://github.com/rust-dev-tools/fmt-rfcs/issues/149.
+# This is unstable (tracking issue: https://github.com/rust-lang/rustfmt/issues/3370)
+overflow_delimited_expr = true
+
+# Apply rustfmt to more places.
+# This is unstable (tracking issue: https://github.com/rust-lang/rustfmt/issues/3362).
+merge_imports = true
+# This is unstable (tracking issue: https://github.com/rust-lang/rustfmt/issues/3348).
+format_code_in_doc_comments = true
+
+# Set the default settings again to always apply the proper formatting without
+# being affected by the editor settings.
+edition = "2018"
+tab_spaces = 4
diff --git a/src/lib.rs b/src/lib.rs
index b1543e1..1c4d453 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,8 +1,9 @@
-//! A crate for safe and ergonomic pin-projection.
+//! A crate for safe and ergonomic [pin-projection].
 //!
-//! ## Examples
+//! # Examples
 //!
-//! [`pin_project`] attribute creates a projection type covering all the fields of struct or enum.
+//! [`#[pin_project]`][`pin_project`] attribute creates projection types
+//! covering all the fields of struct or enum.
 //!
 //! ```rust
 //! use pin_project::pin_project;
@@ -16,7 +17,7 @@
 //! }
 //!
 //! impl<T, U> Struct<T, U> {
-//!     fn foo(self: Pin<&mut Self>) {
+//!     fn method(self: Pin<&mut Self>) {
 //!         let this = self.project();
 //!         let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
 //!         let _: &mut U = this.unpinned; // Normal reference to the field
@@ -24,17 +25,18 @@
 //! }
 //! ```
 //!
-//! [Code like this will be generated](https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs)
+//! [*code like this will be generated*][struct-default-expanded]
 //!
-//! See [`pin_project`] attribute for more details.
-//!
-//! Also, there are examples and generated code of each feature in [examples](https://github.com/taiki-e/pin-project/blob/master/examples/README.md) directory.
+//! See [`#[pin_project]`][`pin_project`] attribute for more details, and
+//! see [examples] directory for more examples and generated code.
 //!
 //! [`pin_project`]: attr.pin_project.html
+//! [examples]: https://github.com/taiki-e/pin-project/blob/master/examples/README.md
+//! [pin-projection]: https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning
+//! [struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs
 
 #![no_std]
-#![recursion_limit = "256"]
-#![doc(html_root_url = "https://docs.rs/pin-project/0.4.17")]
+#![doc(html_root_url = "https://docs.rs/pin-project/0.4.22")]
 #![doc(test(
     no_crate_inject,
     attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code))
@@ -44,6 +46,8 @@
 // mem::take and #[non_exhaustive] requires Rust 1.40
 #![allow(clippy::mem_replace_with_default, clippy::manual_non_exhaustive)]
 #![allow(clippy::needless_doctest_main)]
+// https://github.com/rust-lang/rust-clippy/issues/5704
+#![allow(clippy::unnested_or_patterns)]
 
 // ANDROID: Use std to allow building as a dylib.
 extern crate std;
@@ -54,18 +58,21 @@
 #[doc(inline)]
 pub use pin_project_internal::pinned_drop;
 
+#[allow(deprecated)]
 #[doc(inline)]
 pub use pin_project_internal::project;
 
+#[allow(deprecated)]
 #[doc(inline)]
 pub use pin_project_internal::project_ref;
 
+#[allow(deprecated)]
 #[doc(inline)]
 pub use pin_project_internal::project_replace;
 
 /// A trait used for custom implementations of [`Unpin`].
 /// This trait is used in conjunction with the `UnsafeUnpin`
-/// argument to [`pin_project`]
+/// argument to [`#[pin_project]`][`pin_project`]
 ///
 /// The Rust [`Unpin`] trait is safe to implement - by itself,
 /// implementing it cannot lead to undefined behavior. Undefined
@@ -78,9 +85,9 @@
 ///
 /// However, things change if you want to provide a custom [`Unpin`] impl
 /// for your `#[pin_project]` type. As stated in [the Rust
-/// documentation](https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning),
-/// you must be sure to only implement [`Unpin`] when all of your `#[pin]` fields (i.e. structurally
-/// pinned fields) are also [`Unpin`].
+/// documentation][pin-projection], you must be sure to only implement [`Unpin`]
+/// when all of your `#[pin]` fields (i.e. structurally pinned fields) are also
+/// [`Unpin`].
 ///
 /// To help highlight this unsafety, the `UnsafeUnpin` trait is provided.
 /// Implementing this trait is logically equivalent to implementing [`Unpin`] -
@@ -92,15 +99,16 @@
 ///
 /// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not*
 /// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`].
-/// This is effectively the same thing as adding a [`PhantomPinned`] to your type
+/// This is effectively the same thing as adding a [`PhantomPinned`] to your
+/// type.
 ///
-/// Since this trait is `unsafe`, impls of it will be detected by the `unsafe_code` lint,
-/// and by tools like `cargo geiger`.
+/// Since this trait is `unsafe`, impls of it will be detected by the
+/// `unsafe_code` lint, and by tools like [`cargo geiger`][cargo-geiger].
 ///
-/// ## Examples
+/// # Examples
 ///
-/// An `UnsafeUnpin` impl which, in addition to requiring that structurally pinned
-/// fields be [`Unpin`], imposes an additional requirement:
+/// An `UnsafeUnpin` impl which, in addition to requiring that structurally
+/// pinned fields be [`Unpin`], imposes an additional requirement:
 ///
 /// ```rust
 /// use pin_project::{pin_project, UnsafeUnpin};
@@ -117,13 +125,23 @@
 ///
 /// [`PhantomPinned`]: core::marker::PhantomPinned
 /// [`pin_project`]: attr.pin_project.html
+/// [pin-projection]: https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning
+/// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger
 pub unsafe trait UnsafeUnpin {}
 
 // Not public API.
 #[doc(hidden)]
 pub mod __private {
+    #[doc(hidden)]
+    pub use core::{
+        marker::{PhantomData, PhantomPinned, Unpin},
+        mem::ManuallyDrop,
+        ops::Drop,
+        pin::Pin,
+        ptr,
+    };
+
     use super::UnsafeUnpin;
-    use core::{marker::PhantomData, mem::ManuallyDrop, pin::Pin, ptr};
 
     #[doc(hidden)]
     pub use pin_project_internal::__PinProjectInternalDerive;
@@ -153,6 +171,7 @@
     //
     // Supposed we have the following code:
     //
+    // ```rust
     // #[pin_project(UnsafeUnpin)]
     // struct MyStruct<T> {
     //     #[pin] field: T
@@ -160,37 +179,43 @@
     //
     // impl<T> Unpin for MyStruct<T> where MyStruct<T>: UnsafeUnpin {} // generated by pin-project-internal
     // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
+    // ```
     //
-    // We want this code to be rejected - the user is completely bypassing `UnsafeUnpin`,
-    // and providing an unsound Unpin impl in safe code!
+    // We want this code to be rejected - the user is completely bypassing
+    // `UnsafeUnpin`, and providing an unsound Unpin impl in safe code!
     //
     // Unfortunately, the Rust compiler will accept the above code.
     // Because MyStruct is declared in the same crate as the user-provided impl,
-    // the compiler will notice that 'MyStruct<T>: UnsafeUnpin' never holds.
+    // the compiler will notice that `MyStruct<T>: UnsafeUnpin` never holds.
     //
-    // The solution is to introduce the 'Wrapper' struct, which is defined
-    // in the 'pin-project' crate.
+    // The solution is to introduce the `Wrapper` struct, which is defined
+    // in the `pin-project` crate.
     //
     // We now have code that looks like this:
     //
+    // ```rust
     // impl<T> Unpin for MyStruct<T> where Wrapper<MyStruct<T>>: UnsafeUnpin {} // generated by pin-project-internal
     // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
+    // ```
     //
-    // We also have 'unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}' in the
-    // 'pin-project' crate.
+    // We also have `unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}`
+    // in the `pin-project` crate.
     //
-    // Now, our generated impl has a bound involving a type defined in another crate - Wrapper.
-    // This will cause rust to conservatively assume that 'Wrapper<MyStruct<T>>: UnsafeUnpin'
-    // holds, in the interest of preserving forwards compatibility (in case such an impl is added
-    // for Wrapper<T> in a new version of the crate).
+    // Now, our generated impl has a bound involving a type defined in another
+    // crate - Wrapper. This will cause rust to conservatively assume that
+    // `Wrapper<MyStruct<T>>: UnsafeUnpin` holds, in the interest of preserving
+    // forwards compatibility (in case such an impl is added for Wrapper<T> in
+    // a new version of the crate).
     //
-    // This will cause rust to reject any other Unpin impls for MyStruct<T>, since it will
-    // assume that our generated impl could potentially apply in any situation.
+    // This will cause rust to reject any other `Unpin` impls for MyStruct<T>,
+    // since it will assume that our generated impl could potentially apply in
+    // any situation.
     //
-    // This achieves the desired effect - when the user writes `#[pin_project(UnsafeUnpin)]`,
-    // the user must either provide no impl of `UnsafeUnpin` (which is equivalent
-    // to making the type never implement Unpin), or provide an impl of `UnsafeUnpin`.
-    // It is impossible for them to provide an impl of `Unpin`
+    // This achieves the desired effect - when the user writes
+    // `#[pin_project(UnsafeUnpin)]`, the user must either provide no impl of
+    // `UnsafeUnpin` (which is equivalent to making the type never implement
+    // Unpin), or provide an impl of `UnsafeUnpin`. It is impossible for them to
+    // provide an impl of `Unpin`
     #[doc(hidden)]
     pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T);
 
@@ -232,11 +257,3 @@
         }
     }
 }
-
-// Not public API.
-// See tests/overwriting_core_crate.rs for more.
-#[doc(hidden)]
-pub mod __reexport {
-    #[doc(hidden)]
-    pub use core::{marker, mem, ops, pin, ptr};
-}
diff --git a/tests/cfg.rs b/tests/cfg.rs
index 20b8472..4133517 100644
--- a/tests/cfg.rs
+++ b/tests/cfg.rs
@@ -21,7 +21,7 @@
 fn cfg() {
     // structs
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct SameName {
         #[cfg(target_os = "linux")]
         #[pin]
@@ -41,7 +41,7 @@
     #[cfg(not(target_os = "linux"))]
     let _x = SameName { inner: Other };
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct DifferentName {
         #[cfg(target_os = "linux")]
         #[pin]
@@ -61,7 +61,7 @@
     #[cfg(not(target_os = "linux"))]
     let _x = DifferentName { o: Other };
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct TupleStruct(
         #[cfg(target_os = "linux")]
         #[pin]
@@ -83,7 +83,7 @@
 
     // enums
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Variant {
         #[cfg(target_os = "linux")]
         Inner(#[pin] Linux),
@@ -110,7 +110,7 @@
     #[cfg(not(target_os = "linux"))]
     let _x = Variant::Other(Other);
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Field {
         SameName {
             #[cfg(target_os = "linux")]
@@ -167,7 +167,7 @@
 
 #[test]
 fn cfg_attr() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct SameCfg {
         #[cfg(target_os = "linux")]
         #[cfg_attr(target_os = "linux", pin)]
@@ -193,7 +193,7 @@
     #[cfg(not(target_os = "linux"))]
     let _: Pin<&mut Other> = x.inner;
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct DifferentCfg {
         #[cfg(target_os = "linux")]
         #[cfg_attr(target_os = "linux", pin)]
@@ -233,7 +233,7 @@
 #[test]
 fn cfg_attr_any_packed() {
     // Since `cfg(any())` can never be true, it is okay for this to pass.
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     #[cfg_attr(any(), repr(packed))]
     struct Struct {
         #[pin]
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
index 078abaa..e78b3dc 100644
--- a/tests/compiletest.rs
+++ b/tests/compiletest.rs
@@ -1,6 +1,6 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 
-#[ignore]
+#[rustversion::attr(not(nightly), ignore)]
 #[test]
 fn ui() {
     let t = trybuild::TestCases::new();
diff --git a/tests/forbid_unsafe.rs b/tests/forbid_unsafe.rs
deleted file mode 100644
index 4b2e248..0000000
--- a/tests/forbid_unsafe.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-#![forbid(unsafe_code)]
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-#![allow(dead_code)]
-
-// default #[pin_project], PinnedDrop, Replace, and !Unpin are completely safe.
-
-use pin_project::{pin_project, pinned_drop};
-use std::pin::Pin;
-
-#[pin_project]
-pub struct StructDefault<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project(PinnedDrop)]
-pub struct StructPinnedDrop<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pinned_drop]
-impl<T, U> PinnedDrop for StructPinnedDrop<T, U> {
-    fn drop(self: Pin<&mut Self>) {}
-}
-
-#[pin_project(Replace)]
-pub struct StructReplace<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-// UnsafeUnpin without UnsafeUnpin impl is also safe
-#[pin_project(UnsafeUnpin)]
-pub struct StructUnsafeUnpin<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project(!Unpin)]
-pub struct StructNotUnpin<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project]
-pub enum EnumDefault<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pin_project(PinnedDrop)]
-pub enum EnumPinnedDrop<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pinned_drop]
-impl<T, U> PinnedDrop for EnumPinnedDrop<T, U> {
-    fn drop(self: Pin<&mut Self>) {}
-}
-
-#[pin_project(Replace)]
-pub enum EnumReplace<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-// UnsafeUnpin without UnsafeUnpin impl is also safe
-#[pin_project(UnsafeUnpin)]
-pub enum EnumUnsafeUnpin<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pin_project(!Unpin)]
-pub enum EnumNotUnpin<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[test]
-fn test() {}
diff --git a/tests/include/basic-safe-part.rs b/tests/include/basic-safe-part.rs
new file mode 100644
index 0000000..fefc924
--- /dev/null
+++ b/tests/include/basic-safe-part.rs
@@ -0,0 +1,136 @@
+// default #[pin_project], PinnedDrop, project_replace, !Unpin, and UnsafeUnpin without UnsafeUnpin impl are completely safe.
+
+#[::pin_project::pin_project]
+#[derive(Debug)]
+pub struct DefaultStruct<T, U> {
+    #[pin]
+    pub pinned: T,
+    pub unpinned: U,
+}
+
+#[::pin_project::pin_project]
+#[derive(Debug)]
+pub struct DefaultTupleStruct<T, U>(#[pin] pub T, pub U);
+
+#[::pin_project::pin_project]
+#[derive(Debug)]
+pub enum DefaultEnum<T, U> {
+    Struct {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    },
+    Tuple(#[pin] T, U),
+    Unit,
+}
+
+#[::pin_project::pin_project(PinnedDrop)]
+#[derive(Debug)]
+pub struct PinnedDropStruct<T, U> {
+    #[pin]
+    pub pinned: T,
+    pub unpinned: U,
+}
+
+#[::pin_project::pinned_drop]
+impl<T, U> PinnedDrop for PinnedDropStruct<T, U> {
+    fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
+}
+
+#[::pin_project::pin_project(PinnedDrop)]
+#[derive(Debug)]
+pub struct PinnedDropTupleStruct<T, U>(#[pin] pub T, pub U);
+
+#[::pin_project::pinned_drop]
+impl<T, U> PinnedDrop for PinnedDropTupleStruct<T, U> {
+    fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
+}
+
+#[::pin_project::pin_project(PinnedDrop)]
+#[derive(Debug)]
+pub enum PinnedDropEnum<T, U> {
+    Struct {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    },
+    Tuple(#[pin] T, U),
+    Unit,
+}
+
+#[::pin_project::pinned_drop]
+impl<T, U> PinnedDrop for PinnedDropEnum<T, U> {
+    fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
+}
+
+#[::pin_project::pin_project(project_replace)]
+#[derive(Debug)]
+pub struct ReplaceStruct<T, U> {
+    #[pin]
+    pub pinned: T,
+    pub unpinned: U,
+}
+
+#[::pin_project::pin_project(project_replace)]
+#[derive(Debug)]
+pub struct ReplaceTupleStruct<T, U>(#[pin] pub T, pub U);
+
+#[::pin_project::pin_project(project_replace)]
+#[derive(Debug)]
+pub enum ReplaceEnum<T, U> {
+    Struct {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    },
+    Tuple(#[pin] T, U),
+    Unit,
+}
+
+#[::pin_project::pin_project(UnsafeUnpin)]
+#[derive(Debug)]
+pub struct UnsafeUnpinStruct<T, U> {
+    #[pin]
+    pub pinned: T,
+    pub unpinned: U,
+}
+
+#[::pin_project::pin_project(UnsafeUnpin)]
+#[derive(Debug)]
+pub struct UnsafeUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
+
+#[::pin_project::pin_project(UnsafeUnpin)]
+#[derive(Debug)]
+pub enum UnsafeUnpinEnum<T, U> {
+    Struct {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    },
+    Tuple(#[pin] T, U),
+    Unit,
+}
+
+#[::pin_project::pin_project(!Unpin)]
+#[derive(Debug)]
+pub struct NotUnpinStruct<T, U> {
+    #[pin]
+    pub pinned: T,
+    pub unpinned: U,
+}
+
+#[::pin_project::pin_project(!Unpin)]
+#[derive(Debug)]
+pub struct NotUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
+
+#[::pin_project::pin_project(!Unpin)]
+#[derive(Debug)]
+pub enum NotUnpinEnum<T, U> {
+    Struct {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    },
+    Tuple(#[pin] T, U),
+    Unit,
+}
diff --git a/tests/include/basic.rs b/tests/include/basic.rs
new file mode 100644
index 0000000..f862c63
--- /dev/null
+++ b/tests/include/basic.rs
@@ -0,0 +1,14 @@
+include!("basic-safe-part.rs");
+
+unsafe impl<T: ::pin_project::__private::Unpin, U: ::pin_project::__private::Unpin>
+    ::pin_project::UnsafeUnpin for UnsafeUnpinStruct<T, U>
+{
+}
+unsafe impl<T: ::pin_project::__private::Unpin, U: ::pin_project::__private::Unpin>
+    ::pin_project::UnsafeUnpin for UnsafeUnpinTupleStruct<T, U>
+{
+}
+unsafe impl<T: ::pin_project::__private::Unpin, U: ::pin_project::__private::Unpin>
+    ::pin_project::UnsafeUnpin for UnsafeUnpinEnum<T, U>
+{
+}
diff --git a/tests/lint.rs b/tests/lint.rs
new file mode 100644
index 0000000..25cb649
--- /dev/null
+++ b/tests/lint.rs
@@ -0,0 +1,135 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![warn(future_incompatible, nonstandard_style, rust_2018_compatibility, unused)]
+#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
+
+#[allow(unknown_lints)] // for old compilers
+#[warn(
+    absolute_paths_not_starting_with_crate,
+    anonymous_parameters,
+    box_pointers,
+    confusable_idents,
+    deprecated_in_future,
+    elided_lifetimes_in_paths,
+    explicit_outlives_requirements,
+    indirect_structural_match,
+    keyword_idents,
+    macro_use_extern_crate,
+    meta_variable_misuse,
+    missing_copy_implementations,
+    missing_crate_level_docs,
+    missing_debug_implementations,
+    missing_docs,
+    missing_doc_code_examples,
+    non_ascii_idents,
+    private_doc_tests,
+    single_use_lifetimes,
+    trivial_casts,
+    trivial_numeric_casts,
+    unaligned_references,
+    unreachable_pub,
+    unstable_features,
+    unused_extern_crates,
+    unused_import_braces,
+    unused_lifetimes,
+    unused_qualifications,
+    unused_results,
+    variant_size_differences
+)]
+// unused_crate_dependencies: unrelated
+// unsafe_code: checked in forbid_unsafe module
+// unsafe_block_in_unsafe_fn: unstable
+pub mod basic {
+    include!("include/basic.rs");
+}
+
+pub mod forbid_unsafe {
+    #![forbid(unsafe_code)]
+
+    include!("include/basic-safe-part.rs");
+}
+
+pub mod clippy {
+    use pin_project::pin_project;
+
+    #[pin_project(project_replace)]
+    pub struct MutMutStruct<'a, T, U> {
+        #[pin]
+        pub pinned: &'a mut T,
+        pub unpinned: &'a mut U,
+    }
+
+    #[pin_project(project_replace)]
+    pub struct MutMutTupleStruct<'a, T, U>(#[pin] &'a mut T, &'a mut U);
+
+    #[pin_project(project_replace)]
+    pub enum MutMutEnum<'a, T, U> {
+        Struct {
+            #[pin]
+            pinned: &'a mut T,
+            unpinned: &'a mut U,
+        },
+        Tuple(#[pin] &'a mut T, &'a mut U),
+        Unit,
+    }
+
+    #[pin_project(project_replace)]
+    pub struct TypeRepetitionInBoundsStruct<T, U>
+    where
+        Self: Sized,
+    {
+        #[pin]
+        pub pinned: T,
+        pub unpinned: U,
+    }
+
+    #[pin_project(project_replace)]
+    pub struct TypeRepetitionInBoundsTupleStruct<T, U>(#[pin] T, U)
+    where
+        Self: Sized;
+
+    #[pin_project(project_replace)]
+    pub enum TypeRepetitionInBoundsEnum<T, U>
+    where
+        Self: Sized,
+    {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Tuple(#[pin] T, U),
+        Unit,
+    }
+
+    #[pin_project(project_replace)]
+    pub struct UsedUnderscoreBindingStruct<T, U> {
+        #[pin]
+        pub _pinned: T,
+        pub _unpinned: U,
+    }
+
+    #[pin_project(project_replace)]
+    pub enum UsedUnderscoreBindingEnum<T, U> {
+        Struct {
+            #[pin]
+            _pinned: T,
+            _unpinned: U,
+        },
+    }
+}
+
+#[rustversion::attr(not(since(2020-06-12)), ignore)]
+#[test]
+fn check_lint_list() {
+    use std::{env, process::Command, str};
+
+    (|| -> Result<(), Box<dyn std::error::Error>> {
+        let current = include_str!("lint.txt");
+        let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
+        let output = Command::new(rustc).args(&["-W", "help"]).output()?;
+        let new = str::from_utf8(&output.stdout)?;
+        assert_eq!(current, new);
+        Ok(())
+    })()
+    .unwrap_or_else(|e| panic!("{}", e));
+}
diff --git a/tests/lint.txt b/tests/lint.txt
new file mode 100644
index 0000000..5110d4b
--- /dev/null
+++ b/tests/lint.txt
@@ -0,0 +1,139 @@
+
+Available lint options:
+    -W <foo>           Warn about <foo>
+    -A <foo>           Allow <foo>
+    -D <foo>           Deny <foo>
+    -F <foo>           Forbid <foo> (deny <foo> and all attempts to override)
+
+
+Lint checks provided by rustc:
+
+                                                       name  default  meaning
+                                                       ----  -------  -------
+                     absolute-paths-not-starting-with-crate  allow    fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name
+                                       anonymous-parameters  allow    detects anonymous parameters
+                                               box-pointers  allow    use of owned (Box type) heap memory
+                                          confusable-idents  allow    detects visually confusable pairs between identifiers
+                                       deprecated-in-future  allow    detects use of items that will be deprecated in a future version
+                                  elided-lifetimes-in-paths  allow    hidden lifetime parameters in types are deprecated
+                             explicit-outlives-requirements  allow    outlives requirements can be inferred
+                                  indirect-structural-match  allow    pattern with const indirectly referencing non-structural-match type
+                                             keyword-idents  allow    detects edition keywords being used as an identifier
+                                     macro-use-extern-crate  allow    the `#[macro_use]` attribute is now deprecated in favor of using macros via the module system
+                                       meta-variable-misuse  allow    possible meta-variable misuse at macro definition
+                               missing-copy-implementations  allow    detects potentially-forgotten implementations of `Copy`
+                                   missing-crate-level-docs  allow    detects crates with no crate-level documentation
+                              missing-debug-implementations  allow    detects missing implementations of Debug
+                                               missing-docs  allow    detects missing documentation for public members
+                                  missing-doc-code-examples  allow    detects publicly-exported items without code samples in their documentation
+                                           non-ascii-idents  allow    detects non-ASCII identifiers
+                                          private-doc-tests  allow    detects code samples in docs of private items not documented by rustdoc
+                                       single-use-lifetimes  allow    detects lifetime parameters that are only used once
+                                              trivial-casts  allow    detects trivial casts which could be removed
+                                      trivial-numeric-casts  allow    detects trivial casts of numeric types which could be removed
+                                       unaligned-references  allow    detects unaligned references to fields of packed structs
+                                            unreachable-pub  allow    `pub` items not reachable from crate root
+                                                unsafe-code  allow    usage of `unsafe` code
+                                     unsafe-op-in-unsafe-fn  allow    unsafe operations in unsafe functions without an explicit unsafe block are deprecated
+                                          unstable-features  allow    enabling unstable features (deprecated. do not use)
+                                  unused-crate-dependencies  allow    crate dependencies that are never used
+                                       unused-extern-crates  allow    extern crates that are never used
+                                       unused-import-braces  allow    unnecessary braces around an imported item
+                                           unused-lifetimes  allow    detects lifetime parameters that are never used
+                                      unused-qualifications  allow    detects unnecessarily qualified names
+                                             unused-results  allow    unused result of an expression in a statement
+                                   variant-size-differences  allow    detects enums with widely varying variant sizes
+                                            array-into-iter  warn     detects calling `into_iter` on arrays
+                                           asm-sub-register  warn     using only a subset of a register for inline asm inputs
+                                         bare-trait-objects  warn     suggest using `dyn Trait` for trait objects
+                                 bindings-with-variant-name  warn     detects pattern bindings with the same name as one of the matched variants
+                                       coherence-leak-check  warn     distinct impls distinguished only by the leak-check code
+                                                  dead-code  warn     detect unused, unexported items
+                                                 deprecated  warn     detects use of deprecated items
+                          ellipsis-inclusive-range-patterns  warn     `...` range patterns are deprecated
+                              exported-private-dependencies  warn     public interface leaks type from a private dependency
+                     illegal-floating-point-literal-pattern  warn     floating-point literals cannot be used in patterns
+                                            improper-ctypes  warn     proper use of libc types in foreign modules
+                                        incomplete-features  warn     incomplete features that may function improperly in some or all cases
+                                         inline-no-sanitize  warn     detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`
+                          intra-doc-link-resolution-failure  warn     failures in resolving intra-doc link targets
+                                invalid-codeblock-attribute  warn     codeblock attribute looks a lot like a known one
+                                              invalid-value  warn     an invalid value is being created (such as a NULL reference)
+                                   irrefutable-let-patterns  warn     detects irrefutable patterns in if-let and while-let statements
+                              late-bound-lifetime-arguments  warn     detects generic lifetime arguments in path segments with late bound lifetime parameters
+                        mutable-borrow-reservation-conflict  warn     reservation of a two-phased borrow conflicts with other shared borrows
+                                       non-camel-case-types  warn     types, variants, traits and type parameters should have camel case names
+                               non-shorthand-field-patterns  warn     using `Struct { x: x }` instead of `Struct { x }` in a pattern
+                                             non-snake-case  warn     variables, methods, functions, lifetime parameters and modules should have snake case names
+                                     non-upper-case-globals  warn     static constants should have uppercase identifiers
+                                    no-mangle-generic-items  warn     generic items must be mangled
+                                       overlapping-patterns  warn     detects overlapping patterns
+                                            path-statements  warn     path statements with no effect
+                                          private-in-public  warn     detect private items in public interfaces not caught by the old implementation
+                      proc-macro-derive-resolution-fallback  warn     detects proc macro derives using inaccessible names from parent modules
+                                       redundant-semicolons  warn     detects unnecessary trailing semicolons
+                                  renamed-and-removed-lints  warn     lints that have been renamed or removed
+                                        safe-packed-borrows  warn     safe borrows of fields of packed structs were erroneously allowed
+                                            stable-features  warn     stable features found in `#[feature]` directive
+                                             trivial-bounds  warn     these bounds don't depend on an type parameters
+                                          type-alias-bounds  warn     bounds in type aliases are not enforced
+                                   tyvar-behind-raw-pointer  warn     raw pointer to an inference variable
+                                        uncommon-codepoints  warn     detects uncommon Unicode codepoints in identifiers
+                                    unconditional-recursion  warn     functions that cannot return without calling themselves
+                                              unknown-lints  warn     unrecognized lint attribute
+                                      unnameable-test-items  warn     detects an item that cannot be named being marked as `#[test_case]`
+                                           unreachable-code  warn     detects unreachable code paths
+                                       unreachable-patterns  warn     detects unreachable patterns
+                                   unstable-name-collisions  warn     detects name collision with an existing but unstable method
+                                          unused-allocation  warn     detects unnecessary allocations that can be eliminated
+                                         unused-assignments  warn     detect assignments that will never be read
+                                          unused-attributes  warn     detects attributes that were not used by the compiler
+                                              unused-braces  warn     unnecessary braces around an expression
+                                         unused-comparisons  warn     comparisons made useless by limits of the types involved
+                                        unused-doc-comments  warn     detects doc comments that aren't used by rustdoc
+                                            unused-features  warn     unused features found in crate-level `#[feature]` directives
+                                             unused-imports  warn     imports that are never used
+                                              unused-labels  warn     detects labels that are never used
+                                              unused-macros  warn     detects macros that were not used
+                                            unused-must-use  warn     unused result of a type flagged as `#[must_use]`
+                                                 unused-mut  warn     detect mut variables which don't need to be mutable
+                                              unused-parens  warn     `if`, `match`, `while` and `return` do not need parentheses
+                                              unused-unsafe  warn     unnecessary use of an `unsafe` block
+                                           unused-variables  warn     detect variables which are not used in any way
+                                                   warnings  warn     mass-change the level for lints which produce warnings
+                                where-clauses-object-safety  warn     checks the object safety of where clauses
+                                                 while-true  warn     suggest using `loop { }` instead of `while true { }`
+                                 ambiguous-associated-items  deny     ambiguous associated items
+                                        arithmetic-overflow  deny     arithmetic operation overflows
+                                     conflicting-repr-hints  deny     conflicts between `#[repr(..)]` hints that were previously accepted and used in practice
+                                                  const-err  deny     constant evaluation detected erroneous expression
+                                 ill-formed-attribute-input  deny     ill-formed attribute inputs that were previously accepted and used in practice
+                                         incomplete-include  deny     trailing content in included file
+                                 invalid-type-param-default  deny     type parameter default erroneously allowed in invalid location
+    macro-expanded-macro-exports-accessed-by-absolute-paths  deny     macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths
+                                 missing-fragment-specifier  deny     detects missing fragment specifiers in unused `macro_rules!` patterns
+                                         mutable-transmutes  deny     mutating transmuted &mut T from &T may cause undefined behavior
+                                      no-mangle-const-items  deny     const items will not have their symbols exported
+                              order-dependent-trait-objects  deny     trait-object types were treated as different depending on marker-trait order
+                                       overflowing-literals  deny     literal out of range for its type
+                               patterns-in-fns-without-body  deny     patterns in functions without body were erroneously allowed
+                            pub-use-of-private-extern-crate  deny     detect public re-exports of private extern crates
+                                              soft-unstable  deny     a feature gate that doesn't break dependent crates
+                                        unconditional-panic  deny     operation will cause a panic at runtime
+                                        unknown-crate-types  deny     unknown crate type found in `#[crate_type]` directive
+
+
+Lint groups provided by rustc:
+
+                       name  sub-lints
+                       ----  ---------
+                   warnings  all lints that are set to issue warnings
+        future-incompatible  keyword-idents, anonymous-parameters, illegal-floating-point-literal-pattern, private-in-public, pub-use-of-private-extern-crate, invalid-type-param-default, safe-packed-borrows, patterns-in-fns-without-body, missing-fragment-specifier, late-bound-lifetime-arguments, order-dependent-trait-objects, coherence-leak-check, tyvar-behind-raw-pointer, absolute-paths-not-starting-with-crate, unstable-name-collisions, where-clauses-object-safety, proc-macro-derive-resolution-fallback, macro-expanded-macro-exports-accessed-by-absolute-paths, ill-formed-attribute-input, conflicting-repr-hints, ambiguous-associated-items, mutable-borrow-reservation-conflict, indirect-structural-match, soft-unstable, array-into-iter
+          nonstandard-style  non-camel-case-types, non-snake-case, non-upper-case-globals
+    rust-2018-compatibility  keyword-idents, anonymous-parameters, tyvar-behind-raw-pointer, absolute-paths-not-starting-with-crate
+           rust-2018-idioms  bare-trait-objects, unused-extern-crates, ellipsis-inclusive-range-patterns, elided-lifetimes-in-paths, explicit-outlives-requirements
+                    rustdoc  intra-doc-link-resolution-failure, invalid-codeblock-attribute, missing-doc-code-examples, private-doc-tests
+                     unused  unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, overlapping-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comments, unused-extern-crates, unused-features, unused-labels, unused-parens, unused-braces, redundant-semicolons
+
+
+Compiler plugins can provide additional lints and lint groups. To see a listing of these, re-run `rustc -W help` with a crate filename.
diff --git a/tests/lints.rs b/tests/lints.rs
deleted file mode 100644
index 4009f55..0000000
--- a/tests/lints.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-#![warn(unused, future_incompatible)]
-#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
-
-use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
-use std::pin::Pin;
-
-#[pin_project]
-pub struct StructDefault<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project(PinnedDrop)]
-pub struct StructPinnedDrop<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pinned_drop]
-impl<T, U> PinnedDrop for StructPinnedDrop<T, U> {
-    fn drop(self: Pin<&mut Self>) {}
-}
-
-#[pin_project(Replace)]
-pub struct StructReplace<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project(UnsafeUnpin)]
-pub struct StructUnsafeUnpin<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-unsafe impl<T: Unpin, U> UnsafeUnpin for StructUnsafeUnpin<T, U> {}
-
-#[pin_project(!Unpin)]
-pub struct StructNotUnpin<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project]
-pub struct StructMutMut<'a, T, U> {
-    #[pin]
-    pub pinned: &'a mut T,
-    pub unpinned: &'a mut U,
-}
-
-#[pin_project]
-pub enum EnumDefault<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pin_project(PinnedDrop)]
-pub enum EnumPinnedDrop<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pinned_drop]
-impl<T, U> PinnedDrop for EnumPinnedDrop<T, U> {
-    fn drop(self: Pin<&mut Self>) {}
-}
-
-#[pin_project(Replace)]
-pub enum EnumReplace<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pin_project(UnsafeUnpin)]
-pub enum EnumUnsafeUnpin<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-unsafe impl<T: Unpin, U> UnsafeUnpin for EnumUnsafeUnpin<T, U> {}
-
-#[pin_project(!Unpin)]
-pub enum EnumNotUnpin<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pin_project]
-pub enum EnumMutMut<'a, T, U> {
-    Struct {
-        #[pin]
-        pinned: &'a mut T,
-        unpinned: &'a mut U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[allow(clippy::missing_const_for_fn)]
-#[test]
-fn test() {}
diff --git a/tests/overwriting_core_crate.rs b/tests/overwriting_core_crate.rs
deleted file mode 100644
index 121104c..0000000
--- a/tests/overwriting_core_crate.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-
-// See https://github.com/rust-lang/pin-utils/pull/26#discussion_r344491597
-//
-// Note: If the proc-macro does not depend on its own items, it may be preferable not to
-//       support overwriting the name of core/std crate for compatibility with reexport.
-#[allow(unused_extern_crates)]
-extern crate pin_project as core;
-
-// Dummy module to check that the expansion refers to the crate.
-mod pin_project {}
-
-use ::pin_project::{pin_project, pinned_drop, UnsafeUnpin};
-use std::pin::Pin;
-
-#[pin_project]
-pub struct StructDefault<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project(PinnedDrop)]
-pub struct StructPinnedDrop<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pinned_drop]
-impl<T, U> PinnedDrop for StructPinnedDrop<T, U> {
-    fn drop(self: Pin<&mut Self>) {}
-}
-
-#[pin_project(Replace)]
-pub struct StructReplace<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project(UnsafeUnpin)]
-pub struct StructUnsafeUnpin<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-unsafe impl<T: Unpin, U> UnsafeUnpin for StructUnsafeUnpin<T, U> {}
-
-#[pin_project(!Unpin)]
-pub struct StructNotUnpin<T, U> {
-    #[pin]
-    pub pinned: T,
-    pub unpinned: U,
-}
-
-#[pin_project]
-pub enum EnumDefault<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pin_project(PinnedDrop)]
-pub enum EnumPinnedDrop<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pinned_drop]
-impl<T, U> PinnedDrop for EnumPinnedDrop<T, U> {
-    fn drop(self: Pin<&mut Self>) {}
-}
-
-#[pin_project(Replace)]
-pub enum EnumReplace<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[pin_project(UnsafeUnpin)]
-pub enum EnumUnsafeUnpin<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-unsafe impl<T: Unpin, U> UnsafeUnpin for EnumUnsafeUnpin<T, U> {}
-
-#[pin_project(!Unpin)]
-pub enum EnumNotUnpin<T, U> {
-    Struct {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    },
-    Tuple(#[pin] T, U),
-}
-
-#[test]
-fn test() {}
diff --git a/tests/pin_project.rs b/tests/pin_project.rs
index 72bcd15..766887f 100644
--- a/tests/pin_project.rs
+++ b/tests/pin_project.rs
@@ -1,16 +1,15 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 #![allow(dead_code)]
 
-use core::{
+use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
+use std::{
     marker::{PhantomData, PhantomPinned},
     pin::Pin,
 };
-use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
 
 #[test]
 fn projection() {
     #[pin_project(
-        Replace,
         project = StructProj,
         project_ref = StructProjRef,
         project_replace = StructProjOwn,
@@ -53,7 +52,7 @@
     assert_eq!(s.field1, 3);
     assert_eq!(s.field2, 4);
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct TupleStruct<T, U>(#[pin] T, U);
 
     let mut s = TupleStruct(1, 2);
@@ -65,7 +64,7 @@
     let y: &mut i32 = s.1;
     assert_eq!(*y, 2);
 
-    #[pin_project(Replace, project = EnumProj)]
+    #[pin_project(project_replace, project = EnumProj)]
     #[derive(Eq, PartialEq, Debug)]
     enum Enum<A, B, C, D> {
         Variant1(#[pin] A, B),
@@ -127,7 +126,7 @@
 
 #[test]
 fn enum_project_set() {
-    #[pin_project(Replace, project = EnumProj)]
+    #[pin_project(project_replace, project = EnumProj)]
     #[derive(Eq, PartialEq, Debug)]
     enum Enum {
         Variant1(#[pin] u8),
@@ -175,7 +174,7 @@
 
 #[test]
 fn where_clause_and_associated_type_field() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct1<I>
     where
         I: Iterator,
@@ -185,7 +184,7 @@
         field2: I::Item,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct2<I, J>
     where
         I: Iterator<Item = J>,
@@ -195,7 +194,7 @@
         field2: J,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct3<T>
     where
         T: 'static,
@@ -207,12 +206,12 @@
 
     impl<T> Static for Struct3<T> {}
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct TupleStruct<I>(#[pin] I, I::Item)
     where
         I: Iterator;
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum<I>
     where
         I: Iterator,
@@ -224,7 +223,7 @@
 
 #[test]
 fn derive_copy() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     #[derive(Clone, Copy)]
     struct Struct<T> {
         val: T,
@@ -239,7 +238,7 @@
 fn move_out() {
     struct NotCopy;
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct {
         val: NotCopy,
     }
@@ -247,7 +246,7 @@
     let x = Struct { val: NotCopy };
     let _val: NotCopy = x.val;
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum {
         Variant(NotCopy),
     }
@@ -261,39 +260,39 @@
 
 #[test]
 fn trait_bounds_on_type_generics() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct1<'a, T: ?Sized> {
         field: &'a mut T,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct2<'a, T: ::core::fmt::Debug> {
         field: &'a mut T,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct3<'a, T: core::fmt::Debug> {
         field: &'a mut T,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {
         field: &'a mut T,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {
         field: &'a mut T,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {
         field: &'a mut T,
     }
 
     let _: Struct6<'_> = Struct6 { field: &mut [0u8; 16] };
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct7<T: 'static> {
         field: T,
     }
@@ -302,16 +301,16 @@
 
     impl<T> Static for Struct7<T> {}
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct8<'a, 'b: 'a> {
         field1: &'a u8,
         field2: &'b u8,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct TupleStruct<'a, T: ?Sized>(&'a mut T);
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum<'a, T: ?Sized> {
         Variant(&'a mut T),
     }
@@ -319,13 +318,13 @@
 
 #[test]
 fn overlapping_lifetime_names() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct1<'pin, T> {
         #[pin]
         field: &'pin mut T,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Struct2<'pin, 'pin_, 'pin__> {
         #[pin]
         field: &'pin &'pin_ &'pin__ (),
@@ -334,7 +333,7 @@
     pub trait A<'a> {}
 
     #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct HRTB<'pin___, T>
     where
         for<'pin> &'pin T: Unpin,
@@ -349,39 +348,39 @@
 #[test]
 fn combine() {
     #[pin_project(PinnedDrop, UnsafeUnpin)]
-    pub struct Struct1<T> {
+    pub struct PinnedDropWithUnsafeUnpin<T> {
         #[pin]
         field: T,
     }
 
     #[pinned_drop]
-    impl<T> PinnedDrop for Struct1<T> {
+    impl<T> PinnedDrop for PinnedDropWithUnsafeUnpin<T> {
         fn drop(self: Pin<&mut Self>) {}
     }
 
-    unsafe impl<T: Unpin> UnsafeUnpin for Struct1<T> {}
-
-    #[pin_project(UnsafeUnpin, Replace)]
-    pub struct Struct2<T> {
-        #[pin]
-        field: T,
-    }
-
-    unsafe impl<T: Unpin> UnsafeUnpin for Struct2<T> {}
+    unsafe impl<T: Unpin> UnsafeUnpin for PinnedDropWithUnsafeUnpin<T> {}
 
     #[pin_project(PinnedDrop, !Unpin)]
-    pub struct Struct3<T> {
+    pub struct PinnedDropWithNotUnpin<T> {
         #[pin]
         field: T,
     }
 
     #[pinned_drop]
-    impl<T> PinnedDrop for Struct3<T> {
+    impl<T> PinnedDrop for PinnedDropWithNotUnpin<T> {
         fn drop(self: Pin<&mut Self>) {}
     }
 
-    #[pin_project(!Unpin, Replace)]
-    pub struct Struct4<T> {
+    #[pin_project(UnsafeUnpin, project_replace)]
+    pub struct UnsafeUnpinWithReplace<T> {
+        #[pin]
+        field: T,
+    }
+
+    unsafe impl<T: Unpin> UnsafeUnpin for UnsafeUnpinWithReplace<T> {}
+
+    #[pin_project(!Unpin, project_replace)]
+    pub struct NotUnpinWithReplace<T> {
         #[pin]
         field: T,
     }
@@ -389,7 +388,7 @@
 
 #[test]
 fn private_type_in_public_type() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct PublicStruct<T> {
         #[pin]
         inner: PrivateStruct<T>,
@@ -400,21 +399,21 @@
 
 #[test]
 fn lifetime_project() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct1<T, U> {
         #[pin]
         pinned: T,
         unpinned: U,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct2<'a, T, U> {
         #[pin]
         pinned: &'a mut T,
         unpinned: U,
     }
 
-    #[pin_project(Replace, project = EnumProj, project_ref = EnumProjRef)]
+    #[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
     enum Enum<T, U> {
         Variant {
             #[pin]
@@ -458,21 +457,21 @@
 #[rustversion::since(1.36)] // https://github.com/rust-lang/rust/pull/61207
 #[test]
 fn lifetime_project_elided() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct1<T, U> {
         #[pin]
         pinned: T,
         unpinned: U,
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct2<'a, T, U> {
         #[pin]
         pinned: &'a mut T,
         unpinned: U,
     }
 
-    #[pin_project(Replace, project = EnumProj, project_ref = EnumProjRef)]
+    #[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
     enum Enum<T, U> {
         Variant {
             #[pin]
@@ -516,7 +515,7 @@
 mod visibility {
     use pin_project::pin_project;
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub(crate) struct A {
         pub b: u8,
     }
@@ -534,7 +533,7 @@
 
 #[test]
 fn trivial_bounds() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct NoGenerics {
         #[pin]
         field: PhantomPinned,
@@ -709,34 +708,102 @@
 }
 
 #[test]
-fn self_in_where_clause() {
-    pub trait Trait1 {}
-
-    #[pin_project(Replace)]
-    pub struct Struct1<T>
-    where
-        Self: Trait1,
-    {
-        x: T,
+fn parse_self() {
+    macro_rules! mac {
+        ($($tt:tt)*) => {
+            $($tt)*
+        };
     }
 
-    impl<T> Trait1 for Struct1<T> {}
-
-    pub trait Trait2 {
+    pub trait Trait {
         type Assoc;
     }
 
-    #[pin_project(Replace)]
-    pub struct Struct2<T>
+    #[pin_project(project_replace)]
+    pub struct Generics<T: Trait<Assoc = Self>>
     where
-        Self: Trait2<Assoc = Struct1<T>>,
-        <Self as Trait2>::Assoc: Trait1,
+        Self: Trait<Assoc = Self>,
+        <Self as Trait>::Assoc: Sized,
+        mac!(Self): Trait<Assoc = mac!(Self)>,
     {
-        x: T,
+        _f: T,
     }
 
-    impl<T> Trait2 for Struct2<T> {
-        type Assoc = Struct1<T>;
+    impl<T: Trait<Assoc = Self>> Trait for Generics<T> {
+        type Assoc = Self;
+    }
+
+    #[pin_project(project_replace)]
+    pub struct Struct {
+        _f1: Box<Self>,
+        _f2: Box<<Self as Trait>::Assoc>,
+        _f3: Box<mac!(Self)>,
+        _f4: [(); Self::ASSOC],
+        _f5: [(); Self::assoc()],
+        _f6: [(); mac!(Self::assoc())],
+    }
+
+    impl Struct {
+        const ASSOC: usize = 1;
+        const fn assoc() -> usize {
+            0
+        }
+    }
+
+    impl Trait for Struct {
+        type Assoc = Self;
+    }
+
+    #[pin_project(project_replace)]
+    struct Tuple(
+        Box<Self>,
+        Box<<Self as Trait>::Assoc>,
+        Box<mac!(Self)>,
+        [(); Self::ASSOC],
+        [(); Self::assoc()],
+        [(); mac!(Self::assoc())],
+    );
+
+    impl Tuple {
+        const ASSOC: usize = 1;
+        const fn assoc() -> usize {
+            0
+        }
+    }
+
+    impl Trait for Tuple {
+        type Assoc = Self;
+    }
+
+    #[pin_project(project_replace)]
+    enum Enum {
+        Struct {
+            _f1: Box<Self>,
+            _f2: Box<<Self as Trait>::Assoc>,
+            _f3: Box<mac!(Self)>,
+            _f4: [(); Self::ASSOC],
+            _f5: [(); Self::assoc()],
+            _f6: [(); mac!(Self::assoc())],
+        },
+        Tuple(
+            Box<Self>,
+            Box<<Self as Trait>::Assoc>,
+            Box<mac!(Self)>,
+            [(); Self::ASSOC],
+            [(); Self::assoc()],
+            [(); mac!(Self::assoc())],
+        ),
+    }
+
+    impl Enum {
+        const ASSOC: usize = 1;
+        const fn assoc() -> usize {
+            0
+        }
+    }
+
+    impl Trait for Enum {
+        type Assoc = Self;
     }
 }
 
@@ -752,7 +819,7 @@
         type Y = Option<T>;
     }
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Foo<A, B> {
         _x: <Example<A> as Bar<B>>::Y,
     }
@@ -760,11 +827,12 @@
 
 // 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() {
     use std::panic;
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct S<T, U> {
         #[pin]
         pinned: T,
@@ -786,7 +854,8 @@
         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.
+        // Previous `x.pinned` was dropped and panicked when `project_replace` is
+        // called, so this is unreachable.
         unreachable!();
     }));
     assert!(res.is_err());
@@ -801,7 +870,8 @@
         {
             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,
+            // `_y` (previous `x.unpinned`) live to the end of this scope, so
+            // this is not unreachable.
             // unreachable!();
         }
         unreachable!();
diff --git a/tests/pinned_drop.rs b/tests/pinned_drop.rs
index b0677e2..e257758 100644
--- a/tests/pinned_drop.rs
+++ b/tests/pinned_drop.rs
@@ -1,5 +1,4 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
-#![allow(dead_code)]
 
 use pin_project::{pin_project, pinned_drop};
 use std::pin::Pin;
@@ -26,66 +25,61 @@
 }
 
 #[test]
-fn mut_self_argument() {
+fn self_argument_in_macro() {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
     #[pin_project(PinnedDrop)]
     struct Struct {
-        data: usize,
-    }
-
-    #[pinned_drop]
-    impl PinnedDrop for Struct {
-        fn drop(mut self: Pin<&mut Self>) {
-            let _: &mut _ = &mut self.data;
-        }
-    }
-}
-
-#[test]
-fn self_in_vec() {
-    #[pin_project(PinnedDrop)]
-    struct Struct {
-        data: usize,
+        x: (),
     }
 
     #[pinned_drop]
     impl PinnedDrop for Struct {
         fn drop(self: Pin<&mut Self>) {
-            let _: Vec<_> = vec![self.data];
+            let _: Vec<_> = vec![self.x];
         }
     }
 }
 
 #[test]
 fn self_in_macro_containing_fn() {
-    #[pin_project(PinnedDrop)]
-    pub struct Struct {
-        data: usize,
-    }
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
 
-    macro_rules! emit {
+    macro_rules! mac {
         ($($tt:tt)*) => {
             $($tt)*
         };
     }
 
+    #[pin_project(PinnedDrop)]
+    pub struct Struct {
+        _x: (),
+    }
+
     #[pinned_drop]
     impl PinnedDrop for Struct {
         fn drop(self: Pin<&mut Self>) {
-            let _ = emit!({
+            let _ = mac!({
                 impl Struct {
-                    pub fn f(self) {}
+                    pub fn _f(self) -> Self {
+                        self
+                    }
                 }
             });
-            let _ = self.data;
         }
     }
 }
 
 #[test]
 fn self_call() {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
     #[pin_project(PinnedDrop)]
-    pub struct Struct {
-        data: usize,
+    pub struct Struct<T> {
+        _x: T,
     }
 
     trait Trait {
@@ -96,10 +90,10 @@
         fn assoc_fn(_this: Pin<&mut Self>) {}
     }
 
-    impl Trait for Struct {}
+    impl<T> Trait for Struct<T> {}
 
     #[pinned_drop]
-    impl PinnedDrop for Struct {
+    impl<T> PinnedDrop for Struct<T> {
         fn drop(mut self: Pin<&mut Self>) {
             self.self_ref();
             self.as_ref().self_pin_ref();
@@ -112,53 +106,13 @@
 }
 
 #[test]
-fn self_expr() {
+fn self_struct() {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
     #[pin_project(PinnedDrop)]
     pub struct Struct {
-        x: usize,
-    }
-
-    #[pinned_drop]
-    impl PinnedDrop for Struct {
-        fn drop(mut self: Pin<&mut Self>) {
-            let _: Self = Self { x: 0 };
-        }
-    }
-
-    #[pin_project(PinnedDrop)]
-    pub struct TupleStruct(usize);
-
-    #[pinned_drop]
-    impl PinnedDrop for TupleStruct {
-        fn drop(mut self: Pin<&mut Self>) {
-            let _: Self = Self(0);
-        }
-    }
-}
-
-#[rustversion::since(1.37)]
-#[test]
-fn self_expr_enum() {
-    #[pin_project(PinnedDrop)]
-    pub enum Enum {
-        StructVariant { x: usize },
-        TupleVariant(usize),
-    }
-
-    #[pinned_drop]
-    impl PinnedDrop for Enum {
-        fn drop(mut self: Pin<&mut Self>) {
-            let _: Self = Self::StructVariant { x: 0 };
-            let _: Self = Self::TupleVariant(0);
-        }
-    }
-}
-
-#[test]
-fn self_pat() {
-    #[pin_project(PinnedDrop)]
-    pub struct Struct {
-        x: usize,
+        pub x: (),
     }
 
     #[pinned_drop]
@@ -166,6 +120,10 @@
         #[allow(irrefutable_let_patterns)]
         #[allow(clippy::match_single_binding)]
         fn drop(mut self: Pin<&mut Self>) {
+            // expr
+            let _: Self = Self { x: () };
+
+            // pat
             match *self {
                 Self { x: _ } => {}
             }
@@ -175,12 +133,16 @@
     }
 
     #[pin_project(PinnedDrop)]
-    pub struct TupleStruct(usize);
+    pub struct TupleStruct(());
 
     #[pinned_drop]
     impl PinnedDrop for TupleStruct {
         #[allow(irrefutable_let_patterns)]
         fn drop(mut self: Pin<&mut Self>) {
+            // expr
+            let _: Self = Self(());
+
+            // pat
             match *self {
                 Self(_) => {}
             }
@@ -190,24 +152,32 @@
     }
 }
 
-#[rustversion::since(1.37)]
+#[rustversion::since(1.37)] // type_alias_enum_variants requires Rust 1.37
 #[test]
-fn self_pat_enum() {
+fn self_enum() {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
     #[pin_project(PinnedDrop)]
     pub enum Enum {
-        StructVariant { x: usize },
-        TupleVariant(usize),
+        Struct { x: () },
+        Tuple(()),
     }
 
     #[pinned_drop]
     impl PinnedDrop for Enum {
         fn drop(mut self: Pin<&mut Self>) {
+            // expr
+            let _: Self = Self::Struct { x: () };
+            let _: Self = Self::Tuple(());
+
+            // pat
             match *self {
-                Self::StructVariant { x: _ } => {}
-                Self::TupleVariant(_) => {}
+                Self::Struct { x: _ } => {}
+                Self::Tuple(_) => {}
             }
-            if let Self::StructVariant { x: _ } = *self {}
-            if let Self::TupleVariant(_) = *self {}
+            if let Self::Struct { x: _ } = *self {}
+            if let Self::Tuple(_) = *self {}
         }
     }
 }
@@ -216,20 +186,108 @@
 #[rustversion::since(1.40)] // https://github.com/rust-lang/rust/pull/64690
 #[test]
 fn self_in_macro_def() {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
     #[pin_project(PinnedDrop)]
     pub struct Struct {
-        x: usize,
+        _x: (),
     }
 
     #[pinned_drop]
     impl PinnedDrop for Struct {
         fn drop(self: Pin<&mut Self>) {
-            macro_rules! t {
+            macro_rules! mac {
                 () => {{
                     let _ = self;
                 }};
             }
-            t!();
+            mac!();
         }
     }
 }
+
+#[test]
+fn self_inside_macro() {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
+    macro_rules! mac {
+        ($($tt:tt)*) => {
+            $($tt)*
+        };
+    }
+
+    #[pin_project(PinnedDrop)]
+    pub struct Struct<T: Send>
+    where
+        mac!(Self): Send,
+    {
+        _x: T,
+    }
+
+    impl<T: Send> Struct<T> {
+        const ASSOCIATED1: &'static str = "1";
+        fn associated1() {}
+    }
+
+    trait Trait {
+        type Associated2;
+        const ASSOCIATED2: &'static str;
+        fn associated2();
+    }
+
+    impl<T: Send> Trait for Struct<T> {
+        type Associated2 = ();
+        const ASSOCIATED2: &'static str = "2";
+        fn associated2() {}
+    }
+
+    #[pinned_drop]
+    impl<T: Send> PinnedDrop for Struct<T>
+    where
+        mac!(Self): Send,
+    {
+        #[allow(path_statements)]
+        #[allow(clippy::no_effect)]
+        fn drop(self: Pin<&mut Self>) {
+            // inherent items
+            mac!(Self::ASSOCIATED1;);
+            mac!(<Self>::ASSOCIATED1;);
+            mac!(Self::associated1(););
+            mac!(<Self>::associated1(););
+
+            // trait items
+            mac!(let _: <Self as Trait>::Associated2;);
+            mac!(Self::ASSOCIATED2;);
+            mac!(<Self>::ASSOCIATED2;);
+            mac!(<Self as Trait>::ASSOCIATED2;);
+            mac!(Self::associated2(););
+            mac!(<Self>::associated2(););
+            mac!(<Self as Trait>::associated2(););
+        }
+    }
+}
+
+#[test]
+fn inside_macro() {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
+    #[pin_project(PinnedDrop)]
+    struct Struct(());
+
+    macro_rules! mac {
+        ($expr:expr) => {
+            #[pinned_drop]
+            impl PinnedDrop for Struct {
+                #[allow(clippy::no_effect)]
+                fn drop(self: Pin<&mut Self>) {
+                    $expr;
+                }
+            }
+        };
+    }
+
+    mac!(1);
+}
diff --git a/tests/project.rs b/tests/project.rs
index a0f8b07..78a9261 100644
--- a/tests/project.rs
+++ b/tests/project.rs
@@ -1,5 +1,6 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 #![allow(dead_code)]
+#![allow(deprecated)]
 
 // Ceurrently, `#[attr] if true {}` doesn't even *parse* on MSRV,
 // which means that it will error even behind a `#[rustversion::since(..)]`
@@ -160,8 +161,8 @@
 
 mod project_use_1 {
     use crate::A;
-    use core::pin::Pin;
     use pin_project::project;
+    use std::pin::Pin;
 
     #[project]
     use crate::A;
@@ -242,7 +243,7 @@
 #[project]
 #[test]
 fn combine() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum<A> {
         V1(#[pin] A),
         V2,
@@ -272,7 +273,7 @@
 #[project_replace]
 #[test]
 fn combine_compat() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum<A> {
         V1(#[pin] A),
         V2,
diff --git a/tests/project_if_attr.rs.in b/tests/project_if_attr.rs.in
index a8ceeac..7bc236d 100644
--- a/tests/project_if_attr.rs.in
+++ b/tests/project_if_attr.rs.in
@@ -6,8 +6,9 @@
         Variant1(#[pin] A),
         Variant2(u8),
         Variant3 {
-            #[pin] field: B
-        }
+            #[pin]
+            field: B,
+        },
     }
 
     let mut x: Foo<bool, f32> = Foo::Variant1(true);
diff --git a/tests/project_ref.rs b/tests/project_ref.rs
index e38ef83..0e8ebd9 100644
--- a/tests/project_ref.rs
+++ b/tests/project_ref.rs
@@ -1,5 +1,6 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 #![allow(dead_code)]
+#![allow(deprecated)]
 
 use pin_project::{pin_project, project_ref};
 use std::pin::Pin;
@@ -149,7 +150,7 @@
 #[project_ref]
 #[test]
 fn combine() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum<A> {
         V1(#[pin] A),
         V2,
diff --git a/tests/project_replace.rs b/tests/project_replace.rs
index 9c8a5ab..a97e3af 100644
--- a/tests/project_replace.rs
+++ b/tests/project_replace.rs
@@ -1,5 +1,6 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 #![allow(dead_code)]
+#![allow(deprecated)]
 
 use pin_project::{pin_project, project_replace};
 use std::{marker::PhantomData, pin::Pin};
@@ -7,7 +8,7 @@
 #[project_replace] // Nightly does not need a dummy attribute to the function.
 #[test]
 fn project_replace_stmt_expr() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct Struct<T, U> {
         #[pin]
         field1: T,
@@ -27,7 +28,7 @@
 
     // tuple struct
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct TupleStruct<T, U>(#[pin] T, U);
 
     let mut s = TupleStruct(1, 2);
@@ -39,7 +40,7 @@
     let y: i32 = y;
     assert_eq!(y, 2);
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum<A, B, C, D> {
         Variant1(#[pin] A, B),
         Variant2 {
@@ -73,7 +74,7 @@
 #[project_replace]
 #[test]
 fn combine() {
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     enum Enum<A> {
         V1(#[pin] A),
         V2,
diff --git a/tests/repr_packed.rs b/tests/repr_packed.rs
index ca56959..73fc45c 100644
--- a/tests/repr_packed.rs
+++ b/tests/repr_packed.rs
@@ -1,5 +1,4 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
-#![allow(dead_code)]
 #![deny(safe_packed_borrows)]
 
 use std::cell::Cell;
diff --git a/tests/ui/cfg/cfg_attr-unpin.stderr b/tests/ui/cfg/cfg_attr-unpin.stderr
index ce31c24..45789ff 100644
--- a/tests/ui/cfg/cfg_attr-unpin.stderr
+++ b/tests/ui/cfg/cfg_attr-unpin.stderr
@@ -16,7 +16,7 @@
    |                ----- required by this bound in `is_unpin`
 ...
 20 |     is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__SCOPE_Bar::__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `__SCOPE_Bar::__Bar<'_, std::marker::PhantomPinned>`
+   = note: required because it appears within the type `_::__Bar<'_, std::marker::PhantomPinned>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<std::marker::PhantomPinned>`
diff --git a/tests/ui/cfg/proper_unpin.stderr b/tests/ui/cfg/proper_unpin.stderr
index 407d900..f1fff34 100644
--- a/tests/ui/cfg/proper_unpin.stderr
+++ b/tests/ui/cfg/proper_unpin.stderr
@@ -5,7 +5,7 @@
    |                ----- required by this bound in `is_unpin`
 ...
 27 |     is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__SCOPE_Bar::__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `__SCOPE_Bar::__Bar<'_, std::marker::PhantomPinned>`
+   = note: required because it appears within the type `_::__Bar<'_, std::marker::PhantomPinned>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<std::marker::PhantomPinned>`
diff --git a/tests/ui/not_unpin/conflict-unpin.stderr b/tests/ui/not_unpin/conflict-unpin.stderr
index 7407bdf..e90a574 100644
--- a/tests/ui/not_unpin/conflict-unpin.stderr
+++ b/tests/ui/not_unpin/conflict-unpin.stderr
@@ -1,26 +1,26 @@
 error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_, _>`:
-  --> $DIR/conflict-unpin.rs:3:16
+  --> $DIR/conflict-unpin.rs:3:15
    |
 3  | #[pin_project(!Unpin)] //~ ERROR E0119
-   |                ^^^^^ conflicting implementation for `Foo<_, _>`
+   |               ^^^^^^ conflicting implementation for `Foo<_, _>`
 ...
 10 | impl<T, U> Unpin for Foo<T, U> where T: Unpin {}
    | --------------------------------------------- first implementation here
 
 error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Bar<_, _>`:
-  --> $DIR/conflict-unpin.rs:12:16
+  --> $DIR/conflict-unpin.rs:12:15
    |
 12 | #[pin_project(!Unpin)] //~ ERROR E0119
-   |                ^^^^^ conflicting implementation for `Bar<_, _>`
+   |               ^^^^^^ conflicting implementation for `Bar<_, _>`
 ...
 19 | impl<T, U> Unpin for Bar<T, U> {}
    | ------------------------------ first implementation here
 
 error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Baz<_, _>`:
-  --> $DIR/conflict-unpin.rs:21:16
+  --> $DIR/conflict-unpin.rs:21:15
    |
 21 | #[pin_project(!Unpin)] //~ ERROR E0119
-   |                ^^^^^ conflicting implementation for `Baz<_, _>`
+   |               ^^^^^^ conflicting implementation for `Baz<_, _>`
 ...
 28 | impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {}
    | -------------------------------------------- first implementation here
diff --git a/tests/ui/pin_project/add-pin-attr-to-struct.rs b/tests/ui/pin_project/add-attr-to-struct.rs
similarity index 100%
rename from tests/ui/pin_project/add-pin-attr-to-struct.rs
rename to tests/ui/pin_project/add-attr-to-struct.rs
diff --git a/tests/ui/pin_project/add-pin-attr-to-struct.stderr b/tests/ui/pin_project/add-attr-to-struct.stderr
similarity index 87%
rename from tests/ui/pin_project/add-pin-attr-to-struct.stderr
rename to tests/ui/pin_project/add-attr-to-struct.stderr
index c2adaea..27656d6 100644
--- a/tests/ui/pin_project/add-pin-attr-to-struct.stderr
+++ b/tests/ui/pin_project/add-attr-to-struct.stderr
@@ -1,5 +1,5 @@
 error: duplicate #[pin] attribute
- --> $DIR/add-pin-attr-to-struct.rs:6:1
+ --> $DIR/add-attr-to-struct.rs:6:1
   |
 6 | #[add_pin_attr(struct)] //~ ERROR duplicate #[pin] attribute
   | ^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: #[pin] attribute may only be used on fields of structs or variants
-  --> $DIR/add-pin-attr-to-struct.rs:12:1
+  --> $DIR/add-attr-to-struct.rs:12:1
    |
 12 | #[add_pin_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
    | ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/pin_project/add-pinned-field.stderr b/tests/ui/pin_project/add-pinned-field.stderr
index db07a74..d6a1dcd 100644
--- a/tests/ui/pin_project/add-pinned-field.stderr
+++ b/tests/ui/pin_project/add-pinned-field.stderr
@@ -5,9 +5,9 @@
    |                ----- required by this bound in `is_unpin`
 ...
 21 |     is_unpin::<Foo>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^ within `__SCOPE_Foo::__Foo<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^ within `_::__Foo<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `__SCOPE_Foo::__Foo<'_>`
+   = note: required because it appears within the type `_::__Foo<'_>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo`
 
 error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
@@ -17,7 +17,7 @@
    |                ----- required by this bound in `is_unpin`
 ...
 22 |     is_unpin::<Bar>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^ within `__SCOPE_Bar::__Bar<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^ within `_::__Bar<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `__SCOPE_Bar::__Bar<'_>`
+   = note: required because it appears within the type `_::__Bar<'_>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar`
diff --git a/tests/ui/pin_project/conflict-drop.stderr b/tests/ui/pin_project/conflict-drop.stderr
index f97d060..d5ca7b3 100644
--- a/tests/ui/pin_project/conflict-drop.stderr
+++ b/tests/ui/pin_project/conflict-drop.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `__SCOPE_Foo::FooMustNotImplDrop` for type `Foo<_, _>`:
+error[E0119]: conflicting implementations of trait `_::FooMustNotImplDrop` for type `Foo<_, _>`:
  --> $DIR/conflict-drop.rs:4:1
   |
 4 | #[pin_project] //~ ERROR E0119
diff --git a/tests/ui/pin_project/conflict-naming.rs b/tests/ui/pin_project/conflict-naming.rs
deleted file mode 100644
index 1cb50b4..0000000
--- a/tests/ui/pin_project/conflict-naming.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use pin_project::pin_project;
-
-#[pin_project(project = A, project_ref = A)] //~ ERROR E0428,E0308
-struct Struct(#[pin] ());
-
-fn main() {}
diff --git a/tests/ui/pin_project/conflict-naming.stderr b/tests/ui/pin_project/conflict-naming.stderr
deleted file mode 100644
index bbac1eb..0000000
--- a/tests/ui/pin_project/conflict-naming.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0428]: the name `A` is defined multiple times
- --> $DIR/conflict-naming.rs:3:1
-  |
-3 | #[pin_project(project = A, project_ref = A)] //~ ERROR E0428,E0308
-  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  | |
-  | `A` redefined here
-  | previous definition of the type `A` here
-  |
-  = note: `A` must be defined only once in the type namespace of this module
-  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error[E0308]: mismatched types
- --> $DIR/conflict-naming.rs:3:1
-  |
-3 | #[pin_project(project = A, project_ref = A)] //~ ERROR E0428,E0308
-  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
-  |
-  = note: expected mutable reference `&mut ()`
-                     found reference `&()`
-  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pin_project/invalid.rs b/tests/ui/pin_project/invalid.rs
index d7911df..9c51bec 100644
--- a/tests/ui/pin_project/invalid.rs
+++ b/tests/ui/pin_project/invalid.rs
@@ -100,6 +100,9 @@
     #[pin_project()] // Ok
     struct Unexpected4(#[pin] ());
 
+    #[pin_project(PinnedDrop PinnedDrop)] //~ ERROR expected `,`
+    struct Unexpected5(#[pin] ());
+
     #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
     struct DuplicatePinnedDrop(#[pin] ());
 
@@ -121,13 +124,22 @@
     #[pin_project(project = A, project = B)] //~ ERROR duplicate `project` argument
     struct DuplicateProject(#[pin] ());
 
+    #[pin_project(project = A, project_ref = A, project = B)] //~ ERROR duplicate `project` argument
+    struct DuplicateProject2(#[pin] ());
+
     #[pin_project(project_ref = A, project_ref = B)] //~ ERROR duplicate `project_ref` argument
     struct DuplicateProjectRef(#[pin] ());
 
     #[pin_project(project_replace = A, project_replace = B)] //~ ERROR duplicate `project_replace` argument
-    struct DuplicateProjectReplace(#[pin] ());
+    struct DuplicateProjectReplace1(#[pin] ());
 
-    #[pin_project(project_replace = A)] //~ ERROR `project_replace` argument can only be used together with `Replace` argument
+    #[pin_project(project_replace, project_replace = B)] //~ ERROR duplicate `project_replace` argument
+    struct DuplicateProjectReplace2(#[pin] ());
+
+    #[pin_project(project_replace = A, project_replace)] //~ ERROR duplicate `project_replace` argument
+    struct DuplicateProjectReplace3(#[pin] ());
+
+    #[pin_project(project_replace = A)] // Ok
     struct ProjectReplaceWithoutReplace(#[pin] ());
 
     #[pin_project(PinnedDrop, Replace)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
@@ -136,35 +148,69 @@
     #[pin_project(Replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
     struct PinnedDropWithReplace2(#[pin] ());
 
+    #[pin_project(PinnedDrop, project_replace)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
+    struct PinnedDropWithProjectReplace1(#[pin] ());
+
+    #[pin_project(project_replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
+    struct PinnedDropWithProjectReplace2(#[pin] ());
+
+    #[pin_project(project_replace, Replace)] // Ok
+    struct ProjectReplaceWithReplace1(#[pin] ());
+
+    #[pin_project(project_replace = B, Replace)] // Ok
+    struct ProjectReplaceWithReplace2(#[pin] ());
+
     #[pin_project(UnsafeUnpin, !Unpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
     struct UnsafeUnpinWithNotUnpin1(#[pin] ());
 
     #[pin_project(!Unpin, PinnedDrop, UnsafeUnpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
     struct UnsafeUnpinWithNotUnpin2(#[pin] ());
 
-    #[pin_project(!)] //~ ERROR unexpected end of input, expected `Unpin`
+    #[pin_project(!)] //~ ERROR expected `!Unpin`, found `!`
     struct NotUnpin1(#[pin] ());
 
     #[pin_project(Unpin)] //~ ERROR unexpected argument
     struct NotUnpin2(#[pin] ());
 
-    #[pin_project(project)] //~ ERROR expected `=`
+    #[pin_project(project)] //~ ERROR expected `project = <identifier>`, found `project`
     struct Project1(#[pin] ());
 
-    #[pin_project(project = )] //~ ERROR unexpected end of input, expected identifier
+    #[pin_project(project = )] //~ ERROR expected `project = <identifier>`, found `project =`
     struct Project2(#[pin] ());
 
-    #[pin_project(project_ref)] //~ ERROR expected `=`
+    #[pin_project(project = !)] //~ ERROR expected identifier
+    struct Project3(#[pin] ());
+
+    #[pin_project(project_ref)] //~ ERROR expected `project_ref = <identifier>`, found `project_ref`
     struct ProjectRef1(#[pin] ());
 
-    #[pin_project(project_ref = )] //~ ERROR unexpected end of input, expected identifier
+    #[pin_project(project_ref = )] //~ ERROR expected `project_ref = <identifier>`, found `project_ref =`
     struct ProjectRef2(#[pin] ());
 
-    #[pin_project(project_replace)] //~ ERROR expected `=`
+    #[pin_project(project_ref = !)] //~ ERROR expected identifier
+    struct ProjectRef3(#[pin] ());
+
+    #[pin_project(project_replace)] // Ok
     struct ProjectReplace1(#[pin] ());
 
-    #[pin_project(project_replace = )] //~ ERROR unexpected end of input, expected identifier
+    #[pin_project(project_replace = )] //~ ERROR expected `project_replace = <identifier>`, found `project_replace =`
     struct ProjectReplace2(#[pin] ());
+
+    #[pin_project(project_replace = !)] //~ ERROR expected identifier
+    struct ProjectReplace3(#[pin] ());
+}
+
+mod pin_project_conflict_naming {
+    use pin_project::pin_project;
+
+    #[pin_project(project = A, project_ref = A)] //~ ERROR name `A` is already specified by `project` argument
+    struct ProjAndProjRef(#[pin] ());
+
+    #[pin_project(project = A, project_replace = A)] //~ ERROR name `A` is already specified by `project` argument
+    struct ProjAndProjOwn(#[pin] ());
+
+    #[pin_project(project_ref = A, project_replace = A)] //~ ERROR name `A` is already specified by `project_ref` argument
+    struct ProjRefAndProjOwn(#[pin] ());
 }
 
 mod pin_project_attribute {
diff --git a/tests/ui/pin_project/invalid.stderr b/tests/ui/pin_project/invalid.stderr
index 82026aa..3c6af57 100644
--- a/tests/ui/pin_project/invalid.stderr
+++ b/tests/ui/pin_project/invalid.stderr
@@ -82,219 +82,265 @@
 97 |     #[pin_project(,UnsafeUnpin)] //~ ERROR expected identifier
    |                   ^
 
-error: duplicate `PinnedDrop` argument
-   --> $DIR/invalid.rs:103:31
+error: expected `,`
+   --> $DIR/invalid.rs:103:30
     |
-103 |     #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
+103 |     #[pin_project(PinnedDrop PinnedDrop)] //~ ERROR expected `,`
+    |                              ^^^^^^^^^^
+
+error: duplicate `PinnedDrop` argument
+   --> $DIR/invalid.rs:106:31
+    |
+106 |     #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
     |                               ^^^^^^^^^^
 
 error: duplicate `Replace` argument
-   --> $DIR/invalid.rs:106:28
+   --> $DIR/invalid.rs:109:28
     |
-106 |     #[pin_project(Replace, Replace)] //~ ERROR duplicate `Replace` argument
+109 |     #[pin_project(Replace, Replace)] //~ ERROR duplicate `Replace` argument
     |                            ^^^^^^^
 
 error: duplicate `UnsafeUnpin` argument
-   --> $DIR/invalid.rs:109:32
+   --> $DIR/invalid.rs:112:32
     |
-109 |     #[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
+112 |     #[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
     |                                ^^^^^^^^^^^
 
 error: duplicate `!Unpin` argument
-   --> $DIR/invalid.rs:112:27
+   --> $DIR/invalid.rs:115:27
     |
-112 |     #[pin_project(!Unpin, !Unpin)] //~ ERROR duplicate `!Unpin` argument
+115 |     #[pin_project(!Unpin, !Unpin)] //~ ERROR duplicate `!Unpin` argument
     |                           ^^^^^^
 
 error: duplicate `UnsafeUnpin` argument
-   --> $DIR/invalid.rs:115:44
+   --> $DIR/invalid.rs:118:44
     |
-115 |     #[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
+118 |     #[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
     |                                            ^^^^^^^^^^^
 
 error: duplicate `PinnedDrop` argument
-   --> $DIR/invalid.rs:118:44
+   --> $DIR/invalid.rs:121:44
     |
-118 |     #[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, UnsafeUnpin)] //~ ERROR duplicate `PinnedDrop` argument
+121 |     #[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, UnsafeUnpin)] //~ ERROR duplicate `PinnedDrop` argument
     |                                            ^^^^^^^^^^
 
 error: duplicate `project` argument
-   --> $DIR/invalid.rs:121:32
+   --> $DIR/invalid.rs:124:32
     |
-121 |     #[pin_project(project = A, project = B)] //~ ERROR duplicate `project` argument
-    |                                ^^^^^^^
+124 |     #[pin_project(project = A, project = B)] //~ ERROR duplicate `project` argument
+    |                                ^^^^^^^^^^^
+
+error: duplicate `project` argument
+   --> $DIR/invalid.rs:127:49
+    |
+127 |     #[pin_project(project = A, project_ref = A, project = B)] //~ ERROR duplicate `project` argument
+    |                                                 ^^^^^^^^^^^
 
 error: duplicate `project_ref` argument
-   --> $DIR/invalid.rs:124:36
+   --> $DIR/invalid.rs:130:36
     |
-124 |     #[pin_project(project_ref = A, project_ref = B)] //~ ERROR duplicate `project_ref` argument
-    |                                    ^^^^^^^^^^^
+130 |     #[pin_project(project_ref = A, project_ref = B)] //~ ERROR duplicate `project_ref` argument
+    |                                    ^^^^^^^^^^^^^^^
 
 error: duplicate `project_replace` argument
-   --> $DIR/invalid.rs:127:40
+   --> $DIR/invalid.rs:133:40
     |
-127 |     #[pin_project(project_replace = A, project_replace = B)] //~ ERROR duplicate `project_replace` argument
+133 |     #[pin_project(project_replace = A, project_replace = B)] //~ ERROR duplicate `project_replace` argument
+    |                                        ^^^^^^^^^^^^^^^^^^^
+
+error: duplicate `project_replace` argument
+   --> $DIR/invalid.rs:136:36
+    |
+136 |     #[pin_project(project_replace, project_replace = B)] //~ ERROR duplicate `project_replace` argument
+    |                                    ^^^^^^^^^^^^^^^^^^^
+
+error: duplicate `project_replace` argument
+   --> $DIR/invalid.rs:139:40
+    |
+139 |     #[pin_project(project_replace = A, project_replace)] //~ ERROR duplicate `project_replace` argument
     |                                        ^^^^^^^^^^^^^^^
 
-error: `project_replace` argument can only be used together with `Replace` argument
-   --> $DIR/invalid.rs:130:19
-    |
-130 |     #[pin_project(project_replace = A)] //~ ERROR `project_replace` argument can only be used together with `Replace` argument
-    |                   ^^^^^^^^^^^^^^^
-
 error: arguments `PinnedDrop` and `Replace` are mutually exclusive
-   --> $DIR/invalid.rs:133:19
+   --> $DIR/invalid.rs:145:19
     |
-133 |     #[pin_project(PinnedDrop, Replace)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
+145 |     #[pin_project(PinnedDrop, Replace)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
     |                   ^^^^^^^^^^
 
 error: arguments `PinnedDrop` and `Replace` are mutually exclusive
-   --> $DIR/invalid.rs:136:41
+   --> $DIR/invalid.rs:148:41
     |
-136 |     #[pin_project(Replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
+148 |     #[pin_project(Replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
     |                                         ^^^^^^^^^^
 
-error: arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
-   --> $DIR/invalid.rs:139:19
+error: arguments `PinnedDrop` and `project_replace` are mutually exclusive
+   --> $DIR/invalid.rs:151:19
     |
-139 |     #[pin_project(UnsafeUnpin, !Unpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
+151 |     #[pin_project(PinnedDrop, project_replace)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
+    |                   ^^^^^^^^^^
+
+error: arguments `PinnedDrop` and `project_replace` are mutually exclusive
+   --> $DIR/invalid.rs:154:49
+    |
+154 |     #[pin_project(project_replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
+    |                                                 ^^^^^^^^^^
+
+error: arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
+   --> $DIR/invalid.rs:163:19
+    |
+163 |     #[pin_project(UnsafeUnpin, !Unpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
     |                   ^^^^^^^^^^^
 
 error: arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
-   --> $DIR/invalid.rs:142:39
+   --> $DIR/invalid.rs:166:39
     |
-142 |     #[pin_project(!Unpin, PinnedDrop, UnsafeUnpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
+166 |     #[pin_project(!Unpin, PinnedDrop, UnsafeUnpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
     |                                       ^^^^^^^^^^^
 
-error: unexpected end of input, expected `Unpin`
-   --> $DIR/invalid.rs:145:5
+error: expected `!Unpin`, found `!`
+   --> $DIR/invalid.rs:169:19
     |
-145 |     #[pin_project(!)] //~ ERROR unexpected end of input, expected `Unpin`
-    |     ^^^^^^^^^^^^^^^^^
-    |
-    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+169 |     #[pin_project(!)] //~ ERROR expected `!Unpin`, found `!`
+    |                   ^
 
 error: unexpected argument: Unpin
-   --> $DIR/invalid.rs:148:19
+   --> $DIR/invalid.rs:172:19
     |
-148 |     #[pin_project(Unpin)] //~ ERROR unexpected argument
+172 |     #[pin_project(Unpin)] //~ ERROR unexpected argument
     |                   ^^^^^
 
-error: expected `=`
-   --> $DIR/invalid.rs:151:5
+error: expected `project = <identifier>`, found `project`
+   --> $DIR/invalid.rs:175:19
     |
-151 |     #[pin_project(project)] //~ ERROR expected `=`
-    |     ^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+175 |     #[pin_project(project)] //~ ERROR expected `project = <identifier>`, found `project`
+    |                   ^^^^^^^
 
-error: unexpected end of input, expected identifier
-   --> $DIR/invalid.rs:154:5
+error: expected `project = <identifier>`, found `project =`
+   --> $DIR/invalid.rs:178:19
     |
-154 |     #[pin_project(project = )] //~ ERROR unexpected end of input, expected identifier
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+178 |     #[pin_project(project = )] //~ ERROR expected `project = <identifier>`, found `project =`
+    |                   ^^^^^^^^^
 
-error: expected `=`
-   --> $DIR/invalid.rs:157:5
+error: expected identifier
+   --> $DIR/invalid.rs:181:29
     |
-157 |     #[pin_project(project_ref)] //~ ERROR expected `=`
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+181 |     #[pin_project(project = !)] //~ ERROR expected identifier
+    |                             ^
 
-error: unexpected end of input, expected identifier
-   --> $DIR/invalid.rs:160:5
+error: expected `project_ref = <identifier>`, found `project_ref`
+   --> $DIR/invalid.rs:184:19
     |
-160 |     #[pin_project(project_ref = )] //~ ERROR unexpected end of input, expected identifier
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+184 |     #[pin_project(project_ref)] //~ ERROR expected `project_ref = <identifier>`, found `project_ref`
+    |                   ^^^^^^^^^^^
 
-error: expected `=`
-   --> $DIR/invalid.rs:163:5
+error: expected `project_ref = <identifier>`, found `project_ref =`
+   --> $DIR/invalid.rs:187:19
     |
-163 |     #[pin_project(project_replace)] //~ ERROR expected `=`
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-    |
-    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+187 |     #[pin_project(project_ref = )] //~ ERROR expected `project_ref = <identifier>`, found `project_ref =`
+    |                   ^^^^^^^^^^^^^
 
-error: unexpected end of input, expected identifier
-   --> $DIR/invalid.rs:166:5
+error: expected identifier
+   --> $DIR/invalid.rs:190:33
     |
-166 |     #[pin_project(project_replace = )] //~ ERROR unexpected end of input, expected identifier
-    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+190 |     #[pin_project(project_ref = !)] //~ ERROR expected identifier
+    |                                 ^
+
+error: expected `project_replace = <identifier>`, found `project_replace =`
+   --> $DIR/invalid.rs:196:19
     |
-    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+196 |     #[pin_project(project_replace = )] //~ ERROR expected `project_replace = <identifier>`, found `project_replace =`
+    |                   ^^^^^^^^^^^^^^^^^
+
+error: expected identifier
+   --> $DIR/invalid.rs:199:37
+    |
+199 |     #[pin_project(project_replace = !)] //~ ERROR expected identifier
+    |                                     ^
+
+error: name `A` is already specified by `project` argument
+   --> $DIR/invalid.rs:206:46
+    |
+206 |     #[pin_project(project = A, project_ref = A)] //~ ERROR name `A` is already specified by `project` argument
+    |                                              ^
+
+error: name `A` is already specified by `project` argument
+   --> $DIR/invalid.rs:209:50
+    |
+209 |     #[pin_project(project = A, project_replace = A)] //~ ERROR name `A` is already specified by `project` argument
+    |                                                  ^
+
+error: name `A` is already specified by `project_ref` argument
+   --> $DIR/invalid.rs:212:54
+    |
+212 |     #[pin_project(project_ref = A, project_replace = A)] //~ ERROR name `A` is already specified by `project_ref` argument
+    |                                                      ^
 
 error: duplicate #[pin_project] attribute
-   --> $DIR/invalid.rs:174:5
+   --> $DIR/invalid.rs:220:5
     |
-174 |     #[pin_project] //~ ERROR duplicate #[pin_project] attribute
+220 |     #[pin_project] //~ ERROR duplicate #[pin_project] attribute
     |     ^^^^^^^^^^^^^^
 
 error: #[pin_project] attribute may not be used on structs with zero fields
-   --> $DIR/invalid.rs:182:19
+   --> $DIR/invalid.rs:228:19
     |
-182 |     struct Struct {} //~ ERROR may not be used on structs with zero fields
+228 |     struct Struct {} //~ ERROR may not be used on structs with zero fields
     |                   ^^
 
 error: #[pin_project] attribute may not be used on structs with zero fields
-   --> $DIR/invalid.rs:185:23
+   --> $DIR/invalid.rs:231:23
     |
-185 |     struct TupleStruct(); //~ ERROR may not be used on structs with zero fields
+231 |     struct TupleStruct(); //~ ERROR may not be used on structs with zero fields
     |                       ^^
 
 error: #[pin_project] attribute may not be used on structs with zero fields
-   --> $DIR/invalid.rs:188:12
+   --> $DIR/invalid.rs:234:12
     |
-188 |     struct UnitStruct; //~ ERROR may not be used on structs with zero fields
+234 |     struct UnitStruct; //~ ERROR may not be used on structs with zero fields
     |            ^^^^^^^^^^
 
 error: #[pin_project] attribute may not be used on enums without variants
-   --> $DIR/invalid.rs:191:20
+   --> $DIR/invalid.rs:237:20
     |
-191 |     enum EnumEmpty {} //~ ERROR may not be used on enums without variants
+237 |     enum EnumEmpty {} //~ ERROR may not be used on enums without variants
     |                    ^^
 
 error: #[pin_project] attribute may not be used on enums with discriminants
-   --> $DIR/invalid.rs:195:13
+   --> $DIR/invalid.rs:241:13
     |
-195 |         V = 2, //~ ERROR may not be used on enums with discriminants
+241 |         V = 2, //~ ERROR may not be used on enums with discriminants
     |             ^
 
 error: #[pin_project] attribute may not be used on enums with zero fields
-   --> $DIR/invalid.rs:200:9
+   --> $DIR/invalid.rs:246:9
     |
-200 | /         Unit, //~ ERROR may not be used on enums with zero fields
-201 | |         Tuple(),
-202 | |         Struct {},
+246 | /         Unit, //~ ERROR may not be used on enums with zero fields
+247 | |         Tuple(),
+248 | |         Struct {},
     | |__________________^
 
 error: #[pin_project] attribute may only be used on structs or enums
-   --> $DIR/invalid.rs:206:5
+   --> $DIR/invalid.rs:252:5
     |
-206 | /     union Union {
-207 | |         //~^ ERROR may only be used on structs or enums
-208 | |         f: (),
-209 | |     }
+252 | /     union Union {
+253 | |         //~^ ERROR may only be used on structs or enums
+254 | |         f: (),
+255 | |     }
     | |_____^
 
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
-   --> $DIR/invalid.rs:217:12
+   --> $DIR/invalid.rs:263:12
     |
-217 |     #[repr(packed)]
+263 |     #[repr(packed)]
     |            ^^^^^^
 
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
-   --> $DIR/invalid.rs:221:12
+   --> $DIR/invalid.rs:267:12
     |
-221 |     #[repr(packed)]
+267 |     #[repr(packed)]
     |            ^^^^^^
 
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
-   --> $DIR/invalid.rs:225:12
+   --> $DIR/invalid.rs:271:12
     |
-225 |     #[repr(packed)]
+271 |     #[repr(packed)]
     |            ^^^^^^
diff --git a/tests/ui/pin_project/overlapping_unpin_struct.stderr b/tests/ui/pin_project/overlapping_unpin_struct.stderr
index d0fd4a9..96a9f51 100644
--- a/tests/ui/pin_project/overlapping_unpin_struct.stderr
+++ b/tests/ui/pin_project/overlapping_unpin_struct.stderr
@@ -5,7 +5,7 @@
    |                ----- required by this bound in `is_unpin`
 ...
 17 |     is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__SCOPE_Foo::__Foo<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Foo<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `__SCOPE_Foo::__Foo<'_, std::marker::PhantomPinned>`
+   = note: required because it appears within the type `_::__Foo<'_, std::marker::PhantomPinned>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned>`
diff --git a/tests/ui/pin_project/project_replace_unsized.rs b/tests/ui/pin_project/project_replace_unsized.rs
new file mode 100644
index 0000000..706a0c1
--- /dev/null
+++ b/tests/ui/pin_project/project_replace_unsized.rs
@@ -0,0 +1,11 @@
+use pin_project::pin_project;
+
+#[pin_project(project_replace)] //~ ERROR E0277
+struct Struct<T: ?Sized> {
+    x: T,
+}
+
+#[pin_project(project_replace)] //~ ERROR E0277
+struct TupleStruct<T: ?Sized>(T);
+
+fn main() {}
diff --git a/tests/ui/pin_project/project_replace_unsized.stderr b/tests/ui/pin_project/project_replace_unsized.stderr
new file mode 100644
index 0000000..c3a3be7
--- /dev/null
+++ b/tests/ui/pin_project/project_replace_unsized.stderr
@@ -0,0 +1,77 @@
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+ --> $DIR/project_replace_unsized.rs:3:15
+  |
+3 | #[pin_project(project_replace)] //~ ERROR E0277
+  |               ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+4 | struct Struct<T: ?Sized> {
+  |               - this type parameter needs to be `std::marker::Sized`
+  |
+  = help: within `Struct<T>`, the trait `std::marker::Sized` is not implemented for `T`
+  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+  = note: required because it appears within the type `Struct<T>`
+  = note: all local variables must have a statically known size
+  = help: unsized locals are gated as an unstable feature
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+   --> $DIR/project_replace_unsized.rs:5:5
+    |
+4   | struct Struct<T: ?Sized> {
+    |               - this type parameter needs to be `std::marker::Sized`
+5   |     x: T,
+    |     ^ doesn't have a size known at compile-time
+    |
+    = help: the trait `std::marker::Sized` is not implemented for `T`
+    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+ --> $DIR/project_replace_unsized.rs:3:1
+  |
+3 | #[pin_project(project_replace)] //~ ERROR E0277
+  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+4 | struct Struct<T: ?Sized> {
+  |               - this type parameter needs to be `std::marker::Sized`
+  |
+  = help: within `__StructProjectionOwned<T>`, the trait `std::marker::Sized` is not implemented for `T`
+  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+  = note: required because it appears within the type `__StructProjectionOwned<T>`
+  = note: structs must have a statically known size to be initialized
+  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+ --> $DIR/project_replace_unsized.rs:8:15
+  |
+8 | #[pin_project(project_replace)] //~ ERROR E0277
+  |               ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+9 | struct TupleStruct<T: ?Sized>(T);
+  |                    - this type parameter needs to be `std::marker::Sized`
+  |
+  = help: within `TupleStruct<T>`, the trait `std::marker::Sized` is not implemented for `T`
+  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+  = note: required because it appears within the type `TupleStruct<T>`
+  = note: all local variables must have a statically known size
+  = help: unsized locals are gated as an unstable feature
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+   --> $DIR/project_replace_unsized.rs:8:1
+    |
+8   | #[pin_project(project_replace)] //~ ERROR E0277
+    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+9   | struct TupleStruct<T: ?Sized>(T);
+    |                    - this type parameter needs to be `std::marker::Sized`
+    |
+    = help: the trait `std::marker::Sized` is not implemented for `T`
+    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+ --> $DIR/project_replace_unsized.rs:9:8
+  |
+9 | struct TupleStruct<T: ?Sized>(T);
+  |        ^^^^^^^^^^^ - this type parameter needs to be `std::marker::Sized`
+  |        |
+  |        doesn't have a size known at compile-time
+  |
+  = help: the trait `std::marker::Sized` is not implemented for `T`
+  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+  = note: all function arguments must have a statically known size
+  = help: unsized locals are gated as an unstable feature
diff --git a/tests/ui/pin_project/project_replace_unsized_locals.rs b/tests/ui/pin_project/project_replace_unsized_locals.rs
new file mode 100644
index 0000000..2546041
--- /dev/null
+++ b/tests/ui/pin_project/project_replace_unsized_locals.rs
@@ -0,0 +1,13 @@
+#![feature(unsized_locals)]
+
+use pin_project::pin_project;
+
+#[pin_project(project_replace)] //~ ERROR E0277
+struct Struct<T: ?Sized> {
+    x: T,
+}
+
+#[pin_project(project_replace)] //~ ERROR E0277
+struct TupleStruct<T: ?Sized>(T);
+
+fn main() {}
diff --git a/tests/ui/pin_project/project_replace_unsized_locals.stderr b/tests/ui/pin_project/project_replace_unsized_locals.stderr
new file mode 100644
index 0000000..1616904
--- /dev/null
+++ b/tests/ui/pin_project/project_replace_unsized_locals.stderr
@@ -0,0 +1,64 @@
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+ --> $DIR/project_replace_unsized_locals.rs:6:8
+  |
+6 | struct Struct<T: ?Sized> {
+  |        ^^^^^^^-^^^^^^^^^
+  |        |      |
+  |        |      this type parameter needs to be `std::marker::Sized`
+  |        doesn't have a size known at compile-time
+  |
+  = help: within `__StructProjectionOwned<T>`, the trait `std::marker::Sized` is not implemented for `T`
+  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+  = note: required because it appears within the type `__StructProjectionOwned<T>`
+  = note: the return type of a function must have a statically known size
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+   --> $DIR/project_replace_unsized_locals.rs:7:5
+    |
+6   | struct Struct<T: ?Sized> {
+    |               - this type parameter needs to be `std::marker::Sized`
+7   |     x: T,
+    |     ^ doesn't have a size known at compile-time
+    |
+    = help: the trait `std::marker::Sized` is not implemented for `T`
+    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+ --> $DIR/project_replace_unsized_locals.rs:5:1
+  |
+5 | #[pin_project(project_replace)] //~ ERROR E0277
+  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+6 | struct Struct<T: ?Sized> {
+  |               - this type parameter needs to be `std::marker::Sized`
+  |
+  = help: within `__StructProjectionOwned<T>`, the trait `std::marker::Sized` is not implemented for `T`
+  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+  = note: required because it appears within the type `__StructProjectionOwned<T>`
+  = note: structs must have a statically known size to be initialized
+  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/project_replace_unsized_locals.rs:11:8
+   |
+11 | struct TupleStruct<T: ?Sized>(T);
+   |        ^^^^^^^^^^^^-^^^^^^^^^
+   |        |           |
+   |        |           this type parameter needs to be `std::marker::Sized`
+   |        doesn't have a size known at compile-time
+   |
+   = help: within `__TupleStructProjectionOwned<T>`, the trait `std::marker::Sized` is not implemented for `T`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+   = note: required because it appears within the type `__TupleStructProjectionOwned<T>`
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+   --> $DIR/project_replace_unsized_locals.rs:10:1
+    |
+10  | #[pin_project(project_replace)] //~ ERROR E0277
+    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+11  | struct TupleStruct<T: ?Sized>(T);
+    |                    - this type parameter needs to be `std::marker::Sized`
+    |
+    = help: the trait `std::marker::Sized` is not implemented for `T`
+    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pin_project/proper_unpin.stderr b/tests/ui/pin_project/proper_unpin.stderr
index 9142887..7562597 100644
--- a/tests/ui/pin_project/proper_unpin.stderr
+++ b/tests/ui/pin_project/proper_unpin.stderr
@@ -5,10 +5,10 @@
    |                ----- required by this bound in `is_unpin`
 ...
 31 |     is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__SCOPE_Foo::__Foo<'_, std::marker::PhantomPinned, ()>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Foo<'_, std::marker::PhantomPinned, ()>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
    = note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
-   = note: required because it appears within the type `__SCOPE_Foo::__Foo<'_, std::marker::PhantomPinned, ()>`
+   = note: required because it appears within the type `_::__Foo<'_, std::marker::PhantomPinned, ()>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, ()>`
 
 error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
@@ -18,10 +18,10 @@
    |                ----- required by this bound in `is_unpin`
 ...
 33 |     is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__SCOPE_Foo::__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
    = note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
-   = note: required because it appears within the type `__SCOPE_Foo::__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
+   = note: required because it appears within the type `_::__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, std::marker::PhantomPinned>`
 
 error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
@@ -31,7 +31,7 @@
    |                ----- required by this bound in `is_unpin`
 ...
 35 |     is_unpin::<TrivialBounds>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ within `__SCOPE_TrivialBounds::__TrivialBounds<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__TrivialBounds<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `__SCOPE_TrivialBounds::__TrivialBounds<'_>`
+   = note: required because it appears within the type `_::__TrivialBounds<'_>`
    = note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
diff --git a/tests/ui/pin_project/remove-attr-from-field.rs b/tests/ui/pin_project/remove-attr-from-field.rs
index eebd3cd..1ecd56f 100644
--- a/tests/ui/pin_project/remove-attr-from-field.rs
+++ b/tests/ui/pin_project/remove-attr-from-field.rs
@@ -5,28 +5,28 @@
 fn is_unpin<T: Unpin>() {}
 
 #[pin_project]
-#[remove_attr(field)]
-struct Foo {
+#[remove_attr(field_all)]
+struct A {
     #[pin]
     field: PhantomPinned,
 }
 
-#[remove_attr(field)]
+#[remove_attr(field_all)]
 #[pin_project]
-struct Bar {
+struct B {
     #[pin]
     field: PhantomPinned,
 }
 
 fn main() {
-    is_unpin::<Foo>();
-    is_unpin::<Bar>();
+    is_unpin::<A>();
+    is_unpin::<B>();
 
-    let mut x = Foo { field: PhantomPinned };
+    let mut x = A { field: PhantomPinned };
     let x = Pin::new(&mut x).project();
     let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
 
-    let mut x = Bar { field: PhantomPinned };
+    let mut x = B { field: PhantomPinned };
     let x = Pin::new(&mut x).project();
     let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
 }
diff --git a/tests/ui/pin_project/remove-attr-from-struct.rs b/tests/ui/pin_project/remove-attr-from-struct.rs
index b395a42..0c7af63 100644
--- a/tests/ui/pin_project/remove-attr-from-struct.rs
+++ b/tests/ui/pin_project/remove-attr-from-struct.rs
@@ -5,26 +5,42 @@
 fn is_unpin<T: Unpin>() {}
 
 #[pin_project]
-#[remove_attr(struct)]
-struct Foo {
+#[remove_attr(struct_all)]
+struct A {
     #[pin] //~ ERROR cannot find attribute `pin` in this scope
     field: PhantomPinned,
 }
 
-#[remove_attr(struct)]
+#[remove_attr(struct_all)]
 #[pin_project]
-struct Bar {
+struct B {
     #[pin] //~ ERROR cannot find attribute `pin` in this scope
     field: PhantomPinned,
 }
 
+#[pin_project] //~ ERROR has been removed
+#[remove_attr(struct_pin)]
+struct C {
+    field: PhantomPinned,
+}
+
+#[remove_attr(struct_pin)]
+#[pin_project] // Ok
+struct D {
+    field: PhantomPinned,
+}
+
 fn main() {
-    is_unpin::<Foo>(); //~ ERROR E0277
-    is_unpin::<Bar>(); //~ ERROR E0277
+    is_unpin::<A>(); //~ ERROR E0277
+    is_unpin::<B>(); //~ ERROR E0277
+    is_unpin::<D>(); // Ok
 
-    let mut x = Foo { field: PhantomPinned };
-    let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+    let mut x = A { field: PhantomPinned };
+    let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
 
-    let mut x = Bar { field: PhantomPinned };
-    let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+    let mut x = B { field: PhantomPinned };
+    let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+
+    let mut x = D { field: PhantomPinned };
+    let _ = Pin::new(&mut x).project(); //~ Ok
 }
diff --git a/tests/ui/pin_project/remove-attr-from-struct.stderr b/tests/ui/pin_project/remove-attr-from-struct.stderr
index 3173248..112584e 100644
--- a/tests/ui/pin_project/remove-attr-from-struct.stderr
+++ b/tests/ui/pin_project/remove-attr-from-struct.stderr
@@ -1,3 +1,11 @@
+error: #[pin_project] attribute has been removed
+  --> $DIR/remove-attr-from-struct.rs:21:1
+   |
+21 | #[pin_project] //~ ERROR has been removed
+   | ^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error: cannot find attribute `pin` in this scope
   --> $DIR/remove-attr-from-struct.rs:10:7
    |
@@ -11,53 +19,53 @@
    |       ^^^
 
 error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/remove-attr-from-struct.rs:22:5
+  --> $DIR/remove-attr-from-struct.rs:34:5
    |
 5  | fn is_unpin<T: Unpin>() {}
    |                ----- required by this bound in `is_unpin`
 ...
-22 |     is_unpin::<Foo>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^ within `Foo`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+34 |     is_unpin::<A>(); //~ ERROR E0277
+   |     ^^^^^^^^^^^^^ within `A`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `Foo`
+   = note: required because it appears within the type `A`
 
 error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/remove-attr-from-struct.rs:23:5
+  --> $DIR/remove-attr-from-struct.rs:35:5
    |
 5  | fn is_unpin<T: Unpin>() {}
    |                ----- required by this bound in `is_unpin`
 ...
-23 |     is_unpin::<Bar>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^ within `Bar`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+35 |     is_unpin::<B>(); //~ ERROR E0277
+   |     ^^^^^^^^^^^^^ within `B`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `Bar`
+   = note: required because it appears within the type `B`
 
 error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/remove-attr-from-struct.rs:26:14
+  --> $DIR/remove-attr-from-struct.rs:39:13
    |
-26 |     let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |              ^^^^^^^^ within `Foo`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+39 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+   |             ^^^^^^^^ within `A`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `Foo`
+   = note: required because it appears within the type `A`
    = note: required by `std::pin::Pin::<P>::new`
 
-error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Foo>` in the current scope
-  --> $DIR/remove-attr-from-struct.rs:26:31
+error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut A>` in the current scope
+  --> $DIR/remove-attr-from-struct.rs:39:30
    |
-26 |     let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |                               ^^^^^^^ method not found in `std::pin::Pin<&mut Foo>`
+39 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+   |                              ^^^^^^^ method not found in `std::pin::Pin<&mut A>`
 
 error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/remove-attr-from-struct.rs:29:14
+  --> $DIR/remove-attr-from-struct.rs:42:13
    |
-29 |     let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |              ^^^^^^^^ within `Bar`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+42 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+   |             ^^^^^^^^ within `B`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
    |
-   = note: required because it appears within the type `Bar`
+   = note: required because it appears within the type `B`
    = note: required by `std::pin::Pin::<P>::new`
 
-error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Bar>` in the current scope
-  --> $DIR/remove-attr-from-struct.rs:29:31
+error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut B>` in the current scope
+  --> $DIR/remove-attr-from-struct.rs:42:30
    |
-29 |     let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |                               ^^^^^^^ method not found in `std::pin::Pin<&mut Bar>`
+42 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+   |                              ^^^^^^^ method not found in `std::pin::Pin<&mut B>`
diff --git a/tests/ui/pin_project/visibility.rs b/tests/ui/pin_project/visibility.rs
index 7dce6ab..01c0831 100644
--- a/tests/ui/pin_project/visibility.rs
+++ b/tests/ui/pin_project/visibility.rs
@@ -4,7 +4,7 @@
     #[pin_project]
     pub struct Default(());
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub struct Replace(());
 }
 pub mod pub_use {
@@ -37,7 +37,7 @@
     #[pin_project]
     pub(crate) struct Default(());
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     pub(crate) struct Replace(());
 }
 pub mod pub_crate_use {
@@ -55,7 +55,7 @@
     #[pin_project(project = DProj, project_ref = DProjRef)]
     pub struct Default(());
 
-    #[pin_project(Replace, project = RProj, project_ref = RProjRef, project_replace = RProjOwn)]
+    #[pin_project(project = RProj, project_ref = RProjRef, project_replace = RProjOwn)]
     pub struct Replace(());
 }
 pub mod pub_renamed_use {
diff --git a/tests/ui/pinned_drop/invalid.rs b/tests/ui/pinned_drop/invalid.rs
index 9ff5de2..7065ec9 100644
--- a/tests/ui/pinned_drop/invalid.rs
+++ b/tests/ui/pinned_drop/invalid.rs
@@ -204,4 +204,26 @@
     }
 }
 
+mod self_ty {
+    use pin_project::pinned_drop;
+
+    #[pinned_drop]
+    impl PinnedDrop for () {
+        //~^ ERROR implementing the trait `PinnedDrop` on this type is unsupported
+        fn drop(self: Pin<&mut Self>) {}
+    }
+
+    #[pinned_drop]
+    impl PinnedDrop for &mut A {
+        //~^ ERROR implementing the trait `PinnedDrop` on this type is unsupported
+        fn drop(self: Pin<&mut Self>) {}
+    }
+
+    #[pinned_drop]
+    impl PinnedDrop for [A] {
+        //~^ ERROR implementing the trait `PinnedDrop` on this type is unsupported
+        fn drop(self: Pin<&mut Self>) {}
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/pinned_drop/invalid.stderr b/tests/ui/pinned_drop/invalid.stderr
index 8046903..65ef9ff 100644
--- a/tests/ui/pinned_drop/invalid.stderr
+++ b/tests/ui/pinned_drop/invalid.stderr
@@ -123,3 +123,21 @@
     |
 203 |         fn pinned_drop(&mut self) {} //~ ERROR method `pinned_drop` is not a member of trait `PinnedDrop
     |            ^^^^^^^^^^^
+
+error: implementing the trait `PinnedDrop` on this type is unsupported
+   --> $DIR/invalid.rs:211:25
+    |
+211 |     impl PinnedDrop for () {
+    |                         ^^
+
+error: implementing the trait `PinnedDrop` on this type is unsupported
+   --> $DIR/invalid.rs:217:25
+    |
+217 |     impl PinnedDrop for &mut A {
+    |                         ^^^^^^
+
+error: implementing the trait `PinnedDrop` on this type is unsupported
+   --> $DIR/invalid.rs:223:25
+    |
+223 |     impl PinnedDrop for [A] {
+    |                         ^^^
diff --git a/tests/ui/pinned_drop/self.rs b/tests/ui/pinned_drop/self.rs
index cd53b04..9176066 100644
--- a/tests/ui/pinned_drop/self.rs
+++ b/tests/ui/pinned_drop/self.rs
@@ -1,10 +1,10 @@
-use pin_project::{pin_project, pinned_drop};
-use std::pin::Pin;
+pub mod self_in_macro_def {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
 
-fn self_in_macro_def() {
     #[pin_project(PinnedDrop)]
     pub struct Struct {
-        x: usize,
+        x: (),
     }
 
     #[pinned_drop]
@@ -12,12 +12,9 @@
         fn drop(self: Pin<&mut Self>) {
             macro_rules! t {
                 () => {{
-                    let _ = self; //~ ERROR can't capture dynamic environment in a fn item
+                    let _ = self; //~ ERROR E0434
 
-                    fn f(self: ()) {
-                        //~^ ERROR `self` parameter is only allowed in associated functions
-                        let _ = self;
-                    }
+                    fn f(self: ()) {} //~ ERROR `self` parameter is only allowed in associated functions
                 }};
             }
             t!();
@@ -25,4 +22,35 @@
     }
 }
 
+pub mod self_span {
+    use pin_project::{pin_project, pinned_drop};
+    use std::pin::Pin;
+
+    #[pin_project(PinnedDrop)]
+    pub struct S {
+        x: (),
+    }
+
+    #[pinned_drop]
+    impl PinnedDrop for S {
+        fn drop(self: Pin<&mut Self>) {
+            let _: () = self; //~ ERROR E0308
+            let _: Self = Self; //~ ERROR E0423
+        }
+    }
+
+    #[pin_project(PinnedDrop)]
+    pub enum E {
+        V { x: () },
+    }
+
+    #[pinned_drop]
+    impl PinnedDrop for E {
+        fn drop(self: Pin<&mut Self>) {
+            let _: () = self; //~ ERROR E0308
+            let _: Self = Self::V; //~ ERROR E0533
+        }
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/pinned_drop/self.stderr b/tests/ui/pinned_drop/self.stderr
index 3ba333b..2a71b0a 100644
--- a/tests/ui/pinned_drop/self.stderr
+++ b/tests/ui/pinned_drop/self.stderr
@@ -1,10 +1,10 @@
 error: `self` parameter is only allowed in associated functions
   --> $DIR/self.rs:17:26
    |
-17 |                     fn f(self: ()) {
+17 |                     fn f(self: ()) {} //~ ERROR `self` parameter is only allowed in associated functions
    |                          ^^^^ not semantically valid as function parameter
 ...
-23 |             t!();
+20 |             t!();
    |             ----- in this macro invocation
    |
    = note: associated functions are those in `impl` or `trait` definitions
@@ -13,11 +13,50 @@
 error[E0434]: can't capture dynamic environment in a fn item
   --> $DIR/self.rs:15:29
    |
-15 |                     let _ = self; //~ ERROR can't capture dynamic environment in a fn item
+15 |                     let _ = self; //~ ERROR E0434
    |                             ^^^^
 ...
-23 |             t!();
+20 |             t!();
    |             ----- in this macro invocation
    |
    = help: use the `|| { ... }` closure form instead
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0423]: expected value, found struct `S`
+  --> $DIR/self.rs:38:27
+   |
+30 | /     pub struct S {
+31 | |         x: (),
+32 | |     }
+   | |_____- `S` defined here
+...
+38 |               let _: Self = Self; //~ ERROR E0423
+   |                             ^^^^ did you mean `S { /* fields */ }`?
+
+error[E0308]: mismatched types
+  --> $DIR/self.rs:37:25
+   |
+37 |             let _: () = self; //~ ERROR E0308
+   |                    --   ^^^^ expected `()`, found struct `std::pin::Pin`
+   |                    |
+   |                    expected due to this
+   |
+   = note: expected unit type `()`
+                 found struct `std::pin::Pin<&mut self_span::S>`
+
+error[E0308]: mismatched types
+  --> $DIR/self.rs:50:25
+   |
+50 |             let _: () = self; //~ ERROR E0308
+   |                    --   ^^^^ expected `()`, found struct `std::pin::Pin`
+   |                    |
+   |                    expected due to this
+   |
+   = note: expected unit type `()`
+                 found struct `std::pin::Pin<&mut self_span::E>`
+
+error[E0533]: expected unit struct, unit variant or constant, found struct variant `Self::V`
+  --> $DIR/self.rs:51:27
+   |
+51 |             let _: Self = Self::V; //~ ERROR E0533
+   |                           ^^^^^^^
diff --git a/tests/ui/project/ambiguous-let.rs b/tests/ui/project/ambiguous-let.rs
index a706749..bbb3a2c 100644
--- a/tests/ui/project/ambiguous-let.rs
+++ b/tests/ui/project/ambiguous-let.rs
@@ -1,3 +1,5 @@
+#![allow(deprecated)]
+
 use pin_project::{pin_project, project};
 
 #[pin_project]
diff --git a/tests/ui/project/ambiguous-let.stderr b/tests/ui/project/ambiguous-let.stderr
index e6552c8..2e66484 100644
--- a/tests/ui/project/ambiguous-let.stderr
+++ b/tests/ui/project/ambiguous-let.stderr
@@ -1,5 +1,5 @@
 error: Both initializer expression and pattern are replaceable, you need to split the initializer expression into separate let bindings to avoid ambiguity
-  --> $DIR/ambiguous-let.rs:16:9
+  --> $DIR/ambiguous-let.rs:18:9
    |
-16 |     let Struct(x) = match Pin::new(&mut foo).project() {
+18 |     let Struct(x) = match Pin::new(&mut foo).project() {
    |         ^^^^^^^^^
diff --git a/tests/ui/project/deprecated.rs b/tests/ui/project/deprecated.rs
new file mode 100644
index 0000000..78d593d
--- /dev/null
+++ b/tests/ui/project/deprecated.rs
@@ -0,0 +1,8 @@
+#![deny(deprecated)]
+
+use pin_project::{project, project_ref, project_replace};
+
+#[project]
+#[project_ref]
+#[project_replace]
+fn main() {}
diff --git a/tests/ui/project/deprecated.stderr b/tests/ui/project/deprecated.stderr
new file mode 100644
index 0000000..015b8df
--- /dev/null
+++ b/tests/ui/project/deprecated.stderr
@@ -0,0 +1,23 @@
+error: use of deprecated item 'project': consider naming projected type by passing `project` argument to #[pin_project] attribute instead, see release note <https://github.com/taiki-e/pin-project/releases/tag/v0.4.21> for details
+ --> $DIR/deprecated.rs:5:3
+  |
+5 | #[project]
+  |   ^^^^^^^
+  |
+note: the lint level is defined here
+ --> $DIR/deprecated.rs:1:9
+  |
+1 | #![deny(deprecated)]
+  |         ^^^^^^^^^^
+
+error: use of deprecated item 'project_ref': consider naming projected type by passing `project_ref` argument to #[pin_project] attribute instead, see release note <https://github.com/taiki-e/pin-project/releases/tag/v0.4.21> for details
+ --> $DIR/deprecated.rs:6:3
+  |
+6 | #[project_ref]
+  |   ^^^^^^^^^^^
+
+error: use of deprecated item 'project_replace': consider naming projected type by passing `project_replace` argument to #[pin_project] attribute instead, see release note <https://github.com/taiki-e/pin-project/releases/tag/v0.4.21> for details
+ --> $DIR/deprecated.rs:7:3
+  |
+7 | #[project_replace]
+  |   ^^^^^^^^^^^^^^^
diff --git a/tests/ui/project/invalid.rs b/tests/ui/project/invalid.rs
index 07e9970..e72f84c 100644
--- a/tests/ui/project/invalid.rs
+++ b/tests/ui/project/invalid.rs
@@ -1,3 +1,5 @@
+#![allow(deprecated)]
+
 mod argument {
     use pin_project::{pin_project, project};
 
@@ -46,7 +48,7 @@
 mod attribute {
     use pin_project::{pin_project, project, project_ref, project_replace};
 
-    #[pin_project(Replace)]
+    #[pin_project(project_replace)]
     struct A(#[pin] ());
 
     #[project]
diff --git a/tests/ui/project/invalid.stderr b/tests/ui/project/invalid.stderr
index 287cac8..e1dc388 100644
--- a/tests/ui/project/invalid.stderr
+++ b/tests/ui/project/invalid.stderr
@@ -1,155 +1,155 @@
 error: unexpected token: ()
-  --> $DIR/invalid.rs:10:18
+  --> $DIR/invalid.rs:12:18
    |
-10 |         #[project()] //~ ERROR unexpected token
+12 |         #[project()] //~ ERROR unexpected token
    |                  ^^
 
 error: unexpected token: (foo)
-  --> $DIR/invalid.rs:17:18
+  --> $DIR/invalid.rs:19:18
    |
-17 |         #[project(foo)] //~ ERROR unexpected token
+19 |         #[project(foo)] //~ ERROR unexpected token
    |                  ^^^^^
 
 error: unexpected token: ()
-  --> $DIR/invalid.rs:24:18
+  --> $DIR/invalid.rs:26:18
    |
-24 |         #[project()] //~ ERROR unexpected token
+26 |         #[project()] //~ ERROR unexpected token
    |                  ^^
 
 error: unexpected token: (foo)
-  --> $DIR/invalid.rs:33:18
+  --> $DIR/invalid.rs:35:18
    |
-33 |         #[project(foo)] //~ ERROR unexpected token
+35 |         #[project(foo)] //~ ERROR unexpected token
    |                  ^^^^^
 
 error: unexpected token: foo
-  --> $DIR/invalid.rs:42:15
+  --> $DIR/invalid.rs:44:15
    |
-42 |     #[project(foo)] //~ ERROR unexpected token
+44 |     #[project(foo)] //~ ERROR unexpected token
    |               ^^^
 
 error: duplicate #[project] attribute
-  --> $DIR/invalid.rs:56:9
+  --> $DIR/invalid.rs:58:9
    |
-56 |         #[project] //~ ERROR duplicate #[project] attribute
+58 |         #[project] //~ ERROR duplicate #[project] attribute
    |         ^^^^^^^^^^
 
 error: duplicate #[project_ref] attribute
-  --> $DIR/invalid.rs:64:9
+  --> $DIR/invalid.rs:66:9
    |
-64 |         #[project_ref] //~ ERROR duplicate #[project_ref] attribute
+66 |         #[project_ref] //~ ERROR duplicate #[project_ref] attribute
    |         ^^^^^^^^^^^^^^
 
 error: duplicate #[project_replace] attribute
-  --> $DIR/invalid.rs:72:9
+  --> $DIR/invalid.rs:74:9
    |
-72 |         #[project_replace] //~ ERROR duplicate #[project_replace] attribute
+74 |         #[project_replace] //~ ERROR duplicate #[project_replace] attribute
    |         ^^^^^^^^^^^^^^^^^^
 
-error: attributes `project_ref` and `project` are mutually exclusive
-  --> $DIR/invalid.rs:79:9
+error: attributes `project` and `project_ref` are mutually exclusive
+  --> $DIR/invalid.rs:82:9
    |
-79 |         #[project]
-   |         ^^^^^^^^^^
+82 |         #[project_ref] //~ ERROR are mutually exclusive
+   |         ^^^^^^^^^^^^^^
 
 error: attributes `project` and `project_replace` are mutually exclusive
-  --> $DIR/invalid.rs:88:9
+  --> $DIR/invalid.rs:90:9
    |
-88 |         #[project_replace] //~ ERROR are mutually exclusive
+90 |         #[project_replace] //~ ERROR are mutually exclusive
    |         ^^^^^^^^^^^^^^^^^^
 
 error: attributes `project_ref` and `project_replace` are mutually exclusive
-  --> $DIR/invalid.rs:96:9
+  --> $DIR/invalid.rs:98:9
    |
-96 |         #[project_replace] //~ ERROR are mutually exclusive
+98 |         #[project_replace] //~ ERROR are mutually exclusive
    |         ^^^^^^^^^^^^^^^^^^
 
-error: attributes `project_ref` and `project` are mutually exclusive
-   --> $DIR/invalid.rs:103:9
+error: attributes `project` and `project_ref` are mutually exclusive
+   --> $DIR/invalid.rs:106:9
     |
-103 |         #[project]
-    |         ^^^^^^^^^^
+106 |         #[project_ref] //~ ERROR are mutually exclusive
+    |         ^^^^^^^^^^^^^^
 
 error: attributes `project` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:112:9
+   --> $DIR/invalid.rs:114:9
     |
-112 |         #[project_replace] //~ ERROR are mutually exclusive
+114 |         #[project_replace] //~ ERROR are mutually exclusive
     |         ^^^^^^^^^^^^^^^^^^
 
 error: attributes `project_ref` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:120:9
+   --> $DIR/invalid.rs:122:9
     |
-120 |         #[project_replace] //~ ERROR are mutually exclusive
+122 |         #[project_replace] //~ ERROR are mutually exclusive
     |         ^^^^^^^^^^^^^^^^^^
 
-error: attributes `project_ref` and `project` are mutually exclusive
-   --> $DIR/invalid.rs:127:9
+error: attributes `project` and `project_ref` are mutually exclusive
+   --> $DIR/invalid.rs:130:9
     |
-127 |         #[project]
-    |         ^^^^^^^^^^
+130 |         #[project_ref] //~ ERROR are mutually exclusive
+    |         ^^^^^^^^^^^^^^
 
 error: attributes `project` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:136:9
+   --> $DIR/invalid.rs:138:9
     |
-136 |         #[project_replace] //~ ERROR are mutually exclusive
+138 |         #[project_replace] //~ ERROR are mutually exclusive
     |         ^^^^^^^^^^^^^^^^^^
 
 error: attributes `project_ref` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:144:9
+   --> $DIR/invalid.rs:146:9
     |
-144 |         #[project_replace] //~ ERROR are mutually exclusive
+146 |         #[project_replace] //~ ERROR are mutually exclusive
     |         ^^^^^^^^^^^^^^^^^^
 
 error: duplicate #[project] attribute
-   --> $DIR/invalid.rs:149:5
+   --> $DIR/invalid.rs:151:5
     |
-149 |     #[project] //~ ERROR duplicate #[project] attribute
+151 |     #[project] //~ ERROR duplicate #[project] attribute
     |     ^^^^^^^^^^
 
 error: duplicate #[project_ref] attribute
-   --> $DIR/invalid.rs:153:5
+   --> $DIR/invalid.rs:155:5
     |
-153 |     #[project_ref] //~ ERROR duplicate #[project_ref] attribute
+155 |     #[project_ref] //~ ERROR duplicate #[project_ref] attribute
     |     ^^^^^^^^^^^^^^
 
 error: duplicate #[project_replace] attribute
-   --> $DIR/invalid.rs:157:5
+   --> $DIR/invalid.rs:159:5
     |
-157 |     #[project_replace] //~ ERROR duplicate #[project_replace] attribute
+159 |     #[project_replace] //~ ERROR duplicate #[project_replace] attribute
     |     ^^^^^^^^^^^^^^^^^^
 
 error: duplicate #[project] attribute
-   --> $DIR/invalid.rs:161:5
+   --> $DIR/invalid.rs:163:5
     |
-161 |     #[project] //~ ERROR duplicate #[project] attribute
+163 |     #[project] //~ ERROR duplicate #[project] attribute
     |     ^^^^^^^^^^
 
 error: duplicate #[project_ref] attribute
-   --> $DIR/invalid.rs:165:5
+   --> $DIR/invalid.rs:167:5
     |
-165 |     #[project_ref] //~ ERROR duplicate #[project_ref] attribute
+167 |     #[project_ref] //~ ERROR duplicate #[project_ref] attribute
     |     ^^^^^^^^^^^^^^
 
 error: duplicate #[project_replace] attribute
-   --> $DIR/invalid.rs:169:5
+   --> $DIR/invalid.rs:171:5
     |
-169 |     #[project_replace] //~ ERROR duplicate #[project_replace] attribute
+171 |     #[project_replace] //~ ERROR duplicate #[project_replace] attribute
     |     ^^^^^^^^^^^^^^^^^^
 
 error: duplicate #[project] attribute
-   --> $DIR/invalid.rs:177:9
+   --> $DIR/invalid.rs:179:9
     |
-177 |         #[project] //~ ERROR duplicate #[project] attribute
+179 |         #[project] //~ ERROR duplicate #[project] attribute
     |         ^^^^^^^^^^
 
 error: duplicate #[project_ref] attribute
-   --> $DIR/invalid.rs:181:9
+   --> $DIR/invalid.rs:183:9
     |
-181 |         #[project_ref] //~ ERROR duplicate #[project_ref] attribute
+183 |         #[project_ref] //~ ERROR duplicate #[project_ref] attribute
     |         ^^^^^^^^^^^^^^
 
 error: duplicate #[project_replace] attribute
-   --> $DIR/invalid.rs:185:9
+   --> $DIR/invalid.rs:187:9
     |
-185 |         #[project_replace] //~ ERROR duplicate #[project_replace] attribute
+187 |         #[project_replace] //~ ERROR duplicate #[project_replace] attribute
     |         ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/project/type-mismatch.rs b/tests/ui/project/type-mismatch.rs
index 41a70eb..0e40c83 100644
--- a/tests/ui/project/type-mismatch.rs
+++ b/tests/ui/project/type-mismatch.rs
@@ -1,3 +1,4 @@
+#![allow(deprecated)]
 #![feature(proc_macro_hygiene, stmt_expr_attributes)]
 
 use pin_project::{pin_project, project};
@@ -36,9 +37,6 @@
     }
 }
 
-//~ ERROR mismatched types
-// span is lost.
-// Refs: https://github.com/rust-lang/rust/issues/43081
 fn type_mismatch_span_issue() {
     #[pin_project]
     enum Enum<A, B, C, D> {
@@ -67,7 +65,7 @@
             let _x: &mut Pin<&mut i32> = field1;
             let _y: &mut &mut i32 = field2;
         }
-        None => {}
+        None => {} //~ ERROR mismatched types
     }
 }
 
diff --git a/tests/ui/project/type-mismatch.stderr b/tests/ui/project/type-mismatch.stderr
index b4c97d5..4199c17 100644
--- a/tests/ui/project/type-mismatch.stderr
+++ b/tests/ui/project/type-mismatch.stderr
@@ -1,16 +1,23 @@
 error[E0308]: mismatched types
-  --> $DIR/type-mismatch.rs:35:9
+  --> $DIR/type-mismatch.rs:36:9
    |
-23 |     match &mut foo {
+24 |     match &mut foo {
    |           -------- this expression has type `&mut type_mismatch::__EnumProjection<'_, {integer}, {integer}, _, _>`
 ...
-35 |         None => {} //~ ERROR mismatched types
+36 |         None => {} //~ ERROR mismatched types
    |         ^^^^ expected enum `type_mismatch::__EnumProjection`, found enum `std::option::Option`
    |
    = note: expected enum `type_mismatch::__EnumProjection<'_, {integer}, {integer}, _, _>`
               found enum `std::option::Option<_>`
 
 error[E0308]: mismatched types
-  |
-  = note: expected enum `type_mismatch_span_issue::__EnumProjection<'_, {integer}, {integer}, _, _>`
-             found enum `std::option::Option<_>`
+  --> $DIR/type-mismatch.rs:68:9
+   |
+56 |     match &mut foo {
+   |           -------- this expression has type `&mut type_mismatch_span_issue::__EnumProjection<'_, {integer}, {integer}, _, _>`
+...
+68 |         None => {} //~ ERROR mismatched types
+   |         ^^^^ expected enum `type_mismatch_span_issue::__EnumProjection`, found enum `std::option::Option`
+   |
+   = note: expected enum `type_mismatch_span_issue::__EnumProjection<'_, {integer}, {integer}, _, _>`
+              found enum `std::option::Option<_>`
diff --git a/tests/ui/project/use-public.rs b/tests/ui/project/use-public.rs
index 23c9b89..aa82a95 100644
--- a/tests/ui/project/use-public.rs
+++ b/tests/ui/project/use-public.rs
@@ -1,3 +1,5 @@
+#![allow(deprecated)]
+
 use pin_project::pin_project;
 
 #[pin_project]
diff --git a/tests/ui/project/use-public.stderr b/tests/ui/project/use-public.stderr
index 7919d65..6956656 100644
--- a/tests/ui/project/use-public.stderr
+++ b/tests/ui/project/use-public.stderr
@@ -1,7 +1,7 @@
 error[E0365]: `__AProjection` is private, and cannot be re-exported
-  --> $DIR/use-public.rs:12:13
+  --> $DIR/use-public.rs:14:13
    |
-12 |     pub use crate::A; //~ ERROR E0365
+14 |     pub use crate::A; //~ ERROR E0365
    |             ^^^^^^^^ re-export of private `__AProjection`
    |
    = note: consider declaring type or module `__AProjection` with `pub`
diff --git a/tests/ui/project/use.rs b/tests/ui/project/use.rs
index d4b02c1..ba56382 100644
--- a/tests/ui/project/use.rs
+++ b/tests/ui/project/use.rs
@@ -1,3 +1,5 @@
+#![allow(deprecated)]
+
 use pin_project::pin_project;
 
 #[pin_project]
diff --git a/tests/ui/project/use.stderr b/tests/ui/project/use.stderr
index 07d0241..daddb16 100644
--- a/tests/ui/project/use.stderr
+++ b/tests/ui/project/use.stderr
@@ -1,11 +1,11 @@
 error: #[project] attribute may not be used on renamed imports
-  --> $DIR/use.rs:12:16
+  --> $DIR/use.rs:14:16
    |
-12 |     use crate::A as B; //~ ERROR #[project] attribute may not be used on renamed imports
+14 |     use crate::A as B; //~ ERROR #[project] attribute may not be used on renamed imports
    |                ^^^^^^
 
 error: #[project] attribute may not be used on glob imports
-  --> $DIR/use.rs:14:16
+  --> $DIR/use.rs:16:16
    |
-14 |     use crate::*; //~ ERROR #[project] attribute may not be used on glob imports
+16 |     use crate::*; //~ ERROR #[project] attribute may not be used on glob imports
    |                ^
diff --git a/tests/ui/unsafe_unpin/conflict-unpin.stderr b/tests/ui/unsafe_unpin/conflict-unpin.stderr
index 62de016..916c3f2 100644
--- a/tests/ui/unsafe_unpin/conflict-unpin.stderr
+++ b/tests/ui/unsafe_unpin/conflict-unpin.stderr
@@ -1,35 +1,32 @@
 error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_, _>`:
-  --> $DIR/conflict-unpin.rs:3:1
+  --> $DIR/conflict-unpin.rs:3:15
    |
 3  | #[pin_project(UnsafeUnpin)] //~ ERROR E0119
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Foo<_, _>`
+   |               ^^^^^^^^^^^ conflicting implementation for `Foo<_, _>`
 ...
 10 | impl<T, U> Unpin for Foo<T, U> where T: Unpin {}
    | --------------------------------------------- first implementation here
    |
    = note: upstream crates may add a new impl of trait `pin_project::UnsafeUnpin` for type `pin_project::__private::Wrapper<'_, Foo<_, _>>` in future versions
-   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Bar<_, _>`:
-  --> $DIR/conflict-unpin.rs:12:1
+  --> $DIR/conflict-unpin.rs:12:15
    |
 12 | #[pin_project(UnsafeUnpin)] //~ ERROR E0119
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
+   |               ^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
 ...
 19 | impl<T, U> Unpin for Bar<T, U> {}
    | ------------------------------ first implementation here
    |
    = note: upstream crates may add a new impl of trait `pin_project::UnsafeUnpin` for type `pin_project::__private::Wrapper<'_, Bar<_, _>>` in future versions
-   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Baz<_, _>`:
-  --> $DIR/conflict-unpin.rs:21:1
+  --> $DIR/conflict-unpin.rs:21:15
    |
 21 | #[pin_project(UnsafeUnpin)] //~ ERROR E0119
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Baz<_, _>`
+   |               ^^^^^^^^^^^ conflicting implementation for `Baz<_, _>`
 ...
 28 | impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {}
    | -------------------------------------------- first implementation here
    |
    = note: upstream crates may add a new impl of trait `pin_project::UnsafeUnpin` for type `pin_project::__private::Wrapper<'_, Baz<_, _>>` in future versions
-   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs b/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs
index 8ad8e41..2b6377a 100644
--- a/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs
+++ b/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs
@@ -1,5 +1,6 @@
 // NB: If you change this test, change 'stmt_expr_attributes-feature-gate.rs' at the same time.
 
+#![allow(deprecated)]
 // proc_macro_hygiene
 // Tracking issue: https://github.com/rust-lang/rust/issues/54727
 #![feature(proc_macro_hygiene)]
diff --git a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs b/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs
index 8226723..5dbe523 100644
--- a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs
+++ b/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs
@@ -1,5 +1,7 @@
 // NB: If you change this test, change 'stmt_expr_attributes.rs' at the same time.
 
+#![allow(deprecated)]
+
 use pin_project::{pin_project, project};
 use std::pin::Pin;
 
diff --git a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr b/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr
index 6510ec7..3c0501a 100644
--- a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr
+++ b/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr
@@ -1,34 +1,34 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/stmt_expr_attributes-feature-gate.rs:22:5
+  --> $DIR/stmt_expr_attributes-feature-gate.rs:24:5
    |
-22 |     #[project] //~ ERROR E0658
+24 |     #[project] //~ ERROR E0658
    |     ^^^^^^^^^^
    |
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/stmt_expr_attributes-feature-gate.rs:38:14
+  --> $DIR/stmt_expr_attributes-feature-gate.rs:40:14
    |
-38 |     let () = #[project] //~ ERROR E0658
+40 |     let () = #[project] //~ ERROR E0658
    |              ^^^^^^^^^^
    |
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
 
 error[E0658]: custom attributes cannot be applied to expressions
-  --> $DIR/stmt_expr_attributes-feature-gate.rs:22:5
+  --> $DIR/stmt_expr_attributes-feature-gate.rs:24:5
    |
-22 |     #[project] //~ ERROR E0658
+24 |     #[project] //~ ERROR E0658
    |     ^^^^^^^^^^
    |
    = note: see issue #54727 <https://github.com/rust-lang/rust/issues/54727> for more information
    = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
 
 error[E0658]: custom attributes cannot be applied to expressions
-  --> $DIR/stmt_expr_attributes-feature-gate.rs:38:14
+  --> $DIR/stmt_expr_attributes-feature-gate.rs:40:14
    |
-38 |     let () = #[project] //~ ERROR E0658
+40 |     let () = #[project] //~ ERROR E0658
    |              ^^^^^^^^^^
    |
    = note: see issue #54727 <https://github.com/rust-lang/rust/issues/54727> for more information