Snap for 7110675 from 803535edf46cf1e4d0b092b6b2e52ae776b41711 to sdk-release

Change-Id: I6a2602727cccb44e63ec9ad6d9291a7fcb7ea7ea
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..3ee260d
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,5 @@
+{
+  "git": {
+    "sha1": "eaebdd63756a9eb509be14d601f85293ab78a95c"
+  }
+}
diff --git a/.clippy.toml b/.clippy.toml
new file mode 100644
index 0000000..983eb57
--- /dev/null
+++ b/.clippy.toml
@@ -0,0 +1 @@
+msrv = "1.37"
diff --git a/.editorconfig b/.editorconfig
index c93ffc7..a73a88d 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,16 +1,20 @@
 # EditorConfig configuration
 # https://editorconfig.org
 
-# Top-most EditorConfig file
 root = true
 
 [*]
+charset = utf-8
 end_of_line = lf
+indent_size = 4
+indent_style = space
 insert_final_newline = true
 trim_trailing_whitespace = true
-charset = utf-8
-indent_style = space
-indent_size = 4
 
 [*.{json,yml,md}]
 indent_size = 2
+
+[*.sh]
+indent_size = 2
+binary_next_line = true
+switch_case_indent = true
diff --git a/.gitattributes b/.gitattributes
index 45bca84..6313b56 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,4 +1 @@
-[attr]rust text eol=lf whitespace=tab-in-indent,trailing-space,tabwidth=4
-
 * text=auto eol=lf
-*.rs rust
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
deleted file mode 100644
index 2fdc28f..0000000
--- a/.github/CODEOWNERS
+++ /dev/null
@@ -1 +0,0 @@
-* @taiki-e
diff --git a/.github/bors.toml b/.github/bors.toml
deleted file mode 100644
index 1779788..0000000
--- a/.github/bors.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-status = ["ci"]
-delete_merged_branches = true
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index 6cd7fae..0000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,167 +0,0 @@
-name: CI
-
-on:
-  pull_request:
-  push:
-    branches:
-      - master
-      - staging
-      - trying
-  schedule:
-    - cron: '00 01 * * *'
-
-env:
-  RUSTFLAGS: -Dwarnings
-  RUST_BACKTRACE: 1
-
-defaults:
-  run:
-    shell: bash
-
-jobs:
-  test:
-    name: test
-    strategy:
-      matrix:
-        rust:
-          # This is the minimum supported Rust version of this crate.
-          # When updating this, the reminder to update the minimum supported Rust version in README.md.
-          - 1.34.0
-          - 1.36.0
-          - 1.37.0
-          - stable
-          - beta
-        include:
-          - os: ubuntu
-            rust: nightly
-          # pin-project itself has no platform-dependent implementation.
-          # macOS is only used to check that pin-project can interoperate
-          # correctly with `#[cfg()]`.
-          - os: macos
-            rust: nightly
-    runs-on: ${{ matrix.os || 'ubuntu' }}-latest
-    steps:
-      - uses: actions/checkout@v2
-      - name: Install Rust
-        run: |
-          . ./ci/install-rust.sh ${{ matrix.rust }}
-      - name: Install cargo-hack
-        if: matrix.rust == 'nightly'
-        run: |
-          cargo install cargo-hack
-      - name: Add targets
-        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 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: |
-          . ./ci/check-minimal-versions.sh
-
-  expandtest:
-    name: expandtest
-    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: Install cargo-expand
-        run: |
-          cargo install cargo-expand
-      - name: cargo test (expandtest)
-        run: |
-          cargo test --all-features --manifest-path tests/expand/Cargo.toml
-
-  clippy:
-    name: clippy
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-      - name: Install Rust
-        run: |
-          . ./ci/install-rust.sh
-      - name: Install clippy
-        run: |
-          . ./ci/install-component.sh clippy
-      - name: cargo clippy
-        run: |
-          cargo clippy --all --all-features --all-targets
-
-  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
-        run: |
-          cargo doc --no-deps --all --all-features
-
-  # These jobs don't actually test anything, but they're used to tell bors the
-  # build completed, as there is no practical way to detect when a workflow is
-  # successful listening to webhooks only.
-  #
-  # ALL THE PREVIOUS JOBS NEEDS TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
-
-  ci-success:
-    name: ci
-    if: github.event_name == 'push' && success()
-    needs:
-      - test
-      - clippy
-      - rustfmt
-      - rustdoc
-      - expandtest
-    runs-on: ubuntu-latest
-    steps:
-      - name: Mark the job as a success
-        run: exit 0
-  ci-failure:
-    name: ci
-    if: github.event_name == 'push' && !success()
-    needs:
-      - test
-      - clippy
-      - rustfmt
-      - rustdoc
-      - expandtest
-    runs-on: ubuntu-latest
-    steps:
-      - name: Mark the job as a failure
-        run: exit 1
diff --git a/.gitignore b/.gitignore
index 214d7a8..ad0f684 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,4 @@
 
 # For platform and editor specific settings, it is recommended to add to
 # a global .gitignore file.
-# Refs: https://help.github.com/en/articles/ignoring-files#create-a-global-gitignore
+# Refs: https://docs.github.com/en/free-pro-team@latest/github/using-git/ignoring-files#configuring-ignored-files-for-all-repositories-on-your-computer
diff --git a/rustfmt.toml b/.rustfmt.toml
similarity index 79%
rename from rustfmt.toml
rename to .rustfmt.toml
index 18c6d2a..6604f5c 100644
--- a/rustfmt.toml
+++ b/.rustfmt.toml
@@ -1,10 +1,11 @@
 # Rustfmt configuration
-# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
+# https://github.com/rust-lang/rustfmt/blob/HEAD/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"
+# Rustfmt cannot format long lines inside macros, but this option detects this.
 # This is unstable (tracking issue: https://github.com/rust-lang/rustfmt/issues/3391)
 error_on_line_overflow = true
 
@@ -21,7 +22,13 @@
 # This is unstable (tracking issue: https://github.com/rust-lang/rustfmt/issues/3348).
 format_code_in_doc_comments = true
 
+# Automatically fix deprecated style.
+use_field_init_shorthand = true
+use_try_shorthand = true
+
 # Set the default settings again to always apply the proper formatting without
 # being affected by the editor settings.
 edition = "2018"
+hard_tabs = false
+newline_style = "Unix"
 tab_spaces = 4
diff --git a/Android.bp b/Android.bp
index 748477a..b549a77 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,4 @@
-// This file is generated by cargo2android.py --run --device --dependencies.
+// This file is generated by cargo2android.py --run --dependencies --device --patch=patches/Android.bp.patch.
 
 rust_library {
     name: "libpin_project",
@@ -6,14 +6,16 @@
     crate_name: "pin_project",
     srcs: ["src/lib.rs"],
     edition: "2018",
-    proc_macros: [
-        "libpin_project_internal",
+    proc_macros: ["libpin_project_internal"],
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.virt",
     ],
 }
 
 // dependent_library ["feature_list"]
-//   pin-project-internal-0.4.23
-//   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"
+//   pin-project-internal-1.0.3
+//   proc-macro2-1.0.24 "default,proc-macro"
+//   quote-1.0.8 "default,proc-macro"
+//   syn-1.0.58 "clone-impls,default,derive,full,parsing,printing,proc-macro,quote,visit,visit-mut"
 //   unicode-xid-0.2.1 "default"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ad7438..6551813 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,28 +4,134 @@
 
 This project adheres to [Semantic Versioning](https://semver.org).
 
+<!--
+Note: In this file, do not use the hard wrap in the middle of a sentence for compatibility with GitHub comment style markdown rendering.
+-->
+
 ## [Unreleased]
 
+## [1.0.3] - 2021-01-05
+
+- Exclude unneeded files from crates.io.
+
+## [1.0.2] - 2020-11-18
+
+- [Suppress `clippy::unknown_clippy_lints` lint in generated code.](https://github.com/taiki-e/pin-project/pull/303)
+
+## [1.0.1] - 2020-10-15
+
+- [Fix warnings when `#[pin_project]` attribute used within `macro_rules!` macros.](https://github.com/taiki-e/pin-project/pull/298)
+
+## [1.0.0] - 2020-10-13
+
+- [Remove deprecated `#[project]`, `#[project_ref]`, and `#[project_replace]` attributes.](https://github.com/taiki-e/pin-project/pull/265)
+
+  Name the projected type by passing an argument with the same name as the method to the `#[pin_project]` attribute instead:
+
+  ```diff
+  - #[pin_project]
+  + #[pin_project(project = EnumProj)]
+    enum Enum<T> {
+        Variant(#[pin] T),
+    }
+
+  - #[project]
+    fn func<T>(x: Pin<&mut Enum<T>>) {
+  -     #[project]
+        match x.project() {
+  -         Enum::Variant(_) => { /* ... */ }
+  +         EnumProj::Variant(_) => { /* ... */ }
+        }
+    }
+  ```
+
+- [Remove deprecated `Replace` argument from `#[pin_project]` attribute.](https://github.com/taiki-e/pin-project/pull/266) Use `project_replace` argument instead.
+
+- [Optimize code generation when used on enums.](https://github.com/taiki-e/pin-project/pull/270)
+
+- [Raise the minimum supported Rust version of this crate from Rust 1.34 to Rust 1.37.](https://github.com/taiki-e/pin-project/pull/292)
+
+- Suppress `explicit_outlives_requirements`, `box_pointers`, `clippy::large_enum_variant`, `clippy::pattern_type_mismatch`, `clippy::implicit_return`, and `clippy::redundant_pub_crate` lints in generated code. ([#276](https://github.com/taiki-e/pin-project/pull/276), [#277](https://github.com/taiki-e/pin-project/pull/277), [#284](https://github.com/taiki-e/pin-project/pull/284))
+
+- Diagnostic improvements.
+
+Changes since the 1.0.0-alpha.1 release:
+
+- [Fix drop order of pinned fields in project_replace](https://github.com/taiki-e/pin-project/pull/287)
+
+- Update minimal version of `syn` to 1.0.44
+
+## [1.0.0-alpha.1] - 2020-09-22
+
+- [Remove deprecated `#[project]`, `#[project_ref]`, and `#[project_replace]` attributes.](https://github.com/taiki-e/pin-project/pull/265)
+
+  Name the projected type by passing an argument with the same name as the method to the `#[pin_project]` attribute instead:
+
+  ```diff
+  - #[pin_project]
+  + #[pin_project(project = EnumProj)]
+    enum Enum<T> {
+        Variant(#[pin] T),
+    }
+
+  - #[project]
+    fn func<T>(x: Pin<&mut Enum<T>>) {
+  -     #[project]
+        match x.project() {
+  -         Enum::Variant(_) => { /* ... */ }
+  +         EnumProj::Variant(_) => { /* ... */ }
+        }
+    }
+  ```
+
+- [Remove deprecated `Replace` argument from `#[pin_project]` attribute.](https://github.com/taiki-e/pin-project/pull/266) Use `project_replace` argument instead.
+
+- [Optimize code generation when used on enums.](https://github.com/taiki-e/pin-project/pull/270)
+
+- Suppress `explicit_outlives_requirements`, `box_pointers`, `clippy::large_enum_variant`, `clippy::pattern_type_mismatch`, and `clippy::implicit_return` lints in generated code. ([#276](https://github.com/taiki-e/pin-project/pull/276), [#277](https://github.com/taiki-e/pin-project/pull/277))
+
+- Diagnostic improvements.
+
+See also [tracking issue for 1.0 release](https://github.com/taiki-e/pin-project/issues/264).
+
+## [0.4.27] - 2020-10-11
+
+- Update minimal version of `syn` to 1.0.44
+
+## [0.4.26] - 2020-10-04
+
+- [Fix drop order of pinned fields in project_replace](https://github.com/taiki-e/pin-project/pull/287)
+
+## [0.4.25] - 2020-10-01
+
+- Suppress `drop_bounds` lint, which will be added to rustc in the future. See [#272](https://github.com/taiki-e/pin-project/issues/272) for more details.
+
+  (Note: 1.0.0-alpha.1 already contains this change.)
+
+## [0.4.24] - 2020-09-26
+
+- Fix compatibility of generated code with `forbid(future_incompatible)`
+
+  Note: This does not guarantee compatibility with `forbid(future_incompatible)` in the future.
+  If rustc adds a new lint, we may not be able to keep this.
+
 ## [0.4.23] - 2020-07-27
 
-* [Fix compile error with `?Sized` type parameters.][262]
+- [Fix compile error with `?Sized` type parameters.][263]
 
-[262]: https://github.com/taiki-e/pin-project/pull/262
+[263]: https://github.com/taiki-e/pin-project/pull/263
 
 ## [0.4.22] - 2020-06-14
 
-* Documentation improvements.
+- Documentation improvements.
 
 ## [0.4.21] - 2020-06-13
 
-* [Deprecated `#[project]`, `#[project_ref]`, and `#[project_replace]` attributes due to some unfixable limitations.][244]
+- [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.
+  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),
@@ -42,11 +148,11 @@
 
   See [#225][225] for more details.
 
-* [Support `Self` in fields and generics in type definitions.][245]
+- [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]
+- [Fix errors involving *"`self` value is a keyword only available in methods with `self` parameter"* in apparently correct code.][250]
 
-* Diagnostic improvements.
+- Diagnostic improvements.
 
 [225]: https://github.com/taiki-e/pin-project/pull/225
 [244]: https://github.com/taiki-e/pin-project/pull/244
@@ -55,7 +161,7 @@
 
 ## [0.4.20] - 2020-06-07
 
-* [You can now use project_replace argument without Replace argument.][243]
+- [You can now use project_replace argument without Replace argument.][243]
   This used to require you to specify both.
 
   ```diff
@@ -66,7 +172,7 @@
     }
   ```
 
-* [Makes `project_replace` argument an alias for `Replace` argument so that it can be used without a value.][243]
+- [Makes `project_replace` argument an alias for `Replace` argument so that it can be used without a value.][243]
 
   ```rust
   #[pin_project(project_replace)]
@@ -77,39 +183,36 @@
 
   *The `Replace` argument will be deprecated in the future.*
 
-* Suppress `unreachable_pub` lint in generated code.
+- 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]
+- [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]
+- [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]
+- [Suppress `clippy::type_repetition_in_bounds` and `clippy::used_underscore_binding` lints in generated code.][233]
 
-* Documentation improvements.
+- Documentation improvements.
 
-* Diagnostic 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
 
-* [Support naming the projection 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:
 
   ```rust
-  use pin_project::pin_project;
-  use std::pin::Pin;
-
   #[pin_project(project = EnumProj)]
   enum Enum<T> {
       Variant(#[pin] T),
@@ -128,22 +231,21 @@
 
 ## [0.4.16] - 2020-05-11
 
-* [Fixed an issue that users can call internal function generated by `#[pinned_drop]`.][223]
+- [Fixed an issue that users can call internal function generated by `#[pinned_drop]`.][223]
 
 [223]: https://github.com/taiki-e/pin-project/pull/223
 
 ## [0.4.15] - 2020-05-10
 
-* [`#[project]` attribute can now handle all project* attributes in that scope with one wrapper attribute.][220]
+- [`#[project]` attribute can now handle all project\* attributes in that scope with one wrapper attribute.][220]
 
 [220]: https://github.com/taiki-e/pin-project/pull/220
 
 ## [0.4.14] - 2020-05-09
 
-* [Added `!Unpin` option to `#[pin_project]` attribute for guarantee the type is `!Unpin`.][219]
+- [Added `!Unpin` option to `#[pin_project]` attribute for guarantee the type is `!Unpin`.][219]
 
   ```rust
-  use pin_project::pin_project;
   #[pin_project(!Unpin)]
   struct Struct<T, U> {
       field: T,
@@ -153,8 +255,6 @@
   This is equivalent to use `#[pin]` attribute for `PhantomPinned` field.
 
   ```rust
-  use pin_project::pin_project;
-  use std::marker::PhantomPinned;
   #[pin_project]
   struct Struct<T, U> {
       field: T,
@@ -163,17 +263,17 @@
   }
   ```
 
-  *[Note: This raises the minimum supported Rust version of this crate from rustc 1.33 to rustc 1.34.](https://github.com/taiki-e/pin-project/pull/219#pullrequestreview-408644187)*
+  *[Note: This raises the minimum supported Rust version of this crate from Rust 1.33 to Rust 1.34.](https://github.com/taiki-e/pin-project/pull/219#pullrequestreview-408644187)*
 
-* [Fixed an issue where duplicate `#[project]` attributes were ignored.][218]
+- [Fixed an issue where duplicate `#[project]` attributes were ignored.][218]
 
-* [Suppress `single_use_lifetimes` lint in generated code.][217]
+- [Suppress `single_use_lifetimes` lint in generated code.][217]
 
-* [Support overlapping lifetime names in HRTB.][217]
+- [Support overlapping lifetime names in HRTB.][217]
 
-* [Hide generated items from --document-private-items.][211] See [#211][211] for details.
+- [Hide generated items from --document-private-items.][211] See [#211][211] for details.
 
-* Documentation improvements.
+- Documentation improvements.
 
 [211]: https://github.com/taiki-e/pin-project/pull/211
 [217]: https://github.com/taiki-e/pin-project/pull/217
@@ -182,39 +282,41 @@
 
 ## [0.4.13] - 2020-05-07
 
-* [Fixed a regression in 0.4.11.][207]
+- [Fixed a regression in 0.4.11.][207]
 
   Changes from [0.4.10](https://github.com/taiki-e/pin-project/releases/tag/v0.4.10) and [0.4.12](https://github.com/taiki-e/pin-project/releases/tag/v0.4.12):
 
-  * [Fixed an issue that `#[project]` on non-statement expression does not work without unstable features.][197]
+  - [Fixed an issue that `#[project]` on non-statement expression does not work without unstable features.][197]
 
-  * [Support overwriting the name of core crate.][199]
+  - [Support overwriting the name of core crate.][199]
 
-  * [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.][200]
+  - [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.][200]
 
-  * Documentation improvements.
+  - Documentation improvements.
 
-  * Diagnostic improvements.
+  - Diagnostic improvements.
 
 [207]: https://github.com/taiki-e/pin-project/pull/207
 
 ## [0.4.12] - 2020-05-07
 
-* A release to avoid [a regression in 0.4.11][206]. No code changes from [0.4.10](https://github.com/taiki-e/pin-project/releases/tag/v0.4.10).
+- A release to avoid [a regression in 0.4.11][206]. No code changes from [0.4.10](https://github.com/taiki-e/pin-project/releases/tag/v0.4.10).
 
 [206]: https://github.com/taiki-e/pin-project/issues/206
 
-## [0.4.11] - 2020-05-07 - YANKED
+## [0.4.11] - 2020-05-07
 
-* [Fixed an issue that `#[project]` on non-statement expression does not work without unstable features.][197]
+**Note: This release has been yanked.** See [#206][206] for details.
 
-* [Support overwriting the name of core crate.][199]
+- [Fixed an issue that `#[project]` on non-statement expression does not work without unstable features.][197]
 
-* [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.][200]
+- [Support overwriting the name of core crate.][199]
 
-* Documentation improvements.
+- [Suppress `clippy::needless_pass_by_value` lint in generated code of `#[pinned_drop]`.][200]
 
-* Diagnostic improvements.
+- Documentation improvements.
+
+- Diagnostic improvements.
 
 [197]: https://github.com/taiki-e/pin-project/pull/197
 [199]: https://github.com/taiki-e/pin-project/pull/199
@@ -222,13 +324,13 @@
 
 ## [0.4.10] - 2020-05-04
 
-* [Added `project_replace` method and `#[project_replace]` attribute.][194]
+- [Added `project_replace` method and `#[project_replace]` attribute.][194]
   `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]
+- [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.
+- [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
@@ -236,11 +338,11 @@
 
 ## [0.4.9] - 2020-04-14
 
-* [Fixed lifetime inference error when associated types are used in fields.][188]
+- [Fixed lifetime inference error when associated types are used in fields.][188]
 
-* [Fixed compile error with tuple structs with `where` clauses.][186]
+- [Fixed compile error with tuple structs with `where` clauses.][186]
 
-* [`#[project]` attribute can now be used for `if let` expressions.][181]
+- [`#[project]` attribute can now be used for `if let` expressions.][181]
 
 [181]: https://github.com/taiki-e/pin-project/pull/181
 [186]: https://github.com/taiki-e/pin-project/pull/186
@@ -248,95 +350,104 @@
 
 ## [0.4.8] - 2020-01-27
 
-* [Ensured that users cannot implement `PinnedDrop` without proper attribute argument.][180]
+- [Ensured that users cannot implement `PinnedDrop` without proper attribute argument.][180]
 
-* [Fixed use of `Self` in expression position inside `#[pinned_drop]` impl.][177]
+- [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
 
-* [Fixed support for lifetime bounds.][176]
+- [Fixed support for lifetime bounds.][176]
 
 [176]: https://github.com/taiki-e/pin-project/pull/176
 
 ## [0.4.6] - 2019-11-20
 
-* [Fixed compile error when there is `Self` in the where clause.][169]
+- [Fixed compile error when there is `Self` in the where clause.][169]
 
 [169]: https://github.com/taiki-e/pin-project/pull/169
 
 ## [0.4.5] - 2019-10-21
 
-* [Fixed compile error with `dyn` types.][158]
+- [Fixed compile error with `dyn` types.][158]
 
 [158]: https://github.com/taiki-e/pin-project/pull/158
 
 ## [0.4.4] - 2019-10-17
 
-* [Fixed an issue where `PinnedDrop` implementations can call unsafe code without an unsafe block.][149]
+- [Fixed an issue where `PinnedDrop` implementations can call unsafe code without an unsafe block.][149]
 
 [149]: https://github.com/taiki-e/pin-project/pull/149
 
-## [0.4.3] - 2019-10-15 - YANKED
+## [0.4.3] - 2019-10-15
 
-* [`#[pin_project]` can now interoperate with `#[cfg_attr()]`.][135]
+**Note: This release has been yanked.** See [#148] for details.
 
-* [`#[pin_project]` can now interoperate with `#[cfg()]` on tuple structs and tuple variants.][135]
+- [`#[pin_project]` can now interoperate with `#[cfg_attr()]`.][135]
 
-* [Fixed support for DSTs(Dynamically Sized Types) on `#[pin_project(UnsafeUnpin)]`][120]
+- [`#[pin_project]` can now interoperate with `#[cfg()]` on tuple structs and tuple variants.][135]
 
-* Diagnostic improvements.
+- [Fixed support for DSTs(Dynamically Sized Types) on `#[pin_project(UnsafeUnpin)]`][120]
 
+- Diagnostic improvements.
+
+[#148]: https://github.com/taiki-e/pin-project/pull/148
 [120]: https://github.com/taiki-e/pin-project/pull/120
 [135]: https://github.com/taiki-e/pin-project/pull/135
 
-## [0.4.2] - 2019-09-29 - YANKED
+## [0.4.2] - 2019-09-29
 
-* [Fixed support for DSTs(Dynamically Sized Types).][113]
+**Note: This release has been yanked.** See [#148] for details.
+
+- [Fixed support for DSTs(Dynamically Sized Types).][113]
 
 [113]: https://github.com/taiki-e/pin-project/pull/113
 
-## [0.4.1] - 2019-09-26 - YANKED
+## [0.4.1] - 2019-09-26
 
-* [Fixed an issue that caused an error when using `#[pin_project]` on a type that has `#[pin]` + `!Unpin` field with no generics or lifetime.][111]
+**Note: This release has been yanked.** See [#148] for details.
+
+- [Fixed an issue that caused an error when using `#[pin_project]` on a type that has `#[pin]` + `!Unpin` field with no generics or lifetime.][111]
 
 [111]: https://github.com/taiki-e/pin-project/pull/111
 
-## [0.4.0] - 2019-09-25 - YANKED
+## [0.4.0] - 2019-09-25
 
-* [**Pin projection has become a safe operation.**][18] In the absence of other unsafe code that you write, it is impossible to cause undefined behavior.
+**Note: This release has been yanked.** See [#148] for details.
 
-* `#[unsafe_project]` attribute has been replaced with `#[pin_project]` attribute. ([#18][18], [#33][33])
+- [**Pin projection has become a safe operation.**][18] In the absence of other unsafe code that you write, it is impossible to cause undefined behavior.
 
-* [The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.][18]
+- `#[unsafe_project]` attribute has been replaced with `#[pin_project]` attribute. ([#18][18], [#33][33])
 
-* Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl. ([#18][18], [#33][33], [#86][86])
+- [The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.][18]
 
-* [`Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.][18]
+- Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl. ([#18][18], [#33][33], [#86][86])
 
-* [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
+- [`Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.][18]
 
-* [`#[pin_project]` can now be used for public type with private field types.][53]
+- [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
 
-* [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
+- [`#[pin_project]` can now be used for public type with private field types.][53]
 
-* [Added `project_ref` method to `#[pin_project]` types.][93]
+- [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
 
-* [Added `#[project_ref]` attribute.][93]
+- [Added `project_ref` method to `#[pin_project]` types.][93]
 
-* [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
+- [Added `#[project_ref]` attribute.][93]
 
-* [`#[project]` attribute can now be used for `impl` blocks.][46]
+- [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
 
-* [`#[project]` attribute can now be used for `use` statements.][85]
+- [`#[project]` attribute can now be used for `impl` blocks.][46]
 
-* [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
+- [`#[project]` attribute can now be used for `use` statements.][85]
+
+- [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
 
 Changes since the 0.4.0-beta.1 release:
 
-* [Fixed an issue that caused an error when using `#[pin_project(UnsafeUnpin)]` and not providing a manual `UnsafeUnpin` implementation on a type with no generics or lifetime.][107]
+- [Fixed an issue that caused an error when using `#[pin_project(UnsafeUnpin)]` and not providing a manual `UnsafeUnpin` implementation on a type with no generics or lifetime.][107]
 
 [18]: https://github.com/taiki-e/pin-project/pull/18
 [33]: https://github.com/taiki-e/pin-project/pull/107
@@ -344,17 +455,17 @@
 
 ## [0.4.0-beta.1] - 2019-09-21
 
-* [Changed the argument type of project method back to `self: Pin<&mut Self>`.][90]
+- [Changed the argument type of project method back to `self: Pin<&mut Self>`.][90]
 
-* [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
+- [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
 
-* [Removed "renamed" feature.][100]
+- [Removed "renamed" feature.][100]
 
-* [`#[project]` attribute can now be used for `use` statements.][85]
+- [`#[project]` attribute can now be used for `use` statements.][85]
 
-* [Added `project_ref` method and `#[project_ref]` attribute.][93]
+- [Added `project_ref` method and `#[project_ref]` attribute.][93]
 
-* [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
+- [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
 
 [85]: https://github.com/taiki-e/pin-project/pull/85
 [90]: https://github.com/taiki-e/pin-project/pull/90
@@ -365,7 +476,7 @@
 
 ## [0.4.0-alpha.11] - 2019-09-11
 
-* [Changed #[pinned_drop] to trait implementation.][86]
+- [Changed #[pinned_drop] to trait implementation.][86]
 
   ```rust
   #[pinned_drop]
@@ -376,72 +487,73 @@
   }
   ```
 
-* Added some examples and generated code.
+- Added some examples and generated code.
 
-* Diagnostic improvements.
+- Diagnostic improvements.
 
 [86]: https://github.com/taiki-e/pin-project/pull/86
 
 ## [0.4.0-alpha.10] - 2019-09-07
 
-* [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
+- [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
 
-* Documentation improvements.
+- Documentation improvements.
 
 [77]: https://github.com/taiki-e/pin-project/pull/77
 
 ## [0.4.0-alpha.9] - 2019-09-05
 
-* [Added 'project_into' method to #[pin_project] types][69]. This can be useful when returning a pin projection from a method.
+- [Added 'project_into' method to `#[pin_project]` types][69]. This can be useful when returning a pin projection from a method.
+
   ```rust
   fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
       self.project_into().pinned
   }
   ```
 
-* [Prevented UnpinStruct from appearing in the document by default.][71] See [#71][71] for more details.
+- [Prevented UnpinStruct from appearing in the document by default.][71] See [#71][71] for more details.
 
 [69]: https://github.com/taiki-e/pin-project/pull/69
 [71]: https://github.com/taiki-e/pin-project/pull/69
 
 ## [0.4.0-alpha.8] - 2019-09-03
 
-* [Improved document of generated code.][62]. Also added an option to control the document of generated code. See [#62][62] for more details.
+- [Improved document of generated code.][62]. Also added an option to control the document of generated code. See [#62][62] for more details.
 
-* [Diagnostic improvements.][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
 
-* [Suppress `dead_code` lint in generated types.][57]
+- [Suppress `dead_code` lint in generated types.][57]
 
 [57]: https://github.com/taiki-e/pin-project/pull/57
 
 ## [0.4.0-alpha.6] - 2019-09-01
 
-* [Allowed using `#[pin_project]` type with private field types][53]
+- [Allowed using `#[pin_project]` type with private field types][53]
 
 [53]: https://github.com/taiki-e/pin-project/pull/53
 
 ## [0.4.0-alpha.5] - 2019-08-24
 
-* [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
+- [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
 
 [51]: https://github.com/taiki-e/pin-project/pull/51
 
 ## [0.4.0-alpha.4] - 2019-08-23
 
-* Suppress `clippy::drop_bounds` lint in generated code.
+- Suppress `clippy::drop_bounds` lint in generated code.
 
 ## [0.4.0-alpha.3] - 2019-08-23
 
-* [Changed `project` method generated by `#[pin_project]` attribute to take an `&mut Pin<&mut Self>` argument.][47]
+- [Changed `project` method generated by `#[pin_project]` attribute to take an `&mut Pin<&mut Self>` argument.][47]
 
-* [`#[project]` attribute can now be used for impl blocks.][46]
+- [`#[project]` attribute can now be used for impl blocks.][46]
 
-* [`#[pin_project]` attribute can now detect that the type used does not have its own drop implementation without actually implementing drop.][48] This removed some restrictions.
+- [`#[pin_project]` attribute can now detect that the type used does not have its own drop implementation without actually implementing drop.][48] This removed some restrictions.
 
 [46]: https://github.com/taiki-e/pin-project/pull/46
 [47]: https://github.com/taiki-e/pin-project/pull/47
@@ -449,21 +561,21 @@
 
 ## [0.4.0-alpha.2] - 2019-08-13
 
-* Updated `proc-macro2`, `syn`, and `quote` to 1.0.
+- Updated `proc-macro2`, `syn`, and `quote` to 1.0.
 
 ## [0.4.0-alpha.1] - 2019-08-11
 
-* **Pin projection has become a safe operation.**
+- **Pin projection has become a safe operation.**
 
-* `#[unsafe_project]` has been replaced with `#[pin_project]`.
+- `#[unsafe_project]` has been replaced with `#[pin_project]`.
 
-* The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.
+- The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.
 
-* Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl.
+- Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl.
 
-* `Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.
+- `Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.
 
-* Made `#[project]` attribute disabled by default.
+- Made `#[project]` attribute disabled by default.
 
 See also [tracking issue for 0.4 release][21].
 
@@ -471,89 +583,104 @@
 
 ## [0.3.5] - 2019-08-14
 
-* Updated `proc-macro2`, `syn`, and `quote` to 1.0.
+- Updated `proc-macro2`, `syn`, and `quote` to 1.0.
 
 ## [0.3.4] - 2019-07-21
 
-* Diagnostic improvements.
+- Diagnostic improvements.
 
-## [0.3.3] - 2019-07-15 - YANKED
+## [0.3.3] - 2019-07-15
 
-* Diagnostic improvements.
+**Note: This release has been yanked.** See [#16] for details.
+
+- Diagnostic improvements.
+
+[#16]: https://github.com/taiki-e/pin-project/issues/16
 
 ## [0.3.2] - 2019-03-30
 
-* Avoided suffixes on tuple index.
+- Avoided suffixes on tuple index.
 
 ## [0.3.1] - 2019-03-02
 
-* Documentation improvements.
+- Documentation improvements.
 
-* Updated minimum `syn` version to 0.15.22.
+- Updated minimum `syn` version to 0.15.22.
 
 ## [0.3.0] - 2019-02-20
 
-* Removed `unsafe_fields` attribute.
+- Removed `unsafe_fields` attribute.
 
-* Removed `unsafe_variants` attribute.
+- Removed `unsafe_variants` attribute.
 
 ## [0.2.2] - 2019-02-20
 
-* Fixed a bug that generates incorrect code for the some structures with trait bounds on type generics.
+- Fixed a bug that generates incorrect code for the some structures with trait bounds on type generics.
 
 ## [0.2.1] - 2019-02-20
 
-* Fixed a bug that generates incorrect code for the structures with where clause and associated type fields.
+- Fixed a bug that generates incorrect code for the structures with where clause and associated type fields.
 
 ## [0.2.0] - 2019-02-11
 
-* Made `unsafe_fields` optional.
+- Made `unsafe_fields` optional.
 
-* Documentation improvements.
+- Documentation improvements.
 
 ## [0.1.8] - 2019-02-02
 
-* Added the feature to create projected enums to `unsafe_project`.
+- Added the feature to create projected enums to `unsafe_project`.
 
-* Added `project` attribute to support pattern matching.
+- Added `project` attribute to support pattern matching.
 
 ## [0.1.7] - 2019-01-19
 
-* Fixed documentation.
+- Fixed documentation.
 
 ## [0.1.6] - 2019-01-19
 
-* `unsafe_fields` can now opt-out.
+- `unsafe_fields` can now opt-out.
 
-* Added `unsafe_variants` attribute. This attribute is available if pin-project is built with the "unsafe_variants" feature.
+- Added `unsafe_variants` attribute. This attribute is available if pin-project is built with the "unsafe_variants" feature.
 
 ## [0.1.5] - 2019-01-17
 
-* Added support for tuple struct to `unsafe_project`.
+- Added support for tuple struct to `unsafe_project`.
 
 ## [0.1.4] - 2019-01-12
 
-* Added options for automatically implementing `Unpin` to both `unsafe_project` and `unsafe_fields`.
+- Added options for automatically implementing `Unpin` to both `unsafe_project` and `unsafe_fields`.
 
 ## [0.1.3] - 2019-01-11
 
-* Fixed dependencies.
+- Fixed dependencies.
 
-* Added `unsafe_fields` attribute.
+- Added `unsafe_fields` attribute.
 
 ## [0.1.2] - 2019-01-09
 
-* Documentation improvements.
+- Documentation improvements.
 
 ## [0.1.1] - 2019-01-08
 
-* Renamed from `unsafe_pin_project` to `unsafe_project`.
+- Renamed from `unsafe_pin_project` to `unsafe_project`.
 
-## [0.1.0] - 2019-01-08 - YANKED
+## [0.1.0] - 2019-01-08
+
+**Note: This release has been yanked.**
 
 Initial release
 
-[Unreleased]: https://github.com/taiki-e/pin-project/compare/v0.4.23...HEAD
+[Unreleased]: https://github.com/taiki-e/pin-project/compare/v1.0.3...HEAD
+[1.0.3]: https://github.com/taiki-e/pin-project/compare/v1.0.2...v1.0.3
+[1.0.2]: https://github.com/taiki-e/pin-project/compare/v1.0.1...v1.0.2
+[1.0.1]: https://github.com/taiki-e/pin-project/compare/v1.0.0...v1.0.1
+[1.0.0]: https://github.com/taiki-e/pin-project/compare/v1.0.0-alpha.1...v1.0.0
+[1.0.0-alpha.1]: https://github.com/taiki-e/pin-project/compare/v0.4.23...v1.0.0-alpha.1
+[0.4.27]: https://github.com/taiki-e/pin-project/compare/v0.4.26...v0.4.27
+[0.4.26]: https://github.com/taiki-e/pin-project/compare/v0.4.25...v0.4.26
+[0.4.25]: https://github.com/taiki-e/pin-project/compare/v0.4.24...v0.4.25
+[0.4.24]: https://github.com/taiki-e/pin-project/compare/v0.4.23...v0.4.24
 [0.4.23]: https://github.com/taiki-e/pin-project/compare/v0.4.22...v0.4.23
 [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
diff --git a/Cargo.toml b/Cargo.toml
index 997d6fa..79ba823 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,10 +13,10 @@
 [package]
 edition = "2018"
 name = "pin-project"
-version = "0.4.23"
+version = "1.0.3"
 authors = ["Taiki Endo <te316e89@gmail.com>"]
+exclude = ["/.github", "/ci", "/scripts"]
 description = "A crate for safe and ergonomic pin-projection.\n"
-homepage = "https://github.com/taiki-e/pin-project"
 documentation = "https://docs.rs/pin-project"
 readme = "README.md"
 keywords = ["pin", "macros", "attribute"]
@@ -26,5 +26,16 @@
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
 [dependencies.pin-project-internal]
-version = "=0.4.23"
+version = "=1.0.3"
 default-features = false
+[dev-dependencies.rustversion]
+version = "1"
+
+[dev-dependencies.static_assertions]
+version = "1"
+
+[dev-dependencies.tempfile]
+version = "3"
+
+[dev-dependencies.trybuild]
+version = "1"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 1f3ae36..401635c 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,15 +1,15 @@
 [package]
 name = "pin-project"
-version = "0.4.23"
+version = "1.0.3"
 authors = ["Taiki Endo <te316e89@gmail.com>"]
 edition = "2018"
 license = "Apache-2.0 OR MIT"
 repository = "https://github.com/taiki-e/pin-project"
-homepage = "https://github.com/taiki-e/pin-project"
 documentation = "https://docs.rs/pin-project"
 keywords = ["pin", "macros", "attribute"]
 categories = ["no-std", "rust-patterns"]
 readme = "README.md"
+exclude = ["/.github", "/ci", "/scripts"]
 description = """
 A crate for safe and ergonomic pin-projection.
 """
@@ -20,7 +20,7 @@
 [workspace]
 members = [
     "pin-project-internal",
-    "tests/ui/auxiliary",
+    "tests/auxiliary/macro",
     "tests/doc",
     "tests/expand",
     "tests/no-core",
@@ -29,5 +29,11 @@
 ]
 
 [dependencies]
-pin-project-internal = { version = "=0.4.23", path = "pin-project-internal", default-features = false }
+pin-project-internal = { version = "=1.0.3", path = "pin-project-internal", default-features = false }
 
+[dev-dependencies]
+pin-project-auxiliary-macro = { path = "tests/auxiliary/macro" }
+rustversion = "1"
+static_assertions = "1"
+tempfile = "3"
+trybuild = "1"
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
index d645695..f433b1a 100644
--- a/LICENSE-APACHE
+++ b/LICENSE-APACHE
@@ -175,28 +175,3 @@
       of your accepting any such warranty or additional liability.
 
    END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/METADATA b/METADATA
index 12bc110..b15e8a5 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/pin-project/pin-project-0.4.23.crate"
+    value: "https://static.crates.io/crates/pin-project/pin-project-1.0.3.crate"
   }
-  version: "0.4.23"
+  version: "1.0.3"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2020
-    month: 7
-    day: 27
+    year: 2021
+    month: 1
+    day: 5
   }
 }
diff --git a/README.md b/README.md
index caee4d3..e98bff2 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,10 @@
 # pin-project
 
-[![crates-badge]][crates-url]
-[![docs-badge]][docs-url]
-[![license-badge]][license]
-[![rustc-badge]][rustc-url]
-
-[crates-badge]: https://img.shields.io/crates/v/pin-project.svg
-[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/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
+[![crates.io](https://img.shields.io/crates/v/pin-project.svg?style=flat-square&logo=rust)](https://crates.io/crates/pin-project)
+[![docs.rs](https://img.shields.io/badge/docs.rs-pin--project-blue?style=flat-square)](https://docs.rs/pin-project)
+[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue.svg?style=flat-square)](#license)
+[![rustc](https://img.shields.io/badge/rustc-1.37+-blue.svg?style=flat-square)](https://www.rust-lang.org)
+[![build status](https://img.shields.io/github/workflow/status/taiki-e/pin-project/CI/master?style=flat-square)](https://github.com/taiki-e/pin-project/actions?query=workflow%3ACI+branch%3Amaster)
 
 A crate for safe and ergonomic [pin-projection].
 
@@ -22,10 +14,10 @@
 
 ```toml
 [dependencies]
-pin-project = "0.4"
+pin-project = "1"
 ```
 
-The current pin-project requires Rust 1.34 or later.
+*Compiler support: requires rustc 1.37+*
 
 ## Examples
 
@@ -54,29 +46,55 @@
 
 [*code like this will be generated*][struct-default-expanded]
 
-See [documentation][docs-url] for more details, and
+To use `#[pin_project]` on enums, you need to name the projection type
+returned from the method.
+
+```rust
+use pin_project::pin_project;
+use std::pin::Pin;
+
+#[pin_project(project = EnumProj)]
+enum Enum<T, U> {
+    Pinned(#[pin] T),
+    Unpinned(U),
+}
+
+impl<T, U> Enum<T, U> {
+    fn method(self: Pin<&mut Self>) {
+        match self.project() {
+            EnumProj::Pinned(x) => {
+                let _: Pin<&mut T> = x;
+            }
+            EnumProj::Unpinned(y) => {
+                let _: &mut U = y;
+            }
+        }
+    }
+}
+```
+
+[*code like this will be generated*][enum-default-expanded]
+
+See [documentation](https://docs.rs/pin-project) 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
+[`pin_project`]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html
+[enum-default-expanded]: examples/enum-default-expanded.rs
 [examples]: examples/README.md
-[pin-projection]: https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning
+[pin-projection]: https://doc.rust-lang.org/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]: A lightweight version of pin-project written with declarative macros.
 
 [pin-project-lite]: https://github.com/taiki-e/pin-project-lite
 
 ## License
 
-Licensed under either of
+Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or
+[MIT license](LICENSE-MIT) at your option.
 
-* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
-* MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
-
-at your option.
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..7d1919a
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,12 @@
+// Generated by cargo2android.py for tests in Android.bp
+{
+  "presubmit": [
+    {
+      "host": true,
+      "name": "futures-util_host_test_src_lib"
+    },
+    {
+      "name": "futures-util_device_test_src_lib"
+    }
+  ]
+}
diff --git a/ci.sh b/ci.sh
deleted file mode 100644
index 9c82699..0000000
--- a/ci.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-# A script to run a simplified version of the checks done by CI.
-#
-# Usage
-#
-# ```sh
-# . ./ci.sh
-# ```
-
-echo "Running 'cargo fmt'"
-cargo +nightly fmt --all
-
-echo "Running 'cargo clippy'"
-cargo +nightly clippy --all --all-features --all-targets
-
-echo "Running 'cargo test'"
-TRYBUILD=overwrite cargo +nightly test --all --all-features --exclude expandtest
-
-echo "Running 'cargo doc'"
-cargo +nightly doc --no-deps --all --all-features
-
-echo "Running 'expandtest'"
-# See also https://docs.rs/macrotest/1/macrotest/#updating-expandedrs
-# rm **/*.expanded.rs
-cargo +nightly test --manifest-path tests/expand/Cargo.toml
diff --git a/ci/check-minimal-versions.sh b/ci/check-minimal-versions.sh
deleted file mode 100644
index 6152c15..0000000
--- a/ci/check-minimal-versions.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-# Check all public crates with minimal version dependencies.
-#
-# 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
-# * features 2.0: https://github.com/rust-lang/cargo/issues/8088
-
-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
deleted file mode 100644
index 9aaa5ce..0000000
--- a/ci/install-component.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-component="${1}"
-
-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
-    target=$(curl -sSf "https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/${component}")
-    echo "'${component}' is unavailable on the default toolchain, use the toolchain 'nightly-${target}' instead"
-
-    . ci/install-rust.sh "nightly-${target}"
-
-    rustup component add "${component}"
-fi
-
-case "${component}" in
-    rustfmt) "${component}" -V ;;
-    *) cargo "${component}" -V ;;
-esac
diff --git a/ci/install-rust.sh b/ci/install-rust.sh
deleted file mode 100644
index b6625b6..0000000
--- a/ci/install-rust.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-toolchain="${1:-nightly}"
-
-rustup set profile minimal
-rustup update "${toolchain}" --no-self-update
-rustup default "${toolchain}"
-
-rustup -V
-rustc -V
-cargo -V
diff --git a/examples/README.md b/examples/README.md
index 94f49b5..9324dc6 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -2,34 +2,38 @@
 
 ### Basic usage of `#[pin_project]` on structs
 
-  * [example](struct-default.rs)
-  * [generated code](struct-default-expanded.rs)
+- [example](struct-default.rs)
+- [generated code](struct-default-expanded.rs)
 
 ### Basic usage of `#[pin_project]` on enums
 
-  * [example](enum-default.rs)
-  * [generated code](enum-default-expanded.rs)
+- [example](enum-default.rs)
+- [generated code](enum-default-expanded.rs)
 
 ### Manual implementation of `Unpin` by `UnsafeUnpin`
 
-  * [example](unsafe_unpin.rs)
-  * [generated code](unsafe_unpin-expanded.rs)
-  * [`UnsafeUnpin` documentation](https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html)
+- [example](unsafe_unpin.rs)
+- [generated code](unsafe_unpin-expanded.rs)
+- [`UnsafeUnpin` documentation](https://docs.rs/pin-project/1/pin_project/trait.UnsafeUnpin.html)
 
 ### Manual implementation of `Drop` by `#[pinned_drop]`
 
-  * [example](pinned_drop.rs)
-  * [generated code](pinned_drop-expanded.rs)
-  * [`#[pinned_drop]` documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pinned_drop.html)
+- [example](pinned_drop.rs)
+- [generated code](pinned_drop-expanded.rs)
+- [`#[pinned_drop]` documentation](https://docs.rs/pin-project/1/pin_project/attr.pinned_drop.html)
 
 ### `project_replace()` method
 
-  * [example](project_replace.rs)
-  * [generated code](project_replace-expanded.rs)
-  * [`project_replace()` documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#project_replace)
+- [example](project_replace.rs)
+- [generated code](project_replace-expanded.rs)
+- [`project_replace()` documentation](https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#project_replace)
 
 ### Ensure `!Unpin` by `#[pin_project(!Unpin)]`
 
-  * [example](not_unpin.rs)
-  * [generated code](not_unpin-expanded.rs)
-  * [`!Unpin` documentation](https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#unpin)
+- [example](not_unpin.rs)
+- [generated code](not_unpin-expanded.rs)
+- [`!Unpin` documentation](https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin)
+
+Note: These generated code examples are the little simplified version of the
+actual generated code. See [expansion tests](../tests/expand/README.md) if you
+want to see the exact version of the actual generated code.
diff --git a/examples/enum-default-expanded.rs b/examples/enum-default-expanded.rs
index cea3ae5..2153592 100644
--- a/examples/enum-default-expanded.rs
+++ b/examples/enum-default-expanded.rs
@@ -14,20 +14,17 @@
 // fn main() {}
 // ```
 
-#![allow(dead_code, unused_imports, unused_parens)]
-#![allow(clippy::just_underscores_and_digits)]
+#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
+#![allow(clippy::needless_lifetimes, clippy::just_underscores_and_digits)]
 
 use pin_project::pin_project;
 
+// #[pin_project(project = EnumProj)]
 enum Enum<T, U> {
     Pinned(/* #[pin] */ T),
     Unpinned(U),
 }
 
-#[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,
@@ -35,45 +32,23 @@
     Pinned(::pin_project::__private::Pin<&'pin mut (T)>),
     Unpinned(&'pin mut (U)),
 }
-#[doc(hidden)]
-#[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::__private::Pin<&'pin (T)>),
-    Unpinned(&'pin (U)),
-}
 
-#[doc(hidden)]
-#[allow(non_upper_case_globals)]
-#[allow(single_use_lifetimes)]
-#[allow(clippy::used_underscore_binding)]
 const _: () = {
+    // When `#[pin_project]` is used on enums, only named projection types and
+    // methods are generated because there is no way to access variants of
+    // projected types without naming it.
+    // (When `#[pin_project]` is used on structs, both methods are always generated.)
+
     impl<T, U> Enum<T, U> {
         fn project<'pin>(
             self: ::pin_project::__private::Pin<&'pin mut Self>,
         ) -> EnumProj<'pin, T, U> {
             unsafe {
                 match self.get_unchecked_mut() {
-                    Enum::Pinned(_0) => {
+                    Self::Pinned(_0) => {
                         EnumProj::Pinned(::pin_project::__private::Pin::new_unchecked(_0))
                     }
-                    Enum::Unpinned(_0) => EnumProj::Unpinned(_0),
-                }
-            }
-        }
-        fn project_ref<'pin>(
-            self: ::pin_project::__private::Pin<&'pin Self>,
-        ) -> __EnumProjectionRef<'pin, T, U> {
-            unsafe {
-                match self.get_ref() {
-                    Enum::Pinned(_0) => __EnumProjectionRef::Pinned(
-                        ::pin_project::__private::Pin::new_unchecked(_0),
-                    ),
-                    Enum::Unpinned(_0) => __EnumProjectionRef::Unpinned(_0),
+                    Self::Unpinned(_0) => EnumProj::Unpinned(_0),
                 }
             }
         }
@@ -94,15 +69,23 @@
         __Enum<'pin, T, U>: ::pin_project::__private::Unpin
     {
     }
-    unsafe impl<T, U> ::pin_project::UnsafeUnpin for Enum<T, U> {}
+    // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
+    #[doc(hidden)]
+    unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Enum<T, U> where
+        __Enum<'pin, T, U>: ::pin_project::__private::Unpin
+    {
+    }
 
     // Ensure that enum does not implement `Drop`.
     //
     // See ./struct-default-expanded.rs for details.
     trait EnumMustNotImplDrop {}
-    #[allow(clippy::drop_bounds)]
+    #[allow(clippy::drop_bounds, drop_bounds)]
     impl<T: ::pin_project::__private::Drop> EnumMustNotImplDrop for T {}
     impl<T, U> EnumMustNotImplDrop for Enum<T, U> {}
+    // A dummy impl of `PinnedDrop`, to ensure that users don't accidentally
+    // write a non-functional `PinnedDrop` impls.
+    #[doc(hidden)]
     impl<T, U> ::pin_project::__private::PinnedDrop for Enum<T, U> {
         unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
diff --git a/examples/not_unpin-expanded.rs b/examples/not_unpin-expanded.rs
index fdfe5a2..aa5209d 100644
--- a/examples/not_unpin-expanded.rs
+++ b/examples/not_unpin-expanded.rs
@@ -18,46 +18,34 @@
 // }
 // ```
 
-#![allow(dead_code, unused_imports, unused_parens)]
-#![allow(clippy::no_effect)]
+#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
+#![allow(clippy::needless_lifetimes)]
 
 use pin_project::pin_project;
 
+// #[pin_project(!Unpin)]
 pub struct Struct<T, U> {
     // #[pin]
     pinned: T,
     unpinned: U,
 }
 
-#[doc(hidden)]
-#[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::__private::Pin<&'pin mut (T)>,
-    unpinned: &'pin mut (U),
-}
-#[doc(hidden)]
-#[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::__private::Pin<&'pin (T)>,
-    unpinned: &'pin (U),
-}
-
-#[doc(hidden)]
-#[allow(non_upper_case_globals)]
-#[allow(single_use_lifetimes)]
-#[allow(clippy::used_underscore_binding)]
 const _: () = {
+    pub(crate) struct __StructProjection<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
+        unpinned: &'pin mut (U),
+    }
+    pub(crate) struct __StructProjectionRef<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin (T)>,
+        unpinned: &'pin (U),
+    }
+
     impl<T, U> Struct<T, U> {
         pub(crate) fn project<'pin>(
             self: ::pin_project::__private::Pin<&'pin mut Self>,
@@ -83,6 +71,17 @@
         }
     }
 
+    // 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.
+    #[forbid(safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+
     // Create `Unpin` impl that has trivial `Unpin` bounds.
     //
     // See https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282
@@ -98,29 +97,26 @@
     // 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> {}
+    #[doc(hidden)]
+    unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
+        ::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>:
+            ::pin_project::__private::Unpin
+    {
+    }
 
     // Ensure that struct does not implement `Drop`.
     //
     // See ./struct-default-expanded.rs for details.
     trait StructMustNotImplDrop {}
-    #[allow(clippy::drop_bounds)]
+    #[allow(clippy::drop_bounds, drop_bounds)]
     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.
+    #[doc(hidden)]
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
         unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
-
-    // 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.
-    #[deny(safe_packed_borrows)]
-    fn __assert_not_repr_packed<T, U>(val: &Struct<T, U>) {
-        &val.pinned;
-        &val.unpinned;
-    }
 };
 
 fn main() {
diff --git a/examples/pinned_drop-expanded.rs b/examples/pinned_drop-expanded.rs
index 8f295e9..ad22c0b 100644
--- a/examples/pinned_drop-expanded.rs
+++ b/examples/pinned_drop-expanded.rs
@@ -21,47 +21,35 @@
 // fn main() {}
 // ```
 
-#![allow(dead_code, unused_imports, unused_parens)]
-#![allow(clippy::no_effect)]
+#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
+#![allow(clippy::needless_lifetimes)]
 
 use pin_project::{pin_project, pinned_drop};
 use std::pin::Pin;
 
+// #[pin_project(PinnedDrop)]
 pub struct Struct<'a, T> {
     was_dropped: &'a mut bool,
     // #[pin]
     field: T,
 }
 
-#[doc(hidden)]
-#[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::__private::Pin<&'pin mut (T)>,
-}
-#[doc(hidden)]
-#[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::__private::Pin<&'pin (T)>,
-}
-
-#[doc(hidden)]
-#[allow(non_upper_case_globals)]
-#[allow(single_use_lifetimes)]
-#[allow(clippy::used_underscore_binding)]
 const _: () = {
+    pub(crate) struct __StructProjection<'pin, 'a, T>
+    where
+        Struct<'a, T>: 'pin,
+    {
+        was_dropped: &'pin mut (&'a mut bool),
+        field: ::pin_project::__private::Pin<&'pin mut (T)>,
+    }
+    pub(crate) struct __StructProjectionRef<'pin, 'a, T>
+    where
+        Struct<'a, T>: 'pin,
+    {
+        was_dropped: &'pin (&'a mut bool),
+        field: ::pin_project::__private::Pin<&'pin (T)>,
+    }
+
     impl<'a, T> Struct<'a, T> {
         pub(crate) fn project<'pin>(
             self: ::pin_project::__private::Pin<&'pin mut Self>,
@@ -87,6 +75,17 @@
         }
     }
 
+    // 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.
+    #[forbid(safe_packed_borrows)]
+    fn __assert_not_repr_packed<'a, T>(this: &Struct<'a, T>) {
+        let _ = &this.was_dropped;
+        let _ = &this.field;
+    }
+
     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
@@ -114,17 +113,11 @@
         __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.
-    //
-    // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
-    // for details.
-    #[deny(safe_packed_borrows)]
-    fn __assert_not_repr_packed<'a, T>(val: &Struct<'a, T>) {
-        &val.was_dropped;
-        &val.field;
+    // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
+    #[doc(hidden)]
+    unsafe impl<'pin, 'a, T> ::pin_project::UnsafeUnpin for Struct<'a, T> where
+        __Struct<'pin, 'a, T>: ::pin_project::__private::Unpin
+    {
     }
 };
 
diff --git a/examples/project_replace-expanded.rs b/examples/project_replace-expanded.rs
index 16f47b7..ec00d41 100644
--- a/examples/project_replace-expanded.rs
+++ b/examples/project_replace-expanded.rs
@@ -15,54 +15,38 @@
 // fn main() {}
 // ```
 
-#![allow(dead_code, unused_imports, unused_parens)]
-#![allow(clippy::no_effect)]
+#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
+#![allow(clippy::needless_lifetimes)]
 
 use pin_project::pin_project;
 
+// #[pin_project(project_replace)]
 struct Struct<T, U> {
     // #[pin]
     pinned: T,
     unpinned: U,
 }
 
-#[doc(hidden)]
-#[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::__private::Pin<&'pin mut (T)>,
-    unpinned: &'pin mut (U),
-}
-#[doc(hidden)]
-#[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::__private::Pin<&'pin (T)>,
-    unpinned: &'pin (U),
-}
-#[doc(hidden)]
-#[allow(dead_code)]
-#[allow(unreachable_pub)]
-#[allow(single_use_lifetimes)]
-struct __StructProjectionOwned<T, U> {
-    pinned: ::pin_project::__private::PhantomData<T>,
-    unpinned: U,
-}
-
-#[doc(hidden)]
-#[allow(non_upper_case_globals)]
-#[allow(single_use_lifetimes)]
-#[allow(clippy::used_underscore_binding)]
 const _: () = {
+    struct __StructProjection<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
+        unpinned: &'pin mut (U),
+    }
+    struct __StructProjectionRef<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin (T)>,
+        unpinned: &'pin (U),
+    }
+    struct __StructProjectionOwned<T, U> {
+        pinned: ::pin_project::__private::PhantomData<T>,
+        unpinned: U,
+    }
+
     impl<T, U> Struct<T, U> {
         fn project<'pin>(
             self: ::pin_project::__private::Pin<&'pin mut Self>,
@@ -122,6 +106,17 @@
         }
     }
 
+    // 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.
+    #[forbid(safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+
     // Automatically create the appropriate conditional `Unpin` implementation.
     //
     // See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
@@ -137,29 +132,26 @@
         __Struct<'pin, T, U>: ::pin_project::__private::Unpin
     {
     }
-    unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> {}
+    // A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
+    #[doc(hidden)]
+    unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
+        __Struct<'pin, T, U>: ::pin_project::__private::Unpin
+    {
+    }
 
     // Ensure that struct does not implement `Drop`.
     //
     // See ./struct-default-expanded.rs for details.
     trait StructMustNotImplDrop {}
-    #[allow(clippy::drop_bounds)]
+    #[allow(clippy::drop_bounds, drop_bounds)]
     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.
+    #[doc(hidden)]
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
         unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
-
-    // 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.
-    #[deny(safe_packed_borrows)]
-    fn __assert_not_repr_packed<T, U>(val: &Struct<T, U>) {
-        &val.pinned;
-        &val.unpinned;
-    }
 };
 
 fn main() {}
diff --git a/examples/struct-default-expanded.rs b/examples/struct-default-expanded.rs
index ff160ce..3d0e4ab 100644
--- a/examples/struct-default-expanded.rs
+++ b/examples/struct-default-expanded.rs
@@ -15,46 +15,34 @@
 // fn main() {}
 // ```
 
-#![allow(dead_code, unused_imports, unused_parens)]
-#![allow(clippy::no_effect)]
+#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
+#![allow(clippy::needless_lifetimes)]
 
 use pin_project::pin_project;
 
+// #[pin_project]
 struct Struct<T, U> {
     // #[pin]
     pinned: T,
     unpinned: U,
 }
 
-#[doc(hidden)]
-#[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::__private::Pin<&'pin mut (T)>,
-    unpinned: &'pin mut (U),
-}
-#[doc(hidden)]
-#[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::__private::Pin<&'pin (T)>,
-    unpinned: &'pin (U),
-}
-
-#[doc(hidden)]
-#[allow(non_upper_case_globals)]
-#[allow(single_use_lifetimes)]
-#[allow(clippy::used_underscore_binding)]
 const _: () = {
+    struct __StructProjection<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
+        unpinned: &'pin mut (U),
+    }
+    struct __StructProjectionRef<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin (T)>,
+        unpinned: &'pin (U),
+    }
+
     impl<T, U> Struct<T, U> {
         fn project<'pin>(
             self: ::pin_project::__private::Pin<&'pin mut Self>,
@@ -80,6 +68,26 @@
         }
     }
 
+    // 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
+    // #[forbid(safe_packed_borrows)] makes sure that doing this without
+    // an 'unsafe' block (which we deliberately do not generate)
+    // is a hard error.
+    //
+    // If the struct ends up having #[repr(packed)] applied somehow,
+    // this will generate an (unfriendly) error message. Under all reasonable
+    // circumstances, we'll detect the #[repr(packed)] attribute, and generate
+    // a much nicer error above.
+    //
+    // See https://github.com/taiki-e/pin-project/pull/34 for more details.
+    #[forbid(safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+
     // Automatically create the appropriate conditional `Unpin` implementation.
     //
     // Basically this is equivalent to the following code:
@@ -123,7 +131,11 @@
     // 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> {}
+    #[doc(hidden)]
+    unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
+        __Struct<'pin, T, U>: ::pin_project::__private::Unpin
+    {
+    }
 
     // Ensure that struct does not implement `Drop`.
     //
@@ -131,34 +143,15 @@
     // then apply to your type, causing a compile-time error due to
     // the conflict with the second impl.
     trait StructMustNotImplDrop {}
-    #[allow(clippy::drop_bounds)]
+    #[allow(clippy::drop_bounds, drop_bounds)]
     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.
+    #[doc(hidden)]
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
         unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
-
-    // 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
-    // an 'unsafe' block (which we deliberately do not generate)
-    // is a hard error.
-    //
-    // If the struct ends up having #[repr(packed)] applied somehow,
-    // this will generate an (unfriendly) error message. Under all reasonable
-    // circumstances, we'll detect the #[repr(packed)] attribute, and generate
-    // a much nicer error above.
-    //
-    // See https://github.com/taiki-e/pin-project/pull/34 for more details.
-    #[deny(safe_packed_borrows)]
-    fn __assert_not_repr_packed<T, U>(val: &Struct<T, U>) {
-        &val.pinned;
-        &val.unpinned;
-    }
 };
 
 fn main() {}
diff --git a/examples/unsafe_unpin-expanded.rs b/examples/unsafe_unpin-expanded.rs
index e55b740..2ea1f37 100644
--- a/examples/unsafe_unpin-expanded.rs
+++ b/examples/unsafe_unpin-expanded.rs
@@ -17,46 +17,34 @@
 // fn main() {}
 // ```
 
-#![allow(dead_code, unused_imports, unused_parens)]
-#![allow(clippy::no_effect)]
+#![allow(dead_code, unused_imports, unused_parens, unknown_lints, renamed_and_removed_lints)]
+#![allow(clippy::needless_lifetimes)]
 
 use pin_project::{pin_project, UnsafeUnpin};
 
+// #[pin_project(UnsafeUnpin)]
 pub struct Struct<T, U> {
     // #[pin]
     pinned: T,
     unpinned: U,
 }
 
-#[doc(hidden)]
-#[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::__private::Pin<&'pin mut (T)>,
-    unpinned: &'pin mut (U),
-}
-#[doc(hidden)]
-#[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::__private::Pin<&'pin (T)>,
-    unpinned: &'pin (U),
-}
-
-#[doc(hidden)]
-#[allow(non_upper_case_globals)]
-#[allow(single_use_lifetimes)]
-#[allow(clippy::used_underscore_binding)]
 const _: () = {
+    pub(crate) struct __StructProjection<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin mut (T)>,
+        unpinned: &'pin mut (U),
+    }
+    pub(crate) struct __StructProjectionRef<'pin, T, U>
+    where
+        Struct<T, U>: 'pin,
+    {
+        pinned: ::pin_project::__private::Pin<&'pin (T)>,
+        unpinned: &'pin (U),
+    }
+
     impl<T, U> Struct<T, U> {
         pub(crate) fn project<'pin>(
             self: ::pin_project::__private::Pin<&'pin mut Self>,
@@ -82,6 +70,18 @@
         }
     }
 
+    // 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.
+    #[forbid(safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+
+    // Implement `Unpin` via `UnsafeUnpin`.
     impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
         ::pin_project::__private::Wrapper<'pin, Self>: ::pin_project::UnsafeUnpin
     {
@@ -91,23 +91,15 @@
     //
     // See ./struct-default-expanded.rs for details.
     trait StructMustNotImplDrop {}
-    #[allow(clippy::drop_bounds)]
+    #[allow(clippy::drop_bounds, drop_bounds)]
     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.
+    #[doc(hidden)]
     impl<T, U> ::pin_project::__private::PinnedDrop for Struct<T, U> {
         unsafe fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
     }
-
-    // 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.
-    #[deny(safe_packed_borrows)]
-    fn __assert_not_repr_packed<T, U>(val: &Struct<T, U>) {
-        &val.pinned;
-        &val.unpinned;
-    }
 };
 
 unsafe impl<T: Unpin, U> UnsafeUnpin for Struct<T, U> {}
diff --git a/patches/Android.bp.patch b/patches/Android.bp.patch
new file mode 100644
index 0000000..e0adcd4
--- /dev/null
+++ b/patches/Android.bp.patch
@@ -0,0 +1,15 @@
+diff --git a/Android.bp b/Android.bp
+index 1ed91d5..16df3fc 100644
+--- a/Android.bp
++++ b/Android.bp
+@@ -7,6 +7,10 @@ rust_library {
+     srcs: ["src/lib.rs"],
+     edition: "2018",
+     proc_macros: ["libpin_project_internal"],
++    apex_available: [
++        "//apex_available:platform",
++        "com.android.virt",
++    ],
+ }
+ 
+ // dependent_library ["feature_list"]
diff --git a/patches/std.diff b/patches/std.diff
new file mode 100644
index 0000000..562ddd1
--- /dev/null
+++ b/patches/std.diff
@@ -0,0 +1,14 @@
+diff --git a/src/lib.rs b/src/lib.rs
+index aaa561f..016a0c7 100644
+--- a/src/lib.rs
++++ b/src/lib.rs
+@@ -81,6 +81,9 @@
+ )]
+ #![allow(clippy::needless_doctest_main)]
+ 
++// ANDROID: Use std to allow building as a dylib.
++extern crate std;
++
+ #[doc(inline)]
+ pub use pin_project_internal::pin_project;
+ 
diff --git a/src/lib.rs b/src/lib.rs
index 61d90ea..37e33e6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,24 +27,54 @@
 //!
 //! [*code like this will be generated*][struct-default-expanded]
 //!
+//! To use `#[pin_project]` on enums, you need to name the projection type
+//! returned from the method.
+//!
+//! ```rust
+//! use pin_project::pin_project;
+//! use std::pin::Pin;
+//!
+//! #[pin_project(project = EnumProj)]
+//! enum Enum<T, U> {
+//!     Pinned(#[pin] T),
+//!     Unpinned(U),
+//! }
+//!
+//! impl<T, U> Enum<T, U> {
+//!     fn method(self: Pin<&mut Self>) {
+//!         match self.project() {
+//!             EnumProj::Pinned(x) => {
+//!                 let _: Pin<&mut T> = x;
+//!             }
+//!             EnumProj::Unpinned(y) => {
+//!                 let _: &mut U = y;
+//!             }
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! [*code like this will be generated*][enum-default-expanded]
+//!
 //! 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
+//! [enum-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/enum-default-expanded.rs
+//! [pin-projection]: core::pin#projections-and-structural-pinning
 //! [struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs
 
 #![no_std]
-#![doc(html_root_url = "https://docs.rs/pin-project/0.4.23")]
 #![doc(test(
     no_crate_inject,
-    attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code))
+    attr(
+        deny(warnings, rust_2018_idioms, single_use_lifetimes),
+        allow(dead_code, unused_variables)
+    )
 ))]
-#![warn(missing_docs, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(missing_docs)]
 #![warn(clippy::all, clippy::default_trait_access)]
-// mem::take and #[non_exhaustive] requires Rust 1.40
-#![allow(clippy::mem_replace_with_default, clippy::manual_non_exhaustive)]
 #![allow(clippy::needless_doctest_main)]
 
 // ANDROID: Use std to allow building as a dylib.
@@ -56,25 +86,14 @@
 #[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]`][`pin_project`]
+///
+/// This trait is used in conjunction with the `UnsafeUnpin` argument to
+/// the [`#[pin_project]`][macro@pin_project] attribute.
 ///
 /// The Rust [`Unpin`] trait is safe to implement - by itself,
-/// implementing it cannot lead to undefined behavior. Undefined
-/// behavior can only occur when other unsafe code is used.
+/// implementing it cannot lead to [undefined behavior][undefined-behavior].
+/// Undefined behavior can only occur when other unsafe code is used.
 ///
 /// It turns out that using pin projections, which requires unsafe code,
 /// imposes additional requirements on an [`Unpin`] impl. Normally, all of this
@@ -112,19 +131,19 @@
 /// use pin_project::{pin_project, UnsafeUnpin};
 ///
 /// #[pin_project(UnsafeUnpin)]
-/// struct Foo<K, V> {
+/// struct Struct<K, V> {
 ///     #[pin]
 ///     field_1: K,
 ///     field_2: V,
 /// }
 ///
-/// unsafe impl<K, V> UnsafeUnpin for Foo<K, V> where K: Unpin + Clone {}
+/// unsafe impl<K, V> UnsafeUnpin for Struct<K, V> where K: Unpin + Clone {}
 /// ```
 ///
 /// [`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
+/// [pin-projection]: core::pin#projections-and-structural-pinning
+/// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
 pub unsafe trait UnsafeUnpin {}
 
 // Not public API.
@@ -144,18 +163,26 @@
     #[doc(hidden)]
     pub use pin_project_internal::__PinProjectInternalDerive;
 
+    // An internal trait used for custom implementations of [`Drop`].
+    //
+    // **Do not call or implement this trait directly.**
+    //
+    // # Why this trait is private and `#[pinned_drop]` attribute is needed?
+    //
     // Implementing `PinnedDrop::drop` is safe, but calling it is not safe.
     // This is because destructors can be called multiple times in safe code and
-    // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
+    // [double dropping is unsound][rust-lang/rust#62360].
     //
     // Ideally, it would be desirable to be able to forbid manual calls in
     // the same way as [`Drop::drop`], but the library cannot do it. So, by using
-    // macros and replacing them with private traits, we prevent users from
-    // calling `PinnedDrop::drop`.
+    // macros and replacing them with private traits,
+    // this crate prevent users from calling `PinnedDrop::drop` in safe code.
     //
-    // Users can implement [`Drop`] safely using `#[pinned_drop]` and can drop a
-    // type that implements `PinnedDrop` using the [`drop`] function safely.
-    // **Do not call or implement this trait directly.**
+    // This allows implementing [`Drop`] safely using `#[pinned_drop]`.
+    // Also by using the [`drop`] function just like dropping a type that directly
+    // implements [`Drop`], can drop safely a type that implements `PinnedDrop`.
+    //
+    // [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360
     #[doc(hidden)]
     pub trait PinnedDrop {
         #[doc(hidden)]
@@ -223,7 +250,7 @@
     //
     // See https://github.com/taiki-e/pin-project/pull/53 for more details.
     #[doc(hidden)]
-    pub struct AlwaysUnpin<'a, T: ?Sized>(PhantomData<&'a ()>, PhantomData<T>);
+    pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>);
 
     impl<T> Unpin for AlwaysUnpin<'_, T> {}
 
diff --git a/src/lib.rs.orig b/src/lib.rs.orig
new file mode 100644
index 0000000..b7a20ed
--- /dev/null
+++ b/src/lib.rs.orig
@@ -0,0 +1,281 @@
+//! A crate for safe and ergonomic [pin-projection].
+//!
+//! # Examples
+//!
+//! [`#[pin_project]`][`pin_project`] attribute creates projection types
+//! covering all the fields of struct or enum.
+//!
+//! ```rust
+//! use pin_project::pin_project;
+//! use std::pin::Pin;
+//!
+//! #[pin_project]
+//! struct Struct<T, U> {
+//!     #[pin]
+//!     pinned: T,
+//!     unpinned: U,
+//! }
+//!
+//! impl<T, U> Struct<T, U> {
+//!     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
+//!     }
+//! }
+//! ```
+//!
+//! [*code like this will be generated*][struct-default-expanded]
+//!
+//! To use `#[pin_project]` on enums, you need to name the projection type
+//! returned from the method.
+//!
+//! ```rust
+//! use pin_project::pin_project;
+//! use std::pin::Pin;
+//!
+//! #[pin_project(project = EnumProj)]
+//! enum Enum<T, U> {
+//!     Pinned(#[pin] T),
+//!     Unpinned(U),
+//! }
+//!
+//! impl<T, U> Enum<T, U> {
+//!     fn method(self: Pin<&mut Self>) {
+//!         match self.project() {
+//!             EnumProj::Pinned(x) => {
+//!                 let _: Pin<&mut T> = x;
+//!             }
+//!             EnumProj::Unpinned(y) => {
+//!                 let _: &mut U = y;
+//!             }
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! [*code like this will be generated*][enum-default-expanded]
+//!
+//! See [`#[pin_project]`][`pin_project`] attribute for more details, and
+//! see [examples] directory for more examples and generated code.
+//!
+//! [examples]: https://github.com/taiki-e/pin-project/blob/master/examples/README.md
+//! [enum-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/enum-default-expanded.rs
+//! [pin-projection]: core::pin#projections-and-structural-pinning
+//! [struct-default-expanded]: https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs
+
+#![no_std]
+#![doc(test(
+    no_crate_inject,
+    attr(
+        deny(warnings, rust_2018_idioms, single_use_lifetimes),
+        allow(dead_code, unused_variables)
+    )
+))]
+#![warn(future_incompatible, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(missing_docs)]
+#![warn(clippy::all, clippy::default_trait_access)]
+#![allow(clippy::needless_doctest_main)]
+
+#[doc(inline)]
+pub use pin_project_internal::pin_project;
+
+#[doc(inline)]
+pub use pin_project_internal::pinned_drop;
+
+/// A trait used for custom implementations of [`Unpin`].
+///
+/// This trait is used in conjunction with the `UnsafeUnpin` argument to
+/// the [`#[pin_project]`][macro@pin_project] attribute.
+///
+/// The Rust [`Unpin`] trait is safe to implement - by itself,
+/// implementing it cannot lead to [undefined behavior][undefined-behavior].
+/// Undefined behavior can only occur when other unsafe code is used.
+///
+/// It turns out that using pin projections, which requires unsafe code,
+/// imposes additional requirements on an [`Unpin`] impl. Normally, all of this
+/// unsafety is contained within this crate, ensuring that it's impossible for
+/// you to violate any of the guarantees required by pin projection.
+///
+/// However, things change if you want to provide a custom [`Unpin`] impl
+/// for your `#[pin_project]` type. As stated in [the Rust
+/// 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`] -
+/// this crate will generate an [`Unpin`] impl for your type that 'forwards' to
+/// your `UnsafeUnpin` impl. However, this trait is `unsafe` - since your type
+/// uses structural pinning (otherwise, you wouldn't be using this crate!),
+/// you must be sure that your `UnsafeUnpin` impls follows all of
+/// the requirements for an [`Unpin`] impl of a structurally-pinned type.
+///
+/// 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.
+///
+/// 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
+///
+/// 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};
+///
+/// #[pin_project(UnsafeUnpin)]
+/// struct Struct<K, V> {
+///     #[pin]
+///     field_1: K,
+///     field_2: V,
+/// }
+///
+/// unsafe impl<K, V> UnsafeUnpin for Struct<K, V> where K: Unpin + Clone {}
+/// ```
+///
+/// [`PhantomPinned`]: core::marker::PhantomPinned
+/// [cargo-geiger]: https://github.com/rust-secure-code/cargo-geiger
+/// [pin-projection]: core::pin#projections-and-structural-pinning
+/// [undefined-behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+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;
+
+    #[doc(hidden)]
+    pub use pin_project_internal::__PinProjectInternalDerive;
+
+    // An internal trait used for custom implementations of [`Drop`].
+    //
+    // **Do not call or implement this trait directly.**
+    //
+    // # Why this trait is private and `#[pinned_drop]` attribute is needed?
+    //
+    // Implementing `PinnedDrop::drop` is safe, but calling it is not safe.
+    // This is because destructors can be called multiple times in safe code and
+    // [double dropping is unsound][rust-lang/rust#62360].
+    //
+    // Ideally, it would be desirable to be able to forbid manual calls in
+    // the same way as [`Drop::drop`], but the library cannot do it. So, by using
+    // macros and replacing them with private traits,
+    // this crate prevent users from calling `PinnedDrop::drop` in safe code.
+    //
+    // This allows implementing [`Drop`] safely using `#[pinned_drop]`.
+    // Also by using the [`drop`] function just like dropping a type that directly
+    // implements [`Drop`], can drop safely a type that implements `PinnedDrop`.
+    //
+    // [rust-lang/rust#62360]: https://github.com/rust-lang/rust/pull/62360
+    #[doc(hidden)]
+    pub trait PinnedDrop {
+        #[doc(hidden)]
+        unsafe fn drop(self: Pin<&mut Self>);
+    }
+
+    // This is an internal helper struct used by `pin-project-internal`.
+    // This allows us to force an error if the user tries to provide
+    // a regular `Unpin` impl when they specify the `UnsafeUnpin` argument.
+    // This is why we need Wrapper:
+    //
+    // Supposed we have the following code:
+    //
+    // ```rust
+    // #[pin_project(UnsafeUnpin)]
+    // struct MyStruct<T> {
+    //     #[pin] field: T
+    // }
+    //
+    // 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!
+    //
+    // 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 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.
+    //
+    // 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 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);
+
+    unsafe impl<T: ?Sized> UnsafeUnpin for Wrapper<'_, T> where T: UnsafeUnpin {}
+
+    // This is an internal helper struct used by `pin-project-internal`.
+    //
+    // See https://github.com/taiki-e/pin-project/pull/53 for more details.
+    #[doc(hidden)]
+    pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>);
+
+    impl<T> Unpin for AlwaysUnpin<'_, T> {}
+
+    // This is an internal helper used to ensure a value is dropped.
+    #[doc(hidden)]
+    pub struct UnsafeDropInPlaceGuard<T: ?Sized>(pub *mut T);
+
+    impl<T: ?Sized> Drop for UnsafeDropInPlaceGuard<T> {
+        fn drop(&mut self) {
+            unsafe {
+                ptr::drop_in_place(self.0);
+            }
+        }
+    }
+
+    // This is an internal helper used to ensure a value is overwritten without
+    // its destructor being called.
+    #[doc(hidden)]
+    pub struct UnsafeOverwriteGuard<T> {
+        pub value: ManuallyDrop<T>,
+        pub target: *mut T,
+    }
+
+    impl<T> Drop for UnsafeOverwriteGuard<T> {
+        fn drop(&mut self) {
+            unsafe {
+                ptr::write(self.target, ptr::read(&*self.value));
+            }
+        }
+    }
+}
diff --git a/tests/auxiliary/mod.rs b/tests/auxiliary/mod.rs
new file mode 100644
index 0000000..a0eb7c2
--- /dev/null
+++ b/tests/auxiliary/mod.rs
@@ -0,0 +1,44 @@
+#![allow(dead_code, unused_macros)]
+#![allow(box_pointers, unreachable_pub)]
+#![allow(clippy::restriction)]
+
+use std::{env, fs, path::Path, process::Command};
+use tempfile::Builder;
+
+macro_rules! assert_unpin {
+    ($ty:ty) => {
+        static_assertions::assert_impl_all!($ty: Unpin);
+    };
+}
+macro_rules! assert_not_unpin {
+    ($ty:ty) => {
+        static_assertions::assert_not_impl_all!($ty: Unpin);
+    };
+}
+
+#[rustversion::attr(since(1.46), track_caller)]
+pub fn assert_diff(expected_path: impl AsRef<Path>, actual: impl AsRef<str>) {
+    let actual = actual.as_ref();
+    let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
+    let expected_path = &manifest_dir.join(expected_path);
+    (|| -> Result<(), Box<dyn std::error::Error>> {
+        let expected = fs::read_to_string(expected_path)?;
+        if expected != actual {
+            if env::var_os("CI").is_some() {
+                let outdir = Builder::new().prefix("assert_diff").tempdir()?;
+                let actual_path = &outdir.path().join(expected_path.file_name().unwrap());
+                fs::write(actual_path, actual)?;
+                let status = Command::new("git")
+                    .args(&["--no-pager", "diff", "--no-index", "--"])
+                    .args(&[expected_path, actual_path])
+                    .status()?;
+                assert!(!status.success());
+                panic!("assertion failed");
+            } else {
+                fs::write(expected_path, actual)?;
+            }
+        }
+        Ok(())
+    })()
+    .unwrap_or_else(|e| panic!("{}", e))
+}
diff --git a/tests/cfg.rs b/tests/cfg.rs
index 4133517..2fdcfbb 100644
--- a/tests/cfg.rs
+++ b/tests/cfg.rs
@@ -1,20 +1,20 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 #![allow(dead_code)]
 
-// Refs: https://doc.rust-lang.org/nightly/reference/attributes.html
+// Refs: https://doc.rust-lang.org/reference/attributes.html
+
+#[macro_use]
+mod auxiliary;
 
 use pin_project::pin_project;
 use std::{marker::PhantomPinned, pin::Pin};
 
-fn is_unpin<T: Unpin>() {}
-
 #[cfg(target_os = "linux")]
 struct Linux;
 #[cfg(not(target_os = "linux"))]
 struct Other;
 
 // Use this type to check that `cfg(any())` is working properly.
-// If `cfg(any())` is not working properly, `is_unpin` will fail.
 struct Any(PhantomPinned);
 
 #[test]
@@ -34,12 +34,12 @@
         any: Any,
     }
 
-    is_unpin::<SameName>();
+    assert_unpin!(SameName);
 
     #[cfg(target_os = "linux")]
-    let _x = SameName { inner: Linux };
+    let _ = SameName { inner: Linux };
     #[cfg(not(target_os = "linux"))]
-    let _x = SameName { inner: Other };
+    let _ = SameName { inner: Other };
 
     #[pin_project(project_replace)]
     struct DifferentName {
@@ -54,12 +54,12 @@
         a: Any,
     }
 
-    is_unpin::<DifferentName>();
+    assert_unpin!(DifferentName);
 
     #[cfg(target_os = "linux")]
-    let _x = DifferentName { l: Linux };
+    let _ = DifferentName { l: Linux };
     #[cfg(not(target_os = "linux"))]
-    let _x = DifferentName { o: Other };
+    let _ = DifferentName { o: Other };
 
     #[pin_project(project_replace)]
     struct TupleStruct(
@@ -74,16 +74,20 @@
         Any,
     );
 
-    is_unpin::<TupleStruct>();
+    assert_unpin!(TupleStruct);
 
     #[cfg(target_os = "linux")]
-    let _x = TupleStruct(Linux);
+    let _ = TupleStruct(Linux);
     #[cfg(not(target_os = "linux"))]
-    let _x = TupleStruct(Other);
+    let _ = TupleStruct(Other);
 
     // enums
 
-    #[pin_project(project_replace)]
+    #[pin_project(
+        project = VariantProj,
+        project_ref = VariantProjRef,
+        project_replace = VariantProjOwn,
+    )]
     enum Variant {
         #[cfg(target_os = "linux")]
         Inner(#[pin] Linux),
@@ -98,19 +102,23 @@
         Any(#[pin] Any),
     }
 
-    is_unpin::<Variant>();
+    assert_unpin!(Variant);
 
     #[cfg(target_os = "linux")]
-    let _x = Variant::Inner(Linux);
+    let _ = Variant::Inner(Linux);
     #[cfg(not(target_os = "linux"))]
-    let _x = Variant::Inner(Other);
+    let _ = Variant::Inner(Other);
 
     #[cfg(target_os = "linux")]
-    let _x = Variant::Linux(Linux);
+    let _ = Variant::Linux(Linux);
     #[cfg(not(target_os = "linux"))]
-    let _x = Variant::Other(Other);
+    let _ = Variant::Other(Other);
 
-    #[pin_project(project_replace)]
+    #[pin_project(
+        project = FieldProj,
+        project_ref = FieldProjRef,
+        project_replace = FieldProjOwn,
+    )]
     enum Field {
         SameName {
             #[cfg(target_os = "linux")]
@@ -147,22 +155,22 @@
         ),
     }
 
-    is_unpin::<Field>();
+    assert_unpin!(Field);
 
     #[cfg(target_os = "linux")]
-    let _x = Field::SameName { inner: Linux };
+    let _ = Field::SameName { inner: Linux };
     #[cfg(not(target_os = "linux"))]
-    let _x = Field::SameName { inner: Other };
+    let _ = Field::SameName { inner: Other };
 
     #[cfg(target_os = "linux")]
-    let _x = Field::DifferentName { l: Linux };
+    let _ = Field::DifferentName { l: Linux };
     #[cfg(not(target_os = "linux"))]
-    let _x = Field::DifferentName { w: Other };
+    let _ = Field::DifferentName { w: Other };
 
     #[cfg(target_os = "linux")]
-    let _x = Field::TupleVariant(Linux);
+    let _ = Field::TupleVariant(Linux);
     #[cfg(not(target_os = "linux"))]
-    let _x = Field::TupleVariant(Other);
+    let _ = Field::TupleVariant(Other);
 }
 
 #[test]
@@ -180,7 +188,7 @@
         any: Any,
     }
 
-    is_unpin::<SameCfg>();
+    assert_unpin!(SameCfg);
 
     #[cfg(target_os = "linux")]
     let mut x = SameCfg { inner: Linux };
@@ -206,7 +214,7 @@
         any: Any,
     }
 
-    is_unpin::<DifferentCfg>();
+    assert_unpin!(DifferentCfg);
 
     #[cfg(target_os = "linux")]
     let mut x = DifferentCfg { inner: Linux };
@@ -225,6 +233,9 @@
         inner: T,
     }
 
+    assert_unpin!(Foo<()>);
+    assert_not_unpin!(Foo<PhantomPinned>);
+
     let mut x = Foo { inner: 0_u8 };
     let x = Pin::new(&mut x).project();
     let _: Pin<&mut u8> = x.inner;
@@ -237,6 +248,6 @@
     #[cfg_attr(any(), repr(packed))]
     struct Struct {
         #[pin]
-        field: u32,
+        f: u32,
     }
 }
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
index e78b3dc..85b1db8 100644
--- a/tests/compiletest.rs
+++ b/tests/compiletest.rs
@@ -1,15 +1,21 @@
+#![cfg(not(miri))]
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 
-#[rustversion::attr(not(nightly), ignore)]
+use std::env;
+
+// Run `./dev.sh +$toolchain test --test compiletest` to update this.
+#[rustversion::attr(before(2020-11-25), ignore)] // Note: This date is commit-date and the day before the toolchain date.
 #[test]
 fn ui() {
+    if env::var_os("CI").is_none() {
+        env::set_var("TRYBUILD", "overwrite");
+    }
+
     let t = trybuild::TestCases::new();
     t.compile_fail("tests/ui/cfg/*.rs");
     t.compile_fail("tests/ui/not_unpin/*.rs");
     t.compile_fail("tests/ui/pin_project/*.rs");
     t.compile_fail("tests/ui/pinned_drop/*.rs");
-    t.compile_fail("tests/ui/project/*.rs");
     t.compile_fail("tests/ui/unsafe_unpin/*.rs");
     t.compile_fail("tests/ui/unstable-features/*.rs");
-    t.pass("tests/ui/unstable-features/run-pass/*.rs");
 }
diff --git a/tests/drop_order.rs b/tests/drop_order.rs
new file mode 100644
index 0000000..1557188
--- /dev/null
+++ b/tests/drop_order.rs
@@ -0,0 +1,161 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+// Refs: https://doc.rust-lang.org/reference/destructors.html
+
+use pin_project::pin_project;
+use std::{cell::Cell, pin::Pin, thread};
+
+struct D<'a>(&'a Cell<usize>, usize);
+
+impl Drop for D<'_> {
+    fn drop(&mut self) {
+        if !thread::panicking() {
+            let old = self.0.replace(self.1);
+            assert_eq!(old, self.1 - 1);
+        }
+    }
+}
+
+#[pin_project(project_replace)]
+struct StructPinned<'a> {
+    #[pin]
+    f1: D<'a>,
+    #[pin]
+    f2: D<'a>,
+}
+
+#[pin_project(project_replace)]
+struct StructUnpinned<'a> {
+    f1: D<'a>,
+    f2: D<'a>,
+}
+
+#[pin_project(project_replace)]
+struct TuplePinned<'a>(#[pin] D<'a>, #[pin] D<'a>);
+
+#[pin_project(project_replace)]
+struct TupleUnpinned<'a>(D<'a>, D<'a>);
+
+#[pin_project(project_replace = EnumProj)]
+enum Enum<'a> {
+    #[allow(dead_code)] // false positive that fixed in Rust 1.38
+    StructPinned {
+        #[pin]
+        f1: D<'a>,
+        #[pin]
+        f2: D<'a>,
+    },
+    #[allow(dead_code)] // false positive that fixed in Rust 1.38
+    StructUnpinned {
+        f1: D<'a>,
+        f2: D<'a>,
+    },
+    TuplePinned(#[pin] D<'a>, #[pin] D<'a>),
+    TupleUnpinned(D<'a>, D<'a>),
+}
+
+#[test]
+fn struct_pinned() {
+    {
+        let c = Cell::new(0);
+        let _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+#[test]
+fn struct_unpinned() {
+    {
+        let c = Cell::new(0);
+        let _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+#[test]
+fn tuple_pinned() {
+    {
+        let c = Cell::new(0);
+        let _x = TuplePinned(D(&c, 1), D(&c, 2));
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = TuplePinned(D(&c, 1), D(&c, 2));
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(TuplePinned(D(&c, 3), D(&c, 4)));
+    }
+}
+
+#[test]
+fn tuple_unpinned() {
+    {
+        let c = Cell::new(0);
+        let _x = TupleUnpinned(D(&c, 1), D(&c, 2));
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = TupleUnpinned(D(&c, 1), D(&c, 2));
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(TupleUnpinned(D(&c, 3), D(&c, 4)));
+    }
+}
+
+#[test]
+fn enum_struct() {
+    {
+        let c = Cell::new(0);
+        let _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+
+    {
+        let c = Cell::new(0);
+        let _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+#[test]
+fn enum_tuple() {
+    {
+        let c = Cell::new(0);
+        let _x = Enum::TuplePinned(D(&c, 1), D(&c, 2));
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::TuplePinned(D(&c, 1), D(&c, 2));
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::TuplePinned(D(&c, 3), D(&c, 4)));
+    }
+
+    {
+        let c = Cell::new(0);
+        let _x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2));
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::TupleUnpinned(D(&c, 1), D(&c, 2));
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::TupleUnpinned(D(&c, 3), D(&c, 4)));
+    }
+}
diff --git a/tests/include/basic-safe-part.rs b/tests/include/basic-safe-part.rs
index fefc924..0b7c43e 100644
--- a/tests/include/basic-safe-part.rs
+++ b/tests/include/basic-safe-part.rs
@@ -8,11 +8,32 @@
     pub unpinned: U,
 }
 
+#[::pin_project::pin_project(
+    project = DefaultStructNamedProj,
+    project_ref = DefaultStructNamedProjRef,
+)]
+#[derive(Debug)]
+pub struct DefaultStructNamed<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]
+#[::pin_project::pin_project(
+    project = DefaultTupleStructNamedProj,
+    project_ref = DefaultTupleStructNamedProjRef,
+)]
+#[derive(Debug)]
+pub struct DefaultTupleStructNamed<T, U>(#[pin] pub T, pub U);
+
+#[::pin_project::pin_project(
+    project = DefaultEnumProj,
+    project_ref = DefaultEnumProjRef,
+)]
 #[derive(Debug)]
 pub enum DefaultEnum<T, U> {
     Struct {
@@ -46,7 +67,11 @@
     fn drop(self: ::pin_project::__private::Pin<&mut Self>) {}
 }
 
-#[::pin_project::pin_project(PinnedDrop)]
+#[::pin_project::pin_project(
+    PinnedDrop,
+    project = PinnedDropEnumProj,
+    project_ref = PinnedDropEnumProjRef,
+)]
 #[derive(Debug)]
 pub enum PinnedDropEnum<T, U> {
     Struct {
@@ -71,11 +96,35 @@
     pub unpinned: U,
 }
 
+#[::pin_project::pin_project(
+    project = ReplaceStructNamedProj,
+    project_ref = ReplaceStructNamedProjRef,
+    project_replace = ReplaceStructNamedProjOwn,
+)]
+#[derive(Debug)]
+pub struct ReplaceStructNamed<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)]
+#[::pin_project::pin_project(
+    project = ReplaceTupleStructNamedProj,
+    project_ref = ReplaceTupleStructNamedProjRef,
+    project_replace = ReplaceTupleStructNamedProjOwn,
+)]
+#[derive(Debug)]
+pub struct ReplaceTupleStructNamed<T, U>(#[pin] pub T, pub U);
+
+#[::pin_project::pin_project(
+    project = ReplaceEnumProj,
+    project_ref = ReplaceEnumProjRef,
+    project_replace = ReplaceEnumProjOwn,
+)]
 #[derive(Debug)]
 pub enum ReplaceEnum<T, U> {
     Struct {
@@ -99,7 +148,11 @@
 #[derive(Debug)]
 pub struct UnsafeUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
 
-#[::pin_project::pin_project(UnsafeUnpin)]
+#[::pin_project::pin_project(
+    UnsafeUnpin,
+    project = UnsafeUnpinEnumProj,
+    project_ref = UnsafeUnpinEnumProjRef,
+)]
 #[derive(Debug)]
 pub enum UnsafeUnpinEnum<T, U> {
     Struct {
@@ -123,7 +176,11 @@
 #[derive(Debug)]
 pub struct NotUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
 
-#[::pin_project::pin_project(!Unpin)]
+#[::pin_project::pin_project(
+    !Unpin,
+    project = NotUnpinEnumProj,
+    project_ref = NotUnpinEnumProjRef,
+)]
 #[derive(Debug)]
 pub enum NotUnpinEnum<T, U> {
     Struct {
diff --git a/tests/lint.rs b/tests/lint.rs
index e152930..b577e0e 100644
--- a/tests/lint.rs
+++ b/tests/lint.rs
@@ -1,31 +1,25 @@
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-#![warn(future_incompatible, nonstandard_style, rust_2018_compatibility, unused)]
-#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
+#![warn(nonstandard_style, rust_2018_idioms, rustdoc, unused)]
+// Note: This does not guarantee compatibility with forbidding these lints in the future.
+// If rustc adds a new lint, we may not be able to keep this.
+#![forbid(future_incompatible, rust_2018_compatibility)]
 #![allow(unknown_lints)] // for old compilers
 #![warn(
-    absolute_paths_not_starting_with_crate,
-    anonymous_parameters,
     box_pointers,
     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,
@@ -33,43 +27,558 @@
     unused_results,
     variant_size_differences
 )]
-// unused_crate_dependencies: unrelated
-// unsafe_code: checked in forbid_unsafe module
+// absolute_paths_not_starting_with_crate, anonymous_parameters, keyword_idents, pointer_structural_match: forbidden as a part of future_incompatible
+// missing_doc_code_examples, private_doc_tests, invalid_html_tags: warned as a part of rustdoc
 // unsafe_block_in_unsafe_fn: unstable
+// unsafe_code: checked in forbid_unsafe module
+// unstable_features: deprecated: https://doc.rust-lang.org/beta/rustc/lints/listing/allowed-by-default.html#unstable-features
+// unused_crate_dependencies: unrelated
+#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
+#![warn(clippy::restriction)]
+#![allow(clippy::blanket_clippy_restriction_lints)] // this is a test, so enable all restriction lints intentionally.
 
 // Check interoperability with rustc and clippy lints.
 
+mod auxiliary;
+
 pub mod basic {
     include!("include/basic.rs");
+
+    pub mod inside_macro {
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[::pin_project::pin_project]
+                #[derive(Debug)]
+                pub struct DefaultStruct<T, U> {
+                    #[pin]
+                    pub pinned: T,
+                    pub unpinned: U,
+                }
+
+                #[::pin_project::pin_project(
+                    project = DefaultStructNamedProj,
+                    project_ref = DefaultStructNamedProjRef,
+                )]
+                #[derive(Debug)]
+                pub struct DefaultStructNamed<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(
+                    project = DefaultTupleStructNamedProj,
+                    project_ref = DefaultTupleStructNamedProjRef,
+                )]
+                #[derive(Debug)]
+                pub struct DefaultTupleStructNamed<T, U>(#[pin] pub T, pub U);
+
+                #[::pin_project::pin_project(
+                    project = DefaultEnumProj,
+                    project_ref = DefaultEnumProjRef,
+                )]
+                #[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,
+                    project = PinnedDropEnumProj,
+                    project_ref = PinnedDropEnumProjRef,
+                )]
+                #[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 = ReplaceStructNamedProj,
+                    project_ref = ReplaceStructNamedProjRef,
+                    project_replace = ReplaceStructNamedProjOwn,
+                )]
+                #[derive(Debug)]
+                pub struct ReplaceStructNamed<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 = ReplaceTupleStructNamedProj,
+                    project_ref = ReplaceTupleStructNamedProjRef,
+                    project_replace = ReplaceTupleStructNamedProjOwn,
+                )]
+                #[derive(Debug)]
+                pub struct ReplaceTupleStructNamed<T, U>(#[pin] pub T, pub U);
+
+                #[::pin_project::pin_project(
+                    project = ReplaceEnumProj,
+                    project_ref = ReplaceEnumProjRef,
+                    project_replace = ReplaceEnumProjOwn,
+                )]
+                #[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,
+                    project = UnsafeUnpinEnumProj,
+                    project_ref = UnsafeUnpinEnumProjRef,
+                )]
+                #[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,
+                    project = NotUnpinEnumProj,
+                    project_ref = NotUnpinEnumProjRef,
+                )]
+                #[derive(Debug)]
+                pub enum NotUnpinEnum<T, U> {
+                    Struct {
+                        #[pin]
+                        pinned: T,
+                        unpinned: U,
+                    },
+                    Tuple(#[pin] T, U),
+                    Unit,
+                }
+
+                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>
+                {
+                }
+            };
+        }
+
+        mac!();
+    }
 }
 
 pub mod forbid_unsafe {
     #![forbid(unsafe_code)]
 
     include!("include/basic-safe-part.rs");
+
+    pub mod inside_macro {
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[::pin_project::pin_project]
+                #[derive(Debug)]
+                pub struct DefaultStruct<T, U> {
+                    #[pin]
+                    pub pinned: T,
+                    pub unpinned: U,
+                }
+
+                #[::pin_project::pin_project(
+                    project = DefaultStructNamedProj,
+                    project_ref = DefaultStructNamedProjRef,
+                )]
+                #[derive(Debug)]
+                pub struct DefaultStructNamed<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(
+                    project = DefaultTupleStructNamedProj,
+                    project_ref = DefaultTupleStructNamedProjRef,
+                )]
+                #[derive(Debug)]
+                pub struct DefaultTupleStructNamed<T, U>(#[pin] pub T, pub U);
+
+                #[::pin_project::pin_project(
+                    project = DefaultEnumProj,
+                    project_ref = DefaultEnumProjRef,
+                )]
+                #[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,
+                    project = PinnedDropEnumProj,
+                    project_ref = PinnedDropEnumProjRef,
+                )]
+                #[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 = ReplaceStructNamedProj,
+                    project_ref = ReplaceStructNamedProjRef,
+                    project_replace = ReplaceStructNamedProjOwn,
+                )]
+                #[derive(Debug)]
+                pub struct ReplaceStructNamed<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 = ReplaceTupleStructNamedProj,
+                    project_ref = ReplaceTupleStructNamedProjRef,
+                    project_replace = ReplaceTupleStructNamedProjOwn,
+                )]
+                #[derive(Debug)]
+                pub struct ReplaceTupleStructNamed<T, U>(#[pin] pub T, pub U);
+
+                #[::pin_project::pin_project(
+                    project = ReplaceEnumProj,
+                    project_ref = ReplaceEnumProjRef,
+                    project_replace = ReplaceEnumProjOwn,
+                )]
+                #[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,
+                    project = UnsafeUnpinEnumProj,
+                    project_ref = UnsafeUnpinEnumProjRef,
+                )]
+                #[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,
+                    project = NotUnpinEnumProj,
+                    project_ref = NotUnpinEnumProjRef,
+                )]
+                #[derive(Debug)]
+                pub enum NotUnpinEnum<T, U> {
+                    Struct {
+                        #[pin]
+                        pinned: T,
+                        unpinned: U,
+                    },
+                    Tuple(#[pin] T, U),
+                    Unit,
+                }
+            };
+        }
+
+        mac!();
+    }
 }
 
-pub mod clippy {
+pub mod box_pointers {
     use pin_project::pin_project;
 
-    #[rustversion::attr(before(1.37), allow(single_use_lifetimes))] // https://github.com/rust-lang/rust/issues/53738
+    #[allow(box_pointers)] // for the type itself
     #[pin_project(project_replace)]
     #[derive(Debug)]
-    pub struct MutMutStruct<'a, T, U> {
+    pub struct Struct {
+        #[pin]
+        pub p: Box<isize>,
+        pub u: Box<isize>,
+    }
+
+    #[allow(box_pointers)] // for the type itself
+    #[pin_project(project_replace)]
+    #[derive(Debug)]
+    pub struct TupleStruct(#[pin] pub Box<isize>, pub Box<isize>);
+
+    #[allow(box_pointers)] // for the type itself
+    #[pin_project(
+        project = EnumProj,
+        project_ref = EnumProjRef,
+        project_replace = EnumProjOwn,
+    )]
+    #[derive(Debug)]
+    pub enum Enum {
+        Struct {
+            #[pin]
+            p: Box<isize>,
+            u: Box<isize>,
+        },
+        Tuple(#[pin] Box<isize>, Box<isize>),
+        Unit,
+    }
+
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[allow(box_pointers)] // for the type itself
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct Struct {
+                    #[pin]
+                    pub p: Box<isize>,
+                    pub u: Box<isize>,
+                }
+
+                #[allow(box_pointers)] // for the type itself
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct TupleStruct(#[pin] pub Box<isize>, pub Box<isize>);
+
+                #[allow(box_pointers)] // for the type itself
+                #[pin_project(
+                    project = EnumProj,
+                    project_ref = EnumProjRef,
+                    project_replace = EnumProjOwn,
+                )]
+                #[derive(Debug)]
+                pub enum Enum {
+                    Struct {
+                        #[pin]
+                        p: Box<isize>,
+                        u: Box<isize>,
+                    },
+                    Tuple(#[pin] Box<isize>, Box<isize>),
+                    Unit,
+                }
+            };
+        }
+
+        mac!();
+    }
+}
+
+pub mod explicit_outlives_requirements {
+    use pin_project::pin_project;
+
+    #[allow(explicit_outlives_requirements)] // for the type itself: https://github.com/rust-lang/rust/issues/60993
+    #[pin_project(project_replace)]
+    #[derive(Debug)]
+    pub struct Struct<'a, T, U>
+    where
+        T: ?Sized,
+        U: ?Sized,
+    {
         #[pin]
         pub pinned: &'a mut T,
         pub unpinned: &'a mut U,
     }
 
-    #[rustversion::attr(before(1.37), allow(single_use_lifetimes))] // https://github.com/rust-lang/rust/issues/53738
+    #[allow(explicit_outlives_requirements)] // for the type itself: https://github.com/rust-lang/rust/issues/60993
     #[pin_project(project_replace)]
     #[derive(Debug)]
-    pub struct MutMutTupleStruct<'a, T, U>(#[pin] &'a mut T, &'a mut U);
+    pub struct TupleStruct<'a, T, U>(#[pin] pub &'a mut T, pub &'a mut U)
+    where
+        T: ?Sized,
+        U: ?Sized;
 
-    #[rustversion::attr(before(1.37), allow(single_use_lifetimes))] // https://github.com/rust-lang/rust/issues/53738
-    #[pin_project(project_replace)]
+    #[allow(explicit_outlives_requirements)] // for the type itself: https://github.com/rust-lang/rust/issues/60993
+    #[pin_project(
+        project = EnumProj,
+        project_ref = EnumProjRef,
+        project_replace = EnumProjOwn,
+    )]
     #[derive(Debug)]
-    pub enum MutMutEnum<'a, T, U> {
+    pub enum Enum<'a, T, U>
+    where
+        T: ?Sized,
+        U: ?Sized,
+    {
         Struct {
             #[pin]
             pinned: &'a mut T,
@@ -79,9 +588,301 @@
         Unit,
     }
 
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[allow(explicit_outlives_requirements)] // for the type itself: https://github.com/rust-lang/rust/issues/60993
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct Struct<'a, T, U>
+                where
+                    T: ?Sized,
+                    U: ?Sized,
+                {
+                    #[pin]
+                    pub pinned: &'a mut T,
+                    pub unpinned: &'a mut U,
+                }
+
+                #[allow(explicit_outlives_requirements)] // for the type itself: https://github.com/rust-lang/rust/issues/60993
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct TupleStruct<'a, T, U>(#[pin] pub &'a mut T, pub &'a mut U)
+                where
+                    T: ?Sized,
+                    U: ?Sized;
+
+                #[allow(explicit_outlives_requirements)] // for the type itself: https://github.com/rust-lang/rust/issues/60993
+                #[pin_project(
+                    project = EnumProj,
+                    project_ref = EnumProjRef,
+                    project_replace = EnumProjOwn,
+                )]
+                #[derive(Debug)]
+                pub enum Enum<'a, T, U>
+                where
+                    T: ?Sized,
+                    U: ?Sized,
+                {
+                    Struct {
+                        #[pin]
+                        pinned: &'a mut T,
+                        unpinned: &'a mut U,
+                    },
+                    Tuple(#[pin] &'a mut T, &'a mut U),
+                    Unit,
+                }
+            };
+        }
+
+        mac!();
+    }
+}
+
+pub mod single_use_lifetimes {
+    use pin_project::pin_project;
+
+    #[allow(unused_lifetimes)]
+    pub trait Trait<'a> {}
+
+    #[allow(unused_lifetimes)] // for the type itself
+    #[allow(single_use_lifetimes)] // for the type itself: https://github.com/rust-lang/rust/issues/55058
     #[pin_project(project_replace)]
     #[derive(Debug)]
-    pub struct TypeRepetitionInBoundsStruct<T, U>
+    pub struct HRTB<'pin___, T>
+    where
+        for<'pin> &'pin T: Unpin,
+        T: for<'pin> Trait<'pin>,
+        for<'pin, 'pin_, 'pin__> &'pin &'pin_ &'pin__ T: Unpin,
+    {
+        #[pin]
+        f: &'pin___ mut T,
+    }
+
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[allow(unused_lifetimes)]
+                pub trait Trait<'a> {}
+
+                #[allow(unused_lifetimes)] // for the type itself
+                #[allow(single_use_lifetimes)] // for the type itself: https://github.com/rust-lang/rust/issues/55058
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct HRTB<'pin___, T>
+                where
+                    for<'pin> &'pin T: Unpin,
+                    T: for<'pin> Trait<'pin>,
+                    for<'pin, 'pin_, 'pin__> &'pin &'pin_ &'pin__ T: Unpin,
+                {
+                    #[pin]
+                    f: &'pin___ mut T,
+                }
+            };
+        }
+
+        mac!();
+    }
+}
+
+pub mod variant_size_differences {
+    use pin_project::pin_project;
+
+    #[allow(missing_debug_implementations, missing_copy_implementations)] // https://github.com/rust-lang/rust/pull/74060
+    #[allow(variant_size_differences)] // for the type itself
+    #[allow(clippy::large_enum_variant)] // for the type itself
+    #[pin_project(
+        project = EnumProj,
+        project_ref = EnumProjRef,
+        project_replace = EnumProjOwn,
+    )]
+    pub enum Enum {
+        V1(u8),
+        V2([u8; 1024]),
+    }
+
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[allow(missing_debug_implementations, missing_copy_implementations)] // https://github.com/rust-lang/rust/pull/74060
+                #[allow(variant_size_differences)] // for the type itself
+                #[allow(clippy::large_enum_variant)] // for the type itself
+                #[pin_project(
+                    project = EnumProj,
+                    project_ref = EnumProjRef,
+                    project_replace = EnumProjOwn,
+                )]
+                pub enum Enum {
+                    V1(u8),
+                    V2([u8; 1024]),
+                }
+            };
+        }
+
+        mac!();
+    }
+}
+
+pub mod clippy_mut_mut {
+    use pin_project::pin_project;
+
+    #[pin_project(project_replace)]
+    #[derive(Debug)]
+    pub struct Struct<'a, T, U> {
+        #[pin]
+        pub pinned: &'a mut T,
+        pub unpinned: &'a mut U,
+    }
+
+    #[pin_project(project_replace)]
+    #[derive(Debug)]
+    pub struct TupleStruct<'a, T, U>(#[pin] &'a mut T, &'a mut U);
+
+    #[pin_project(
+        project = EnumProj,
+        project_ref = EnumProjRef,
+        project_replace = EnumProjOwn,
+    )]
+    #[derive(Debug)]
+    pub enum Enum<'a, T, U> {
+        Struct {
+            #[pin]
+            pinned: &'a mut T,
+            unpinned: &'a mut U,
+        },
+        Tuple(#[pin] &'a mut T, &'a mut U),
+        Unit,
+    }
+
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct Struct<'a, T, U> {
+                    #[pin]
+                    pub pinned: &'a mut T,
+                    pub unpinned: &'a mut U,
+                }
+
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct TupleStruct<'a, T, U>(#[pin] &'a mut T, &'a mut U);
+
+                #[pin_project(
+                    project = EnumProj,
+                    project_ref = EnumProjRef,
+                    project_replace = EnumProjOwn,
+                )]
+                #[derive(Debug)]
+                pub enum Enum<'a, T, U> {
+                    Struct {
+                        #[pin]
+                        pinned: &'a mut T,
+                        unpinned: &'a mut U,
+                    },
+                    Tuple(#[pin] &'a mut T, &'a mut U),
+                    Unit,
+                }
+            };
+        }
+
+        mac!();
+    }
+}
+
+#[allow(unreachable_pub)]
+mod clippy_redundant_pub_crate {
+    use pin_project::pin_project;
+
+    #[pin_project(project_replace)]
+    #[derive(Debug)]
+    pub struct Struct<T, U> {
+        #[pin]
+        pub pinned: T,
+        pub unpinned: U,
+    }
+
+    #[pin_project(project_replace)]
+    #[derive(Debug)]
+    pub struct TupleStruct<T, U>(#[pin] pub T, pub U);
+
+    #[allow(dead_code)]
+    #[pin_project(
+        project = EnumProj,
+        project_ref = EnumProjRef,
+        project_replace = EnumProjOwn,
+    )]
+    #[derive(Debug)]
+    pub enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Tuple(#[pin] T, U),
+        Unit,
+    }
+
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct Struct<T, U> {
+                    #[pin]
+                    pub pinned: T,
+                    pub unpinned: U,
+                }
+
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct TupleStruct<T, U>(#[pin] pub T, pub U);
+
+                #[allow(dead_code)]
+                #[pin_project(
+                    project = EnumProj,
+                    project_ref = EnumProjRef,
+                    project_replace = EnumProjOwn,
+                )]
+                #[derive(Debug)]
+                pub enum Enum<T, U> {
+                    Struct {
+                        #[pin]
+                        pinned: T,
+                        unpinned: U,
+                    },
+                    Tuple(#[pin] T, U),
+                    Unit,
+                }
+            };
+        }
+
+        mac!();
+    }
+}
+
+pub mod clippy_type_repetition_in_bounds {
+    use pin_project::pin_project;
+
+    #[pin_project(project_replace)]
+    #[derive(Debug)]
+    pub struct Struct<T, U>
     where
         Self: Sized,
     {
@@ -92,13 +893,17 @@
 
     #[pin_project(project_replace)]
     #[derive(Debug)]
-    pub struct TypeRepetitionInBoundsTupleStruct<T, U>(#[pin] T, U)
+    pub struct TupleStruct<T, U>(#[pin] T, U)
     where
         Self: Sized;
 
-    #[pin_project(project_replace)]
+    #[pin_project(
+        project = EnumProj,
+        project_ref = EnumProjRef,
+        project_replace = EnumProjOwn,
+    )]
     #[derive(Debug)]
-    pub enum TypeRepetitionInBoundsEnum<T, U>
+    pub enum Enum<T, U>
     where
         Self: Sized,
     {
@@ -111,38 +916,124 @@
         Unit,
     }
 
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct Struct<T, U>
+                where
+                    Self: Sized,
+                {
+                    #[pin]
+                    pub pinned: T,
+                    pub unpinned: U,
+                }
+
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct TupleStruct<T, U>(#[pin] T, U)
+                where
+                    Self: Sized;
+
+                #[pin_project(
+                    project = EnumProj,
+                    project_ref = EnumProjRef,
+                    project_replace = EnumProjOwn,
+                )]
+                #[derive(Debug)]
+                pub enum Enum<T, U>
+                where
+                    Self: Sized,
+                {
+                    Struct {
+                        #[pin]
+                        pinned: T,
+                        unpinned: U,
+                    },
+                    Tuple(#[pin] T, U),
+                    Unit,
+                }
+            };
+        }
+
+        mac!();
+    }
+}
+
+pub mod clippy_used_underscore_binding {
+    use pin_project::pin_project;
+
     #[pin_project(project_replace)]
     #[derive(Debug)]
-    pub struct UsedUnderscoreBindingStruct<T, U> {
+    pub struct Struct<T, U> {
         #[pin]
         pub _pinned: T,
         pub _unpinned: U,
     }
 
-    #[pin_project(project_replace)]
+    #[pin_project(
+        project = EnumProj,
+        project_ref = EnumProjRef,
+        project_replace = EnumProjOwn,
+    )]
     #[derive(Debug)]
-    pub enum UsedUnderscoreBindingEnum<T, U> {
+    pub enum Enum<T, U> {
         Struct {
             #[pin]
             _pinned: T,
             _unpinned: U,
         },
     }
+
+    pub mod inside_macro {
+        use pin_project::pin_project;
+
+        #[rustfmt::skip]
+        macro_rules! mac {
+            () => {
+                #[pin_project(project_replace)]
+                #[derive(Debug)]
+                pub struct Struct<T, U> {
+                    #[pin]
+                    pub _pinned: T,
+                    pub _unpinned: U,
+                }
+
+                #[pin_project(
+                    project = EnumProj,
+                    project_ref = EnumProjRef,
+                    project_replace = EnumProjOwn,
+                )]
+                #[derive(Debug)]
+                pub enum Enum<T, U> {
+                    Struct {
+                        #[pin]
+                        _pinned: T,
+                        _unpinned: U,
+                    },
+                }
+            };
+        }
+
+        mac!();
+    }
 }
 
-#[allow(box_pointers)]
-#[rustversion::attr(not(nightly), ignore)]
+// Run `./dev.sh +$toolchain test --test lint` to update this.
+#[cfg(not(miri))]
+#[allow(clippy::restriction)]
+#[rustversion::attr(before(2020-12-25), ignore)] // Note: This date is commit-date and the day before the toolchain date.
 #[test]
 fn check_lint_list() {
+    use auxiliary::assert_diff;
     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));
+    let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
+    let output = Command::new(rustc).args(&["-W", "help"]).output().unwrap();
+    let new = str::from_utf8(&output.stdout).unwrap();
+    assert_diff("tests/lint.txt", new);
 }
diff --git a/tests/lint.txt b/tests/lint.txt
index 4205786..8983ad7 100644
--- a/tests/lint.txt
+++ b/tests/lint.txt
@@ -16,7 +16,7 @@
                                        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
+                                          invalid-html-tags  allow    detects invalid HTML tags in doc comments
                                              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
@@ -26,6 +26,7 @@
                                                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
+                                   pointer-structural-match  allow    pointers are not structural-match
                                           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
@@ -46,49 +47,61 @@
                                            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
+                                     broken-intra-doc-links  warn     failures in resolving intra-doc link targets
                                        cenum-impl-drop-cast  warn     a C-like enum implementing Drop is cast
                                clashing-extern-declarations  warn     detects when an extern fn has been declared with the same name but different types
                                        coherence-leak-check  warn     distinct impls distinguished only by the leak-check code
                                           confusable-idents  warn     detects visually confusable pairs between identifiers
+                                const-evaluatable-unchecked  warn     detects a generic constant is used in a type without a emitting a warning
+                                        const-item-mutation  warn     detects attempts to mutate a `const` item
                                                   dead-code  warn     detect unused, unexported items
                                                  deprecated  warn     detects use of deprecated items
+                                                drop-bounds  warn     bounds of the form `T: Drop` are useless
                           ellipsis-inclusive-range-patterns  warn     `...` range patterns are deprecated
                               exported-private-dependencies  warn     public interface leaks type from a private dependency
+                                   function-item-references  warn     suggest casting to a function pointer when attempting to take references to function items
                      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
                                 improper-ctypes-definitions  warn     proper use of libc types in foreign item definitions
                                         incomplete-features  warn     incomplete features that may function improperly in some or all cases
+                                  indirect-structural-match  warn     constant used in pattern contains value of non-structural-match type in a field or a variant
                                          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-attributes  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
                                    mixed-script-confusables  warn     detects Unicode scripts whose mixed script confusables codepoints are solely used
                         mutable-borrow-reservation-conflict  warn     reservation of a two-phased borrow conflicts with other shared borrows
+                                nontrivial-structural-match  warn     constant used in pattern of non-structural-match type and the constant's initializer expression contains values of non-structural-match types
+                                              non-autolinks  warn     detects URLs that could be written using only angle brackets
                                        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
+                                overlapping-range-endpoints  warn     detects range patterns with overlapping endpoints
+                                                  panic-fmt  warn     detect braces in single-argument panic!() invocations
                                             path-statements  warn     path statements with no effect
+                                    private-intra-doc-links  warn     linking from a public item to a private one
                                           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
+                                   temporary-cstring-as-ptr  warn     detects getting the inner pointer of a temporary `CString`
                                              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
+                                         uninhabited-static  warn     uninhabited static
                                               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
+                                unsupported-naked-functions  warn     unsupported naked function definitions
                                           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
@@ -125,6 +138,7 @@
                                               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
+                                         useless-deprecated  deny     detects deprecation attributes with no effect
 
 
 Lint groups provided by rustc:
@@ -132,12 +146,12 @@
                        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, cenum-impl-drop-cast, array-into-iter
+        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, pointer-structural-match, nontrivial-structural-match, soft-unstable, cenum-impl-drop-cast, const-evaluatable-unchecked, uninhabited-static, unsupported-naked-functions, 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-attributes, 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
+                    rustdoc  non-autolinks, broken-intra-doc-links, private-intra-doc-links, invalid-codeblock-attributes, missing-doc-code-examples, private-doc-tests, invalid-html-tags
+                     unused  unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-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.
+Lint tools like Clippy can provide additional lints and lint groups.
diff --git a/tests/pin_project.rs b/tests/pin_project.rs
index 766887f..17dbd2a 100644
--- a/tests/pin_project.rs
+++ b/tests/pin_project.rs
@@ -1,9 +1,13 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 #![allow(dead_code)]
 
+#[macro_use]
+mod auxiliary;
+
 use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
 use std::{
     marker::{PhantomData, PhantomPinned},
+    panic,
     pin::Pin,
 };
 
@@ -16,41 +20,42 @@
     )]
     struct Struct<T, U> {
         #[pin]
-        field1: T,
-        field2: U,
+        f1: T,
+        f2: U,
     }
 
-    let mut s = Struct { field1: 1, field2: 2 };
+    let mut s = Struct { f1: 1, f2: 2 };
     let mut s_orig = Pin::new(&mut s);
     let s = s_orig.as_mut().project();
 
-    let x: Pin<&mut i32> = s.field1;
-    assert_eq!(*x, 1);
+    let _: Pin<&mut i32> = s.f1;
+    assert_eq!(*s.f1, 1);
+    let _: &mut i32 = s.f2;
+    assert_eq!(*s.f2, 2);
 
-    let y: &mut i32 = s.field2;
-    assert_eq!(*y, 2);
+    assert_eq!(s_orig.as_ref().f1, 1);
+    assert_eq!(s_orig.as_ref().f2, 2);
 
-    assert_eq!(s_orig.as_ref().field1, 1);
-    assert_eq!(s_orig.as_ref().field2, 2);
-
-    let mut s = Struct { field1: 1, field2: 2 };
-
-    let StructProj { field1, field2 } = Pin::new(&mut s).project();
-    let _: Pin<&mut i32> = field1;
-    let _: &mut i32 = field2;
-
-    let StructProjRef { field1, field2 } = Pin::new(&s).project_ref();
-    let _: Pin<&i32> = field1;
-    let _: &i32 = field2;
-
+    let mut s = Struct { f1: 1, f2: 2 };
     let mut s = Pin::new(&mut s);
-    let StructProjOwn { field1, field2 } =
-        s.as_mut().project_replace(Struct { field1: 3, field2: 4 });
-    let _: PhantomData<i32> = field1;
-    let _: i32 = field2;
-    assert_eq!(field2, 2);
-    assert_eq!(s.field1, 3);
-    assert_eq!(s.field2, 4);
+    {
+        let StructProj { f1, f2 } = s.as_mut().project();
+        let _: Pin<&mut i32> = f1;
+        let _: &mut i32 = f2;
+    }
+    {
+        let StructProjRef { f1, f2 } = s.as_ref().project_ref();
+        let _: Pin<&i32> = f1;
+        let _: &i32 = f2;
+    }
+    {
+        let StructProjOwn { f1, f2 } = s.as_mut().project_replace(Struct { f1: 3, f2: 4 });
+        let _: PhantomData<i32> = f1;
+        let _: i32 = f2;
+        assert_eq!(f2, 2);
+        assert_eq!(s.f1, 3);
+        assert_eq!(s.f2, 4);
+    }
 
     #[pin_project(project_replace)]
     struct TupleStruct<T, U>(#[pin] T, U);
@@ -58,94 +63,91 @@
     let mut s = TupleStruct(1, 2);
     let s = Pin::new(&mut s).project();
 
-    let x: Pin<&mut i32> = s.0;
-    assert_eq!(*x, 1);
+    let _: Pin<&mut i32> = s.0;
+    assert_eq!(*s.0, 1);
+    let _: &mut i32 = s.1;
+    assert_eq!(*s.1, 2);
 
-    let y: &mut i32 = s.1;
-    assert_eq!(*y, 2);
-
-    #[pin_project(project_replace, project = EnumProj)]
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
     #[derive(Eq, PartialEq, Debug)]
     enum Enum<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
+        Tuple(#[pin] A, B),
+        Struct {
             #[pin]
-            field1: C,
-            field2: D,
+            f1: C,
+            f2: D,
         },
-        None,
+        Unit,
     }
 
-    let mut e = Enum::Variant1(1, 2);
-    let mut e_orig = Pin::new(&mut e);
-    let e = e_orig.as_mut().project();
+    let mut e = Enum::Tuple(1, 2);
+    let mut e = Pin::new(&mut e);
 
-    match e {
-        EnumProj::Variant1(x, y) => {
+    match e.as_mut().project() {
+        EnumProj::Tuple(x, y) => {
             let x: Pin<&mut i32> = x;
             assert_eq!(*x, 1);
-
             let y: &mut i32 = y;
             assert_eq!(*y, 2);
         }
-        EnumProj::Variant2 { field1, field2 } => {
-            let _x: Pin<&mut i32> = field1;
-            let _y: &mut i32 = field2;
+        EnumProj::Struct { f1, f2 } => {
+            let _: Pin<&mut i32> = f1;
+            let _: &mut i32 = f2;
+            unreachable!()
         }
-        EnumProj::None => {}
+        EnumProj::Unit => unreachable!(),
     }
 
-    assert_eq!(Pin::into_ref(e_orig).get_ref(), &Enum::Variant1(1, 2));
+    assert_eq!(&*e, &Enum::Tuple(1, 2));
 
-    let mut e = Enum::Variant2 { field1: 3, field2: 4 };
-    let mut e = Pin::new(&mut e).project();
+    let mut e = Enum::Struct { f1: 3, f2: 4 };
+    let mut e = Pin::new(&mut e);
 
-    match &mut e {
-        EnumProj::Variant1(x, y) => {
-            let _x: &mut Pin<&mut i32> = x;
-            let _y: &mut &mut i32 = y;
+    match e.as_mut().project() {
+        EnumProj::Tuple(x, y) => {
+            let _: Pin<&mut i32> = x;
+            let _: &mut i32 = y;
+            unreachable!()
         }
-        EnumProj::Variant2 { field1, field2 } => {
-            let x: &mut Pin<&mut i32> = field1;
-            assert_eq!(**x, 3);
-
-            let y: &mut &mut i32 = field2;
-            assert_eq!(**y, 4);
+        EnumProj::Struct { f1, f2 } => {
+            let _: Pin<&mut i32> = f1;
+            assert_eq!(*f1, 3);
+            let _: &mut i32 = f2;
+            assert_eq!(*f2, 4);
         }
-        EnumProj::None => {}
+        EnumProj::Unit => unreachable!(),
     }
 
-    if let EnumProj::Variant2 { field1, field2 } = e {
-        let x: Pin<&mut i32> = field1;
-        assert_eq!(*x, 3);
-
-        let y: &mut i32 = field2;
-        assert_eq!(*y, 4);
+    if let EnumProj::Struct { f1, f2 } = e.as_mut().project() {
+        let _: Pin<&mut i32> = f1;
+        assert_eq!(*f1, 3);
+        let _: &mut i32 = f2;
+        assert_eq!(*f2, 4);
     }
 }
 
 #[test]
 fn enum_project_set() {
-    #[pin_project(project_replace, project = EnumProj)]
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
     #[derive(Eq, PartialEq, Debug)]
     enum Enum {
-        Variant1(#[pin] u8),
-        Variant2(bool),
+        V1(#[pin] u8),
+        V2(bool),
     }
 
-    let mut e = Enum::Variant1(25);
+    let mut e = Enum::V1(25);
     let mut e_orig = Pin::new(&mut e);
     let e_proj = e_orig.as_mut().project();
 
     match e_proj {
-        EnumProj::Variant1(val) => {
-            let new_e = Enum::Variant2(val.as_ref().get_ref() == &25);
+        EnumProj::V1(val) => {
+            let new_e = Enum::V2(val.as_ref().get_ref() == &25);
             e_orig.set(new_e);
         }
-        _ => unreachable!(),
+        EnumProj::V2(_) => unreachable!(),
     }
 
-    assert_eq!(e, Enum::Variant2(true));
+    assert_eq!(e, Enum::V2(true));
 }
 
 #[test]
@@ -155,7 +157,7 @@
     where
         T: Copy,
     {
-        field: T,
+        f: T,
     }
 
     #[pin_project]
@@ -163,12 +165,12 @@
     where
         T: Copy;
 
-    #[pin_project]
-    enum EnumWhere<T>
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
+    enum Enum<T>
     where
         T: Copy,
     {
-        Variant(T),
+        V(T),
     }
 }
 
@@ -180,8 +182,8 @@
         I: Iterator,
     {
         #[pin]
-        field1: I,
-        field2: I::Item,
+        f1: I,
+        f2: I::Item,
     }
 
     #[pin_project(project_replace)]
@@ -190,8 +192,8 @@
         I: Iterator<Item = J>,
     {
         #[pin]
-        field1: I,
-        field2: J,
+        f1: I,
+        f2: J,
     }
 
     #[pin_project(project_replace)]
@@ -199,7 +201,7 @@
     where
         T: 'static,
     {
-        field: T,
+        f: T,
     }
 
     trait Static: 'static {}
@@ -211,13 +213,13 @@
     where
         I: Iterator;
 
-    #[pin_project(project_replace)]
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
     enum Enum<I>
     where
         I: Iterator,
     {
-        Variant1(#[pin] I),
-        Variant2(I::Item),
+        V1(#[pin] I),
+        V2(I::Item),
     }
 }
 
@@ -226,7 +228,7 @@
     #[pin_project(project_replace)]
     #[derive(Clone, Copy)]
     struct Struct<T> {
-        val: T,
+        f: T,
     }
 
     fn is_copy<T: Copy>() {}
@@ -240,21 +242,21 @@
 
     #[pin_project(project_replace)]
     struct Struct {
-        val: NotCopy,
+        f: NotCopy,
     }
 
-    let x = Struct { val: NotCopy };
-    let _val: NotCopy = x.val;
+    let x = Struct { f: NotCopy };
+    let _val: NotCopy = x.f;
 
-    #[pin_project(project_replace)]
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
     enum Enum {
-        Variant(NotCopy),
+        V(NotCopy),
     }
 
-    let x = Enum::Variant(NotCopy);
+    let x = Enum::V(NotCopy);
     #[allow(clippy::infallible_destructuring_match)]
     let _val: NotCopy = match x {
-        Enum::Variant(val) => val,
+        Enum::V(val) => val,
     };
 }
 
@@ -262,39 +264,39 @@
 fn trait_bounds_on_type_generics() {
     #[pin_project(project_replace)]
     pub struct Struct1<'a, T: ?Sized> {
-        field: &'a mut T,
+        f: &'a mut T,
     }
 
     #[pin_project(project_replace)]
     pub struct Struct2<'a, T: ::core::fmt::Debug> {
-        field: &'a mut T,
+        f: &'a mut T,
     }
 
     #[pin_project(project_replace)]
     pub struct Struct3<'a, T: core::fmt::Debug> {
-        field: &'a mut T,
+        f: &'a mut T,
     }
 
     #[pin_project(project_replace)]
     pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {
-        field: &'a mut T,
+        f: &'a mut T,
     }
 
     #[pin_project(project_replace)]
     pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {
-        field: &'a mut T,
+        f: &'a mut T,
     }
 
     #[pin_project(project_replace)]
     pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {
-        field: &'a mut T,
+        f: &'a mut T,
     }
 
-    let _: Struct6<'_> = Struct6 { field: &mut [0u8; 16] };
+    let _: Struct6<'_> = Struct6 { f: &mut [0_u8; 16] };
 
     #[pin_project(project_replace)]
     pub struct Struct7<T: 'static> {
-        field: T,
+        f: T,
     }
 
     trait Static: 'static {}
@@ -303,16 +305,16 @@
 
     #[pin_project(project_replace)]
     pub struct Struct8<'a, 'b: 'a> {
-        field1: &'a u8,
-        field2: &'b u8,
+        f1: &'a u8,
+        f2: &'b u8,
     }
 
     #[pin_project(project_replace)]
     pub struct TupleStruct<'a, T: ?Sized>(&'a mut T);
 
-    #[pin_project(project_replace)]
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
     enum Enum<'a, T: ?Sized> {
-        Variant(&'a mut T),
+        V(&'a mut T),
     }
 }
 
@@ -321,27 +323,52 @@
     #[pin_project(project_replace)]
     pub struct Struct1<'pin, T> {
         #[pin]
-        field: &'pin mut T,
+        f: &'pin mut T,
     }
 
     #[pin_project(project_replace)]
     pub struct Struct2<'pin, 'pin_, 'pin__> {
         #[pin]
-        field: &'pin &'pin_ &'pin__ (),
+        f: &'pin &'pin_ &'pin__ (),
     }
 
-    pub trait A<'a> {}
+    pub trait Trait<'a> {}
 
     #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
     #[pin_project(project_replace)]
     pub struct HRTB<'pin___, T>
     where
         for<'pin> &'pin T: Unpin,
-        T: for<'pin> A<'pin>,
+        T: for<'pin> Trait<'pin>,
         for<'pin, 'pin_, 'pin__> &'pin &'pin_ &'pin__ T: Unpin,
     {
         #[pin]
-        field: &'pin___ mut T,
+        f: &'pin___ mut T,
+    }
+
+    #[pin_project(PinnedDrop)]
+    pub struct PinnedDropStruct<'pin> {
+        #[pin]
+        f: &'pin (),
+    }
+
+    #[pinned_drop]
+    impl PinnedDrop for PinnedDropStruct<'_> {
+        fn drop(self: Pin<&mut Self>) {}
+    }
+
+    #[pin_project(UnsafeUnpin)]
+    pub struct UnsafeUnpinStruct<'pin> {
+        #[pin]
+        f: &'pin (),
+    }
+
+    unsafe impl UnsafeUnpin for UnsafeUnpinStruct<'_> {}
+
+    #[pin_project(!Unpin)]
+    pub struct NotUnpinStruct<'pin> {
+        #[pin]
+        f: &'pin (),
     }
 }
 
@@ -350,7 +377,7 @@
     #[pin_project(PinnedDrop, UnsafeUnpin)]
     pub struct PinnedDropWithUnsafeUnpin<T> {
         #[pin]
-        field: T,
+        f: T,
     }
 
     #[pinned_drop]
@@ -363,7 +390,7 @@
     #[pin_project(PinnedDrop, !Unpin)]
     pub struct PinnedDropWithNotUnpin<T> {
         #[pin]
-        field: T,
+        f: T,
     }
 
     #[pinned_drop]
@@ -374,7 +401,7 @@
     #[pin_project(UnsafeUnpin, project_replace)]
     pub struct UnsafeUnpinWithReplace<T> {
         #[pin]
-        field: T,
+        f: T,
     }
 
     unsafe impl<T: Unpin> UnsafeUnpin for UnsafeUnpinWithReplace<T> {}
@@ -382,7 +409,7 @@
     #[pin_project(!Unpin, project_replace)]
     pub struct NotUnpinWithReplace<T> {
         #[pin]
-        field: T,
+        f: T,
     }
 }
 
@@ -397,6 +424,7 @@
     struct PrivateStruct<T>(T);
 }
 
+#[allow(clippy::needless_lifetimes)]
 #[test]
 fn lifetime_project() {
     #[pin_project(project_replace)]
@@ -409,13 +437,13 @@
     #[pin_project(project_replace)]
     struct Struct2<'a, T, U> {
         #[pin]
-        pinned: &'a mut T,
+        pinned: &'a T,
         unpinned: U,
     }
 
-    #[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
     enum Enum<T, U> {
-        Variant {
+        V {
             #[pin]
             pinned: T,
             unpinned: U,
@@ -429,13 +457,25 @@
         fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> {
             self.project().pinned
         }
+        fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&T> {
+            self.project_ref().pinned
+        }
+        fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut T> {
+            self.project().pinned
+        }
     }
 
     impl<'b, T, U> Struct2<'b, T, U> {
-        fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b mut T> {
+        fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b T> {
             self.project_ref().pinned
         }
-        fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b mut T> {
+        fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b T> {
+            self.project().pinned
+        }
+        fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&&'b T> {
+            self.project_ref().pinned
+        }
+        fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut &'b T> {
             self.project().pinned
         }
     }
@@ -443,70 +483,22 @@
     impl<T, U> Enum<T, U> {
         fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> {
             match self.project_ref() {
-                EnumProjRef::Variant { pinned, .. } => pinned,
+                EnumProjRef::V { pinned, .. } => pinned,
             }
         }
         fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> {
             match self.project() {
-                EnumProj::Variant { pinned, .. } => pinned,
+                EnumProj::V { pinned, .. } => pinned,
             }
         }
-    }
-}
-
-#[rustversion::since(1.36)] // https://github.com/rust-lang/rust/pull/61207
-#[test]
-fn lifetime_project_elided() {
-    #[pin_project(project_replace)]
-    struct Struct1<T, U> {
-        #[pin]
-        pinned: T,
-        unpinned: U,
-    }
-
-    #[pin_project(project_replace)]
-    struct Struct2<'a, T, U> {
-        #[pin]
-        pinned: &'a mut T,
-        unpinned: U,
-    }
-
-    #[pin_project(project_replace, project = EnumProj, project_ref = EnumProjRef)]
-    enum Enum<T, U> {
-        Variant {
-            #[pin]
-            pinned: T,
-            unpinned: U,
-        },
-    }
-
-    impl<T, U> Struct1<T, U> {
-        fn get_pin_ref(self: Pin<&Self>) -> Pin<&T> {
-            self.project_ref().pinned
-        }
-        fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
-            self.project().pinned
-        }
-    }
-
-    impl<'b, T, U> Struct2<'b, T, U> {
-        fn get_pin_ref(self: Pin<&Self>) -> Pin<&&'b mut T> {
-            self.project_ref().pinned
-        }
-        fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut &'b mut T> {
-            self.project().pinned
-        }
-    }
-
-    impl<T, U> Enum<T, U> {
-        fn get_pin_ref(self: Pin<&Self>) -> Pin<&T> {
+        fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&T> {
             match self.project_ref() {
-                EnumProjRef::Variant { pinned, .. } => pinned,
+                EnumProjRef::V { pinned, .. } => pinned,
             }
         }
-        fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
+        fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut T> {
             match self.project() {
-                EnumProj::Variant { pinned, .. } => pinned,
+                EnumProj::V { pinned, .. } => pinned,
             }
         }
     }
@@ -516,19 +508,19 @@
     use pin_project::pin_project;
 
     #[pin_project(project_replace)]
-    pub(crate) struct A {
-        pub b: u8,
+    pub(crate) struct S {
+        pub f: u8,
     }
 }
 
 #[test]
 fn visibility() {
-    let mut x = visibility::A { b: 0 };
+    let mut x = visibility::S { f: 0 };
     let x = Pin::new(&mut x);
     let y = x.as_ref().project_ref();
-    let _: &u8 = y.b;
+    let _: &u8 = y.f;
     let y = x.project();
-    let _: &mut u8 = y.b;
+    let _: &mut u8 = y.f;
 }
 
 #[test]
@@ -536,45 +528,66 @@
     #[pin_project(project_replace)]
     pub struct NoGenerics {
         #[pin]
-        field: PhantomPinned,
+        f: PhantomPinned,
     }
+
+    assert_not_unpin!(NoGenerics);
 }
 
 #[test]
 fn dst() {
     #[pin_project]
     struct Struct1<T: ?Sized> {
-        x: T,
+        f: T,
     }
 
-    let mut x = Struct1 { x: 0_u8 };
+    let mut x = Struct1 { f: 0_u8 };
     let x: Pin<&mut Struct1<dyn core::fmt::Debug>> = Pin::new(&mut x as _);
-    let _y: &mut (dyn core::fmt::Debug) = x.project().x;
+    let _: &mut (dyn core::fmt::Debug) = x.project().f;
 
     #[pin_project]
     struct Struct2<T: ?Sized> {
         #[pin]
-        x: T,
+        f: T,
     }
 
-    let mut x = Struct2 { x: 0_u8 };
+    let mut x = Struct2 { f: 0_u8 };
     let x: Pin<&mut Struct2<dyn core::fmt::Debug + Unpin>> = Pin::new(&mut x as _);
-    let _y: Pin<&mut (dyn core::fmt::Debug + Unpin)> = x.project().x;
+    let _: Pin<&mut (dyn core::fmt::Debug + Unpin)> = x.project().f;
+
+    #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+    #[pin_project]
+    struct Struct3<T>
+    where
+        T: ?Sized,
+    {
+        f: T,
+    }
+
+    #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+    #[pin_project]
+    struct Struct4<T>
+    where
+        T: ?Sized,
+    {
+        #[pin]
+        f: T,
+    }
 
     #[pin_project(UnsafeUnpin)]
     struct Struct5<T: ?Sized> {
-        x: T,
+        f: T,
     }
 
     #[pin_project(UnsafeUnpin)]
     struct Struct6<T: ?Sized> {
         #[pin]
-        x: T,
+        f: T,
     }
 
     #[pin_project(PinnedDrop)]
     struct Struct7<T: ?Sized> {
-        x: T,
+        f: T,
     }
 
     #[pinned_drop]
@@ -585,7 +598,7 @@
     #[pin_project(PinnedDrop)]
     struct Struct8<T: ?Sized> {
         #[pin]
-        x: T,
+        f: T,
     }
 
     #[pinned_drop]
@@ -595,13 +608,19 @@
 
     #[pin_project(!Unpin)]
     struct Struct9<T: ?Sized> {
-        x: T,
+        f: T,
     }
 
     #[pin_project(!Unpin)]
     struct Struct10<T: ?Sized> {
         #[pin]
-        x: T,
+        f: T,
+    }
+
+    #[pin_project]
+    struct Struct11<'a, T: ?Sized, U: ?Sized> {
+        f1: &'a mut T,
+        f2: U,
     }
 
     #[pin_project]
@@ -610,6 +629,18 @@
     #[pin_project]
     struct TupleStruct2<T: ?Sized>(#[pin] T);
 
+    #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+    #[pin_project]
+    struct TupleStruct3<T>(T)
+    where
+        T: ?Sized;
+
+    #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+    #[pin_project]
+    struct TupleStruct4<T>(#[pin] T)
+    where
+        T: ?Sized;
+
     #[pin_project(UnsafeUnpin)]
     struct TupleStruct5<T: ?Sized>(T);
 
@@ -637,37 +668,9 @@
 
     #[pin_project(!Unpin)]
     struct TupleStruct10<T: ?Sized>(#[pin] T);
-}
-
-#[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
-#[test]
-fn unsized_in_where_clause() {
-    #[pin_project]
-    struct Struct3<T>
-    where
-        T: ?Sized,
-    {
-        x: T,
-    }
 
     #[pin_project]
-    struct Struct4<T>
-    where
-        T: ?Sized,
-    {
-        #[pin]
-        x: T,
-    }
-
-    #[pin_project]
-    struct TupleStruct3<T>(T)
-    where
-        T: ?Sized;
-
-    #[pin_project]
-    struct TupleStruct4<T>(#[pin] T)
-    where
-        T: ?Sized;
+    struct TupleStruct11<'a, T: ?Sized, U: ?Sized>(&'a mut T, U);
 }
 
 #[test]
@@ -775,7 +778,7 @@
         type Assoc = Self;
     }
 
-    #[pin_project(project_replace)]
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef, project_replace = EnumProjOwn)]
     enum Enum {
         Struct {
             _f1: Box<Self>,
@@ -809,19 +812,19 @@
 
 #[test]
 fn no_infer_outlives() {
-    trait Bar<X> {
+    trait Trait<X> {
         type Y;
     }
 
-    struct Example<A>(A);
+    struct Struct1<A>(A);
 
-    impl<X, T> Bar<X> for Example<T> {
+    impl<X, T> Trait<X> for Struct1<T> {
         type Y = Option<T>;
     }
 
     #[pin_project(project_replace)]
-    struct Foo<A, B> {
-        _x: <Example<A> as Bar<B>>::Y,
+    struct Struct2<A, B> {
+        _f: <Struct1<A> as Trait<B>>::Y,
     }
 }
 
@@ -830,8 +833,6 @@
 #[allow(clippy::many_single_char_names)]
 #[test]
 fn project_replace_panic() {
-    use std::panic;
-
     #[pin_project(project_replace)]
     struct S<T, U> {
         #[pin]
diff --git a/tests/pinned_drop.rs b/tests/pinned_drop.rs
index e257758..78b73dc 100644
--- a/tests/pinned_drop.rs
+++ b/tests/pinned_drop.rs
@@ -25,62 +25,9 @@
 }
 
 #[test]
-fn self_argument_in_macro() {
-    use pin_project::{pin_project, pinned_drop};
-    use std::pin::Pin;
-
-    #[pin_project(PinnedDrop)]
-    struct Struct {
-        x: (),
-    }
-
-    #[pinned_drop]
-    impl PinnedDrop for Struct {
-        fn drop(self: Pin<&mut Self>) {
-            let _: Vec<_> = vec![self.x];
-        }
-    }
-}
-
-#[test]
-fn self_in_macro_containing_fn() {
-    use pin_project::{pin_project, pinned_drop};
-    use std::pin::Pin;
-
-    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 _ = mac!({
-                impl Struct {
-                    pub fn _f(self) -> Self {
-                        self
-                    }
-                }
-            });
-        }
-    }
-}
-
-#[test]
 fn self_call() {
-    use pin_project::{pin_project, pinned_drop};
-    use std::pin::Pin;
-
     #[pin_project(PinnedDrop)]
-    pub struct Struct<T> {
-        _x: T,
-    }
+    pub struct S<T>(T);
 
     trait Trait {
         fn self_ref(&self) {}
@@ -90,10 +37,10 @@
         fn assoc_fn(_this: Pin<&mut Self>) {}
     }
 
-    impl<T> Trait for Struct<T> {}
+    impl<T> Trait for S<T> {}
 
     #[pinned_drop]
-    impl<T> PinnedDrop for Struct<T> {
+    impl<T> PinnedDrop for S<T> {
         fn drop(mut self: Pin<&mut Self>) {
             self.self_ref();
             self.as_ref().self_pin_ref();
@@ -106,13 +53,10 @@
 }
 
 #[test]
-fn self_struct() {
-    use pin_project::{pin_project, pinned_drop};
-    use std::pin::Pin;
-
+fn self_ty() {
     #[pin_project(PinnedDrop)]
     pub struct Struct {
-        pub x: (),
+        pub f: (),
     }
 
     #[pinned_drop]
@@ -121,14 +65,14 @@
         #[allow(clippy::match_single_binding)]
         fn drop(mut self: Pin<&mut Self>) {
             // expr
-            let _: Self = Self { x: () };
+            let _: Self = Self { f: () };
 
             // pat
             match *self {
-                Self { x: _ } => {}
+                Self { f: _ } => {}
             }
-            if let Self { x: _ } = *self {}
-            let Self { x: _ } = *self;
+            if let Self { f: _ } = *self {}
+            let Self { f: _ } = *self;
         }
     }
 
@@ -150,34 +94,56 @@
             let Self(_) = *self;
         }
     }
-}
 
-#[rustversion::since(1.37)] // type_alias_enum_variants requires Rust 1.37
-#[test]
-fn self_enum() {
-    use pin_project::{pin_project, pinned_drop};
-    use std::pin::Pin;
-
-    #[pin_project(PinnedDrop)]
+    #[pin_project(PinnedDrop, project = EnumProj, project_ref = EnumProjRef)]
     pub enum Enum {
-        Struct { x: () },
+        Struct { f: () },
         Tuple(()),
+        Unit,
     }
 
     #[pinned_drop]
     impl PinnedDrop for Enum {
         fn drop(mut self: Pin<&mut Self>) {
             // expr
-            let _: Self = Self::Struct { x: () };
+            let _: Self = Self::Struct { f: () };
             let _: Self = Self::Tuple(());
+            let _: Self = Self::Unit;
 
             // pat
             match *self {
-                Self::Struct { x: _ } => {}
+                Self::Struct { f: _ } => {}
                 Self::Tuple(_) => {}
+                Self::Unit => {}
             }
-            if let Self::Struct { x: _ } = *self {}
+            if let Self::Struct { f: _ } = *self {}
             if let Self::Tuple(_) = *self {}
+            if let Self::Unit = *self {}
+        }
+    }
+}
+
+#[test]
+fn self_inside_macro_containing_fn() {
+    macro_rules! mac {
+        ($($tt:tt)*) => {
+            $($tt)*
+        };
+    }
+
+    #[pin_project(PinnedDrop)]
+    pub struct S(());
+
+    #[pinned_drop]
+    impl PinnedDrop for S {
+        fn drop(self: Pin<&mut Self>) {
+            let _ = mac!({
+                impl S {
+                    pub fn _f(self) -> Self {
+                        self
+                    }
+                }
+            });
         }
     }
 }
@@ -185,21 +151,17 @@
 // See also `ui/pinned_drop/self.rs`.
 #[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;
-
+fn self_inside_macro_def() {
     #[pin_project(PinnedDrop)]
-    pub struct Struct {
-        _x: (),
-    }
+    pub struct S(());
 
     #[pinned_drop]
-    impl PinnedDrop for Struct {
+    impl PinnedDrop for S {
         fn drop(self: Pin<&mut Self>) {
             macro_rules! mac {
                 () => {{
                     let _ = self;
+                    let _ = Self(());
                 }};
             }
             mac!();
@@ -208,10 +170,22 @@
 }
 
 #[test]
-fn self_inside_macro() {
-    use pin_project::{pin_project, pinned_drop};
-    use std::pin::Pin;
+fn self_arg_inside_macro_call() {
+    #[pin_project(PinnedDrop)]
+    struct Struct {
+        f: (),
+    }
 
+    #[pinned_drop]
+    impl PinnedDrop for Struct {
+        fn drop(self: Pin<&mut Self>) {
+            let _: Vec<_> = vec![self.f];
+        }
+    }
+}
+
+#[test]
+fn self_ty_inside_macro_call() {
     macro_rules! mac {
         ($($tt:tt)*) => {
             $($tt)*
@@ -223,24 +197,24 @@
     where
         mac!(Self): Send,
     {
-        _x: T,
+        _f: T,
     }
 
     impl<T: Send> Struct<T> {
-        const ASSOCIATED1: &'static str = "1";
-        fn associated1() {}
+        const ASSOC1: usize = 1;
+        fn assoc1() {}
     }
 
     trait Trait {
-        type Associated2;
-        const ASSOCIATED2: &'static str;
-        fn associated2();
+        type Assoc2;
+        const ASSOC2: usize;
+        fn assoc2();
     }
 
     impl<T: Send> Trait for Struct<T> {
-        type Associated2 = ();
-        const ASSOCIATED2: &'static str = "2";
-        fn associated2() {}
+        type Assoc2 = ();
+        const ASSOC2: usize = 2;
+        fn assoc2() {}
     }
 
     #[pinned_drop]
@@ -252,38 +226,34 @@
         #[allow(clippy::no_effect)]
         fn drop(self: Pin<&mut Self>) {
             // inherent items
-            mac!(Self::ASSOCIATED1;);
-            mac!(<Self>::ASSOCIATED1;);
-            mac!(Self::associated1(););
-            mac!(<Self>::associated1(););
+            mac!(Self::ASSOC1;);
+            mac!(<Self>::ASSOC1;);
+            mac!(Self::assoc1(););
+            mac!(<Self>::assoc1(););
 
             // 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(););
+            mac!(let _: <Self as Trait>::Assoc2;);
+            mac!(Self::ASSOC2;);
+            mac!(<Self>::ASSOC2;);
+            mac!(<Self as Trait>::ASSOC2;);
+            mac!(Self::assoc2(););
+            mac!(<Self>::assoc2(););
+            mac!(<Self as Trait>::assoc2(););
         }
     }
 }
 
 #[test]
 fn inside_macro() {
-    use pin_project::{pin_project, pinned_drop};
-    use std::pin::Pin;
-
     #[pin_project(PinnedDrop)]
-    struct Struct(());
+    struct S(());
 
     macro_rules! mac {
         ($expr:expr) => {
             #[pinned_drop]
-            impl PinnedDrop for Struct {
-                #[allow(clippy::no_effect)]
+            impl PinnedDrop for S {
                 fn drop(self: Pin<&mut Self>) {
-                    $expr;
+                    let _ = $expr;
                 }
             }
         };
diff --git a/tests/project.rs b/tests/project.rs
deleted file mode 100644
index 78a9261..0000000
--- a/tests/project.rs
+++ /dev/null
@@ -1,298 +0,0 @@
-#![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(..)]`
-//
-// This trick makes sure that we don't even attempt to parse
-// the `#[project] if let _` test on MSRV.
-#[rustversion::since(1.43)]
-include!("project_if_attr.rs.in");
-
-use pin_project::{pin_project, project, project_ref, project_replace};
-use std::pin::Pin;
-
-#[project] // Nightly does not need a dummy attribute to the function.
-#[test]
-fn project_stmt_expr() {
-    #[pin_project]
-    struct Struct<T, U> {
-        #[pin]
-        field1: T,
-        field2: U,
-    }
-
-    let mut s = Struct { field1: 1, field2: 2 };
-
-    #[project]
-    let Struct { field1, field2 } = Pin::new(&mut s).project();
-
-    let x: Pin<&mut i32> = field1;
-    assert_eq!(*x, 1);
-
-    let y: &mut i32 = field2;
-    assert_eq!(*y, 2);
-
-    #[pin_project]
-    struct TupleStruct<T, U>(#[pin] T, U);
-
-    let mut s = TupleStruct(1, 2);
-
-    #[project]
-    let TupleStruct(x, y) = Pin::new(&mut s).project();
-
-    let x: Pin<&mut i32> = x;
-    assert_eq!(*x, 1);
-
-    let y: &mut i32 = y;
-    assert_eq!(*y, 2);
-
-    #[pin_project]
-    enum Enum<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
-            #[pin]
-            field1: C,
-            field2: D,
-        },
-        None,
-    }
-
-    let mut e = Enum::Variant1(1, 2);
-
-    let mut e = Pin::new(&mut e).project();
-
-    #[project]
-    match &mut e {
-        Enum::Variant1(x, y) => {
-            let x: &mut Pin<&mut i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &mut &mut i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Enum::Variant2 { field1, field2 } => {
-            let _x: &mut Pin<&mut i32> = field1;
-            let _y: &mut &mut i32 = field2;
-        }
-        Enum::None => {}
-    }
-
-    #[project]
-    let val = match &mut e {
-        Enum::Variant1(_, _) => true,
-        Enum::Variant2 { .. } => false,
-        Enum::None => false,
-    };
-    assert_eq!(val, true);
-}
-
-#[test]
-fn project_impl() {
-    #[pin_project]
-    struct HasGenerics<T, U> {
-        #[pin]
-        field1: T,
-        field2: U,
-    }
-
-    #[project]
-    impl<T, U> HasGenerics<T, U> {
-        fn a(self) {
-            let Self { field1, field2 } = self;
-
-            let _x: Pin<&mut T> = field1;
-            let _y: &mut U = field2;
-        }
-    }
-
-    #[pin_project]
-    struct NoneGenerics {
-        #[pin]
-        field1: i32,
-        field2: u32,
-    }
-
-    #[project]
-    impl NoneGenerics {}
-
-    #[pin_project]
-    struct HasLifetimes<'a, T, U> {
-        #[pin]
-        field1: &'a mut T,
-        field2: U,
-    }
-
-    #[project]
-    impl<T, U> HasLifetimes<'_, T, U> {}
-
-    #[pin_project]
-    struct HasOverlappingLifetimes<'pin, T, U> {
-        #[pin]
-        field1: &'pin mut T,
-        field2: U,
-    }
-
-    #[allow(single_use_lifetimes)]
-    #[project]
-    impl<'pin, T, U> HasOverlappingLifetimes<'pin, T, U> {}
-
-    #[pin_project]
-    struct HasOverlappingLifetimes2<T, U> {
-        #[pin]
-        field1: T,
-        field2: U,
-    }
-
-    #[allow(single_use_lifetimes)]
-    #[allow(clippy::needless_lifetimes)]
-    #[project]
-    impl<T, U> HasOverlappingLifetimes2<T, U> {
-        fn foo<'pin>(&'pin self) {}
-    }
-}
-
-#[pin_project]
-struct A {
-    #[pin]
-    field: u8,
-}
-
-mod project_use_1 {
-    use crate::A;
-    use pin_project::project;
-    use std::pin::Pin;
-
-    #[project]
-    use crate::A;
-
-    #[project]
-    #[test]
-    fn project_use() {
-        let mut x = A { field: 0 };
-        #[project]
-        let A { field } = Pin::new(&mut x).project();
-        let _: Pin<&mut u8> = field;
-    }
-}
-
-mod project_use_2 {
-    #[project]
-    use crate::A;
-    use pin_project::project;
-
-    #[project]
-    impl A {
-        fn project_use(self) {}
-    }
-}
-
-#[allow(clippy::unnecessary_operation, clippy::unit_arg)]
-#[test]
-#[project]
-fn non_stmt_expr_match() {
-    #[pin_project]
-    enum Enum<A> {
-        Variant(#[pin] A),
-    }
-
-    let mut x = Enum::Variant(1);
-    let x = Pin::new(&mut x).project();
-
-    Some(
-        #[project]
-        match x {
-            Enum::Variant(_x) => {}
-        },
-    );
-}
-
-// https://github.com/taiki-e/pin-project/issues/206
-#[allow(clippy::unnecessary_operation, clippy::unit_arg)]
-#[test]
-#[project]
-fn issue_206() {
-    #[pin_project]
-    enum Enum<A> {
-        Variant(#[pin] A),
-    }
-
-    let mut x = Enum::Variant(1);
-    let x = Pin::new(&mut x).project();
-
-    Some({
-        #[project]
-        match &x {
-            Enum::Variant(_) => {}
-        }
-    });
-
-    #[allow(clippy::never_loop)]
-    loop {
-        let _ = {
-            #[project]
-            match &x {
-                Enum::Variant(_) => {}
-            }
-        };
-        break;
-    }
-}
-
-#[project]
-#[test]
-fn combine() {
-    #[pin_project(project_replace)]
-    enum Enum<A> {
-        V1(#[pin] A),
-        V2,
-    }
-
-    let mut x = Enum::V1(1);
-    #[project]
-    match Pin::new(&mut x).project() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_ref]
-    match Pin::new(&x).project_ref() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_replace]
-    match Pin::new(&mut x).project_replace(Enum::V2) {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-}
-
-// FIXME: This should be denied, but allowed for compatibility at this time.
-#[project]
-#[project_ref]
-#[project_replace]
-#[test]
-fn combine_compat() {
-    #[pin_project(project_replace)]
-    enum Enum<A> {
-        V1(#[pin] A),
-        V2,
-    }
-
-    let mut x = Enum::V1(1);
-    #[project]
-    match Pin::new(&mut x).project() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_ref]
-    match Pin::new(&x).project_ref() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_replace]
-    match Pin::new(&mut x).project_replace(Enum::V2) {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-}
diff --git a/tests/project_if_attr.rs.in b/tests/project_if_attr.rs.in
deleted file mode 100644
index 7bc236d..0000000
--- a/tests/project_if_attr.rs.in
+++ /dev/null
@@ -1,45 +0,0 @@
-#[test]
-#[project]
-fn project_if_let() {
-    #[pin_project]
-    enum Foo<A, B> {
-        Variant1(#[pin] A),
-        Variant2(u8),
-        Variant3 {
-            #[pin]
-            field: B,
-        },
-    }
-
-    let mut x: Foo<bool, f32> = Foo::Variant1(true);
-    let x = Pin::new(&mut x).project();
-
-    #[project]
-    if let Foo::Variant1(a) = x {
-        let a: Pin<&mut bool> = a;
-        assert_eq!(*a, true);
-    } else if let Foo::Variant2(_) = x {
-        unreachable!();
-    } else if let Foo::Variant3 { .. } = x {
-        unreachable!();
-    }
-}
-
-#[allow(clippy::unnecessary_operation, clippy::unit_arg)]
-#[test]
-#[project]
-fn non_stmt_expr_if_let() {
-    #[pin_project]
-    enum Enum<A> {
-        Variant(#[pin] A),
-    }
-
-    let mut x = Enum::Variant(1);
-    let x = Pin::new(&mut x).project();
-
-    #[allow(irrefutable_let_patterns)]
-    Some(
-        #[project]
-        if let Enum::Variant(_x) = x {},
-    );
-}
diff --git a/tests/project_ref.rs b/tests/project_ref.rs
deleted file mode 100644
index 0e8ebd9..0000000
--- a/tests/project_ref.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-#![allow(dead_code)]
-#![allow(deprecated)]
-
-use pin_project::{pin_project, project_ref};
-use std::pin::Pin;
-
-#[project_ref] // Nightly does not need a dummy attribute to the function.
-#[test]
-fn project_stmt_expr() {
-    #[pin_project]
-    struct Struct<T, U> {
-        #[pin]
-        field1: T,
-        field2: U,
-    }
-
-    let s = Struct { field1: 1, field2: 2 };
-
-    #[project_ref]
-    let Struct { field1, field2 } = Pin::new(&s).project_ref();
-
-    let x: Pin<&i32> = field1;
-    assert_eq!(*x, 1);
-
-    let y: &i32 = field2;
-    assert_eq!(*y, 2);
-
-    // tuple struct
-
-    #[pin_project]
-    struct TupleStruct<T, U>(#[pin] T, U);
-
-    let s = TupleStruct(1, 2);
-
-    #[project_ref]
-    let TupleStruct(x, y) = Pin::new(&s).project_ref();
-
-    let x: Pin<&i32> = x;
-    assert_eq!(*x, 1);
-
-    let y: &i32 = y;
-    assert_eq!(*y, 2);
-
-    #[pin_project]
-    enum Enum<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
-            #[pin]
-            field1: C,
-            field2: D,
-        },
-        None,
-    }
-
-    let e = Enum::Variant1(1, 2);
-
-    let e = Pin::new(&e).project_ref();
-
-    #[project_ref]
-    match &e {
-        Enum::Variant1(x, y) => {
-            let x: &Pin<&i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &&i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Enum::Variant2 { field1, field2 } => {
-            let _x: &Pin<&i32> = field1;
-            let _y: &&i32 = field2;
-        }
-        Enum::None => {}
-    }
-
-    #[project_ref]
-    let val = match &e {
-        Enum::Variant1(_, _) => true,
-        Enum::Variant2 { .. } => false,
-        Enum::None => false,
-    };
-    assert_eq!(val, true);
-}
-
-#[test]
-fn project_impl() {
-    #[pin_project]
-    struct HasGenerics<T, U> {
-        #[pin]
-        field1: T,
-        field2: U,
-    }
-
-    #[project_ref]
-    impl<T, U> HasGenerics<T, U> {
-        fn a(self) {
-            let Self { field1, field2 } = self;
-
-            let _x: Pin<&T> = field1;
-            let _y: &U = field2;
-        }
-    }
-
-    #[pin_project]
-    struct NoneGenerics {
-        #[pin]
-        field1: i32,
-        field2: u32,
-    }
-
-    #[project_ref]
-    impl NoneGenerics {}
-
-    #[pin_project]
-    struct HasLifetimes<'a, T, U> {
-        #[pin]
-        field1: &'a mut T,
-        field2: U,
-    }
-
-    #[project_ref]
-    impl<T, U> HasLifetimes<'_, T, U> {}
-
-    #[pin_project]
-    struct HasOverlappingLifetimes<'pin, T, U> {
-        #[pin]
-        field1: &'pin mut T,
-        field2: U,
-    }
-
-    #[allow(single_use_lifetimes)]
-    #[project_ref]
-    impl<'pin, T, U> HasOverlappingLifetimes<'pin, T, U> {}
-
-    #[pin_project]
-    struct HasOverlappingLifetimes2<T, U> {
-        #[pin]
-        field1: T,
-        field2: U,
-    }
-
-    #[allow(single_use_lifetimes)]
-    #[allow(clippy::needless_lifetimes)]
-    #[project_ref]
-    impl<T, U> HasOverlappingLifetimes2<T, U> {
-        fn foo<'pin>(&'pin self) {}
-    }
-}
-
-#[project_ref]
-#[test]
-fn combine() {
-    #[pin_project(project_replace)]
-    enum Enum<A> {
-        V1(#[pin] A),
-        V2,
-    }
-
-    let mut x = Enum::V1(1);
-    #[project]
-    match Pin::new(&mut x).project() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_ref]
-    match Pin::new(&x).project_ref() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_replace]
-    match Pin::new(&mut x).project_replace(Enum::V2) {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-}
diff --git a/tests/project_replace.rs b/tests/project_replace.rs
deleted file mode 100644
index a97e3af..0000000
--- a/tests/project_replace.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-#![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};
-
-#[project_replace] // Nightly does not need a dummy attribute to the function.
-#[test]
-fn project_replace_stmt_expr() {
-    #[pin_project(project_replace)]
-    struct Struct<T, U> {
-        #[pin]
-        field1: T,
-        field2: U,
-    }
-
-    let mut s = Struct { field1: 1, field2: 2 };
-
-    #[project_replace]
-    let Struct { field1, field2 } =
-        Pin::new(&mut s).project_replace(Struct { field1: 42, field2: 43 });
-
-    let _x: PhantomData<i32> = field1;
-
-    let y: i32 = field2;
-    assert_eq!(y, 2);
-
-    // tuple struct
-
-    #[pin_project(project_replace)]
-    struct TupleStruct<T, U>(#[pin] T, U);
-
-    let mut s = TupleStruct(1, 2);
-
-    #[project_replace]
-    let TupleStruct(x, y) = Pin::new(&mut s).project_replace(TupleStruct(42, 43));
-
-    let _x: PhantomData<i32> = x;
-    let y: i32 = y;
-    assert_eq!(y, 2);
-
-    #[pin_project(project_replace)]
-    enum Enum<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
-            #[pin]
-            field1: C,
-            field2: D,
-        },
-        None,
-    }
-
-    let mut e = Enum::Variant1(1, 2);
-
-    let e = Pin::new(&mut e).project_replace(Enum::None);
-
-    #[project_replace]
-    match e {
-        Enum::Variant1(x, y) => {
-            let _x: PhantomData<i32> = x;
-            let y: i32 = y;
-            assert_eq!(y, 2);
-        }
-        Enum::Variant2 { field1, field2 } => {
-            let _x: PhantomData<i32> = field1;
-            let _y: i32 = field2;
-            panic!()
-        }
-        Enum::None => panic!(),
-    }
-}
-
-#[project_replace]
-#[test]
-fn combine() {
-    #[pin_project(project_replace)]
-    enum Enum<A> {
-        V1(#[pin] A),
-        V2,
-    }
-
-    let mut x = Enum::V1(1);
-    #[project]
-    match Pin::new(&mut x).project() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_ref]
-    match Pin::new(&x).project_ref() {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-    #[project_replace]
-    match Pin::new(&mut x).project_replace(Enum::V2) {
-        Enum::V1(_) => {}
-        Enum::V2 => unreachable!(),
-    }
-}
diff --git a/tests/proper_unpin.rs b/tests/proper_unpin.rs
new file mode 100644
index 0000000..8873572
--- /dev/null
+++ b/tests/proper_unpin.rs
@@ -0,0 +1,149 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+#[macro_use]
+mod auxiliary;
+
+pub mod default {
+    use pin_project::pin_project;
+    use std::marker::PhantomPinned;
+
+    struct Inner<T> {
+        f: T,
+    }
+
+    assert_unpin!(Inner<()>);
+    assert_not_unpin!(Inner<PhantomPinned>);
+
+    #[pin_project]
+    struct Struct<T, U> {
+        #[pin]
+        f1: Inner<T>,
+        f2: U,
+    }
+
+    assert_unpin!(Struct<(), ()>);
+    assert_unpin!(Struct<(), PhantomPinned>);
+    assert_not_unpin!(Struct<PhantomPinned, ()>);
+    assert_not_unpin!(Struct<PhantomPinned, PhantomPinned>);
+
+    #[pin_project(project = EnumProj, project_ref = EnumProjRef)]
+    enum Enum<T, U> {
+        V1 {
+            #[pin]
+            f1: Inner<T>,
+            f2: U,
+        },
+    }
+
+    assert_unpin!(Enum<(), ()>);
+    assert_unpin!(Enum<(), PhantomPinned>);
+    assert_not_unpin!(Enum<PhantomPinned, ()>);
+    assert_not_unpin!(Enum<PhantomPinned, PhantomPinned>);
+
+    #[pin_project]
+    struct TrivialBounds {
+        #[pin]
+        f: PhantomPinned,
+    }
+
+    assert_not_unpin!(TrivialBounds);
+
+    #[pin_project]
+    struct PinRef<'a, T, U> {
+        #[pin]
+        f1: &'a mut Inner<T>,
+        f2: U,
+    }
+
+    assert_unpin!(PinRef<'_, PhantomPinned, PhantomPinned>);
+}
+
+pub mod cfg {
+    use pin_project::pin_project;
+    use std::marker::PhantomPinned;
+
+    #[pin_project]
+    struct Foo<T> {
+        #[cfg(any())]
+        #[pin]
+        f: T,
+        #[cfg(not(any()))]
+        f: T,
+    }
+
+    assert_unpin!(Foo<PhantomPinned>);
+
+    #[pin_project]
+    struct Bar<T> {
+        #[cfg(any())]
+        f: T,
+        #[cfg(not(any()))]
+        #[pin]
+        f: T,
+    }
+
+    assert_unpin!(Bar<()>);
+    assert_not_unpin!(Bar<PhantomPinned>);
+}
+
+pub mod cfg_attr {
+    use pin_project::pin_project;
+    use std::marker::PhantomPinned;
+
+    #[cfg_attr(any(), pin_project)]
+    struct Foo<T> {
+        f: T,
+    }
+
+    assert_unpin!(Foo<()>);
+    assert_not_unpin!(Foo<PhantomPinned>);
+
+    #[cfg_attr(not(any()), pin_project)]
+    struct Bar<T> {
+        #[cfg_attr(not(any()), pin)]
+        f: T,
+    }
+
+    assert_unpin!(Bar<()>);
+    assert_not_unpin!(Bar<PhantomPinned>);
+}
+
+// pin_project(!Unpin)
+pub mod not_unpin {
+    use pin_project::pin_project;
+    use std::marker::PhantomPinned;
+
+    struct Inner<T> {
+        f: T,
+    }
+
+    #[pin_project(!Unpin)]
+    struct Struct<T, U> {
+        #[pin]
+        inner: Inner<T>,
+        other: U,
+    }
+
+    assert_not_unpin!(Struct<(), ()>);
+    assert_not_unpin!(Struct<(), PhantomPinned>);
+    assert_not_unpin!(Struct<PhantomPinned, ()>);
+    assert_not_unpin!(Struct<PhantomPinned, PhantomPinned>);
+
+    #[pin_project(!Unpin)]
+    struct TrivialBounds {
+        #[pin]
+        f: PhantomPinned,
+    }
+
+    assert_not_unpin!(TrivialBounds);
+
+    #[pin_project(!Unpin)]
+    struct PinRef<'a, T, U> {
+        #[pin]
+        inner: &'a mut Inner<T>,
+        other: U,
+    }
+
+    assert_not_unpin!(PinRef<'_, (), ()>);
+}
diff --git a/tests/repr_packed.rs b/tests/repr_packed.rs
index 73fc45c..a0d8bdc 100644
--- a/tests/repr_packed.rs
+++ b/tests/repr_packed.rs
@@ -1,5 +1,5 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
-#![deny(safe_packed_borrows)]
+#![forbid(safe_packed_borrows)]
 
 use std::cell::Cell;
 
@@ -22,11 +22,11 @@
     }
 
     #[repr(packed)]
-    struct Foo {
+    struct Struct {
         field: u8,
     }
 
-    impl Drop for Foo {
+    impl Drop for Struct {
         fn drop(&mut self) {
             FIELD_ADDR.with(|f| {
                 f.set(&self.field as *const u8 as usize);
@@ -41,7 +41,7 @@
         // Calling drop(foo) causes 'foo' to be moved
         // into the 'drop' function, resulting in a different
         // address.
-        let x = Foo { field: 27 };
+        let x = Struct { field: 27 };
         let field_addr = &x.field as *const u8 as usize;
         field_addr
     };
diff --git a/tests/sized.rs b/tests/sized.rs
deleted file mode 100644
index 9fd7e2b..0000000
--- a/tests/sized.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#![warn(rust_2018_idioms, single_use_lifetimes)]
-#![allow(dead_code)]
-
-use pin_project::pin_project;
-
-#[pin_project]
-struct Foo<'a, I: ?Sized, Item>
-where
-    I: Iterator,
-{
-    iter: &'a mut I,
-    item: Option<Item>,
-}
diff --git a/tests/ui/cfg/cfg_attr-resolve.rs b/tests/ui/cfg/cfg_attr-resolve.rs
index e16f3e8..e36cc95 100644
--- a/tests/ui/cfg/cfg_attr-resolve.rs
+++ b/tests/ui/cfg/cfg_attr-resolve.rs
@@ -2,10 +2,10 @@
 
 #[cfg_attr(any(), pin_project::pin_project)]
 struct Foo<T> {
-    inner: T,
+    f: T,
 }
 
 fn main() {
-    let mut x = Foo { inner: 0_u8 };
-    let _x = Pin::new(&mut x).project(); //~ ERROR E0599
+    let mut x = Foo { f: 0_u8 };
+    let _ = Pin::new(&mut x).project(); //~ ERROR E0599
 }
diff --git a/tests/ui/cfg/cfg_attr-resolve.stderr b/tests/ui/cfg/cfg_attr-resolve.stderr
index 45af3ae..12bcc67 100644
--- a/tests/ui/cfg/cfg_attr-resolve.stderr
+++ b/tests/ui/cfg/cfg_attr-resolve.stderr
@@ -1,5 +1,5 @@
-error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Foo<u8>>` in the current scope
-  --> $DIR/cfg_attr-resolve.rs:10:31
+error[E0599]: no method named `project` found for struct `Pin<&mut Foo<u8>>` in the current scope
+  --> $DIR/cfg_attr-resolve.rs:10:30
    |
-10 |     let _x = Pin::new(&mut x).project(); //~ ERROR E0599
-   |                               ^^^^^^^ method not found in `std::pin::Pin<&mut Foo<u8>>`
+10 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0599
+   |                              ^^^^^^^ method not found in `Pin<&mut Foo<u8>>`
diff --git a/tests/ui/cfg/cfg_attr-type-mismatch.rs b/tests/ui/cfg/cfg_attr-type-mismatch.rs
index 2807c87..b075af9 100644
--- a/tests/ui/cfg/cfg_attr-type-mismatch.rs
+++ b/tests/ui/cfg/cfg_attr-type-mismatch.rs
@@ -4,21 +4,21 @@
 #[cfg_attr(not(any()), pin_project)]
 struct Foo<T> {
     #[cfg_attr(any(), pin)]
-    inner: T,
+    f: T,
 }
 
 #[cfg_attr(not(any()), pin_project)]
 struct Bar<T> {
     #[cfg_attr(not(any()), pin)]
-    inner: T,
+    f: T,
 }
 
 fn main() {
-    let mut x = Foo { inner: 0_u8 };
+    let mut x = Foo { f: 0_u8 };
     let x = Pin::new(&mut x).project();
-    let _: Pin<&mut u8> = x.inner; //~ ERROR E0308
+    let _: Pin<&mut u8> = x.f; //~ ERROR E0308
 
-    let mut x = Bar { inner: 0_u8 };
+    let mut x = Bar { f: 0_u8 };
     let x = Pin::new(&mut x).project();
-    let _: &mut u8 = x.inner; //~ ERROR E0308
+    let _: &mut u8 = x.f; //~ ERROR E0308
 }
diff --git a/tests/ui/cfg/cfg_attr-type-mismatch.stderr b/tests/ui/cfg/cfg_attr-type-mismatch.stderr
index 2868299..89172a2 100644
--- a/tests/ui/cfg/cfg_attr-type-mismatch.stderr
+++ b/tests/ui/cfg/cfg_attr-type-mismatch.stderr
@@ -1,23 +1,23 @@
 error[E0308]: mismatched types
   --> $DIR/cfg_attr-type-mismatch.rs:19:27
    |
-19 |     let _: Pin<&mut u8> = x.inner; //~ ERROR E0308
-   |            ------------   ^^^^^^^ expected struct `std::pin::Pin`, found `&mut u8`
+19 |     let _: Pin<&mut u8> = x.f; //~ ERROR E0308
+   |            ------------   ^^^ expected struct `Pin`, found `&mut u8`
    |            |
    |            expected due to this
    |
-   = note:         expected struct `std::pin::Pin<&mut u8>`
+   = note:         expected struct `Pin<&mut u8>`
            found mutable reference `&mut u8`
 
 error[E0308]: mismatched types
   --> $DIR/cfg_attr-type-mismatch.rs:23:22
    |
-23 |     let _: &mut u8 = x.inner; //~ ERROR E0308
-   |            -------   ^^^^^^^
+23 |     let _: &mut u8 = x.f; //~ ERROR E0308
+   |            -------   ^^^
    |            |         |
-   |            |         expected `&mut u8`, found struct `std::pin::Pin`
-   |            |         help: consider mutably borrowing here: `&mut x.inner`
+   |            |         expected `&mut u8`, found struct `Pin`
+   |            |         help: consider mutably borrowing here: `&mut x.f`
    |            expected due to this
    |
    = note: expected mutable reference `&mut u8`
-                         found struct `std::pin::Pin<&mut u8>`
+                         found struct `Pin<&mut u8>`
diff --git a/tests/ui/cfg/cfg_attr-unpin.rs b/tests/ui/cfg/cfg_attr-unpin.rs
deleted file mode 100644
index 7b88205..0000000
--- a/tests/ui/cfg/cfg_attr-unpin.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use pin_project::pin_project;
-use std::marker::PhantomPinned;
-
-#[cfg_attr(any(), pin_project)]
-struct Foo<T> {
-    inner: T,
-}
-
-#[cfg_attr(not(any()), pin_project)]
-struct Bar<T> {
-    #[cfg_attr(not(any()), pin)]
-    inner: T,
-}
-
-fn is_unpin<T: Unpin>() {}
-
-fn main() {
-    is_unpin::<Foo<PhantomPinned>>(); // ERROR E0277
-    is_unpin::<Bar<()>>(); // Ok
-    is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
-}
diff --git a/tests/ui/cfg/cfg_attr-unpin.stderr b/tests/ui/cfg/cfg_attr-unpin.stderr
deleted file mode 100644
index 45789ff..0000000
--- a/tests/ui/cfg/cfg_attr-unpin.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/cfg_attr-unpin.rs:18:5
-   |
-15 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-18 |     is_unpin::<Foo<PhantomPinned>>(); // ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `Foo<std::marker::PhantomPinned>`
-
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/cfg_attr-unpin.rs:20:5
-   |
-15 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-20 |     is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `_::__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/packed_sneaky-span-issue-1.rs b/tests/ui/cfg/packed_sneaky-span-issue-1.rs
index 3776dac..8455d07 100644
--- a/tests/ui/cfg/packed_sneaky-span-issue-1.rs
+++ b/tests/ui/cfg/packed_sneaky-span-issue-1.rs
@@ -1,4 +1,4 @@
-use auxiliary_macros::hidden_repr;
+use auxiliary_macro::hidden_repr;
 use pin_project::pin_project;
 
 //~ ERROR may not be used on #[repr(packed)] types
@@ -6,13 +6,13 @@
 // Refs: https://github.com/rust-lang/rust/issues/43081
 #[pin_project]
 #[hidden_repr(packed)]
-struct Foo {
+struct S {
     #[cfg(not(any()))]
     #[pin]
-    field: u32,
+    f: u32,
     #[cfg(any())]
     #[pin]
-    field: u8,
+    f: u8,
 }
 
 fn main() {}
diff --git a/tests/ui/cfg/packed_sneaky-span-issue-2.rs b/tests/ui/cfg/packed_sneaky-span-issue-2.rs
index aa65d33..01706ee 100644
--- a/tests/ui/cfg/packed_sneaky-span-issue-2.rs
+++ b/tests/ui/cfg/packed_sneaky-span-issue-2.rs
@@ -1,4 +1,4 @@
-use auxiliary_macros::hidden_repr;
+use auxiliary_macro::hidden_repr;
 use pin_project::pin_project;
 
 //~ ERROR may not be used on #[repr(packed)] types
@@ -6,13 +6,13 @@
 // Refs: https://github.com/rust-lang/rust/issues/43081
 #[pin_project]
 #[hidden_repr(packed)]
-struct Foo {
+struct S {
     #[cfg(any())]
     #[pin]
-    field: u32,
+    f: u32,
     #[cfg(not(any()))]
     #[pin]
-    field: u8,
+    f: u8,
 }
 
 fn main() {}
diff --git a/tests/ui/cfg/packed_sneaky.rs b/tests/ui/cfg/packed_sneaky.rs
index 3305ed3..0b01dc9 100644
--- a/tests/ui/cfg/packed_sneaky.rs
+++ b/tests/ui/cfg/packed_sneaky.rs
@@ -1,12 +1,12 @@
-use auxiliary_macros::hidden_repr_cfg_not_any;
+use auxiliary_macro::hidden_repr_cfg_not_any;
 use pin_project::pin_project;
 
 // `#[hidden_repr_cfg_not_any(packed)]` generates `#[cfg_attr(not(any()), repr(packed))]`.
 #[pin_project]
 #[hidden_repr_cfg_not_any(packed)] //~ ERROR may not be used on #[repr(packed)] types
-struct Foo {
+struct S {
     #[pin]
-    field: u32,
+    f: u32,
 }
 
 fn main() {}
diff --git a/tests/ui/cfg/packed_sneaky.stderr b/tests/ui/cfg/packed_sneaky.stderr
index 5910cf4..b0d4d93 100644
--- a/tests/ui/cfg/packed_sneaky.stderr
+++ b/tests/ui/cfg/packed_sneaky.stderr
@@ -1,7 +1,5 @@
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
- --> $DIR/packed_sneaky.rs:6:1
+ --> $DIR/packed_sneaky.rs:6:27
   |
 6 | #[hidden_repr_cfg_not_any(packed)] //~ ERROR may not be used on #[repr(packed)] types
-  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  |
-  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+  |                           ^^^^^^
diff --git a/tests/ui/cfg/proper_unpin.rs b/tests/ui/cfg/proper_unpin.rs
deleted file mode 100644
index b7bb04d..0000000
--- a/tests/ui/cfg/proper_unpin.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-use pin_project::pin_project;
-use std::marker::PhantomPinned;
-
-#[pin_project]
-struct Foo<T> {
-    #[cfg(any())]
-    #[pin]
-    inner: T,
-    #[cfg(not(any()))]
-    inner: T,
-}
-
-#[pin_project]
-struct Bar<T> {
-    #[cfg(any())]
-    inner: T,
-    #[cfg(not(any()))]
-    #[pin]
-    inner: T,
-}
-
-fn is_unpin<T: Unpin>() {}
-
-fn main() {
-    is_unpin::<Foo<PhantomPinned>>(); // Ok
-    is_unpin::<Bar<()>>(); // Ok
-    is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
-}
diff --git a/tests/ui/cfg/proper_unpin.stderr b/tests/ui/cfg/proper_unpin.stderr
deleted file mode 100644
index f1fff34..0000000
--- a/tests/ui/cfg/proper_unpin.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/proper_unpin.rs:27:5
-   |
-22 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-27 |     is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `_::__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/unsupported.rs b/tests/ui/cfg/unsupported.rs
index 5205307..c450f6f 100644
--- a/tests/ui/cfg/unsupported.rs
+++ b/tests/ui/cfg/unsupported.rs
@@ -4,7 +4,7 @@
 // span is lost.
 // Refs: https://github.com/rust-lang/rust/issues/43081
 #[pin_project]
-struct Struct {
+struct S {
     #[cfg(any())]
     #[pin]
     f: u8,
diff --git a/tests/ui/not_unpin/assert-not-unpin.rs b/tests/ui/not_unpin/assert-not-unpin.rs
deleted file mode 100644
index b8f8238..0000000
--- a/tests/ui/not_unpin/assert-not-unpin.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use pin_project::pin_project;
-use std::marker::PhantomPinned;
-
-struct Inner<T> {
-    val: T,
-}
-
-#[pin_project(!Unpin)]
-struct Foo<T, U> {
-    #[pin]
-    inner: Inner<T>,
-    other: U,
-}
-
-#[pin_project(!Unpin)]
-struct TrivialBounds {
-    #[pin]
-    field1: PhantomPinned,
-}
-
-#[pin_project(!Unpin)]
-struct Bar<'a, T, U> {
-    #[pin]
-    inner: &'a mut Inner<T>,
-    other: U,
-}
-
-fn is_unpin<T: Unpin>() {}
-
-fn main() {
-    is_unpin::<Foo<(), ()>>(); //~ ERROR E0277
-    is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
-    is_unpin::<Foo<(), PhantomPinned>>(); //~ ERROR E0277
-    is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-
-    is_unpin::<TrivialBounds>(); //~ ERROR E0277
-
-    is_unpin::<Bar<'_, (), ()>>(); //~ ERROR E0277
-    is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-}
diff --git a/tests/ui/not_unpin/assert-not-unpin.stderr b/tests/ui/not_unpin/assert-not-unpin.stderr
deleted file mode 100644
index 5e323fc..0000000
--- a/tests/ui/not_unpin/assert-not-unpin.stderr
+++ /dev/null
@@ -1,83 +0,0 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/assert-not-unpin.rs:31:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-31 |     is_unpin::<Foo<(), ()>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ within `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because it appears within the type `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<(), ()>`
-
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/assert-not-unpin.rs:32:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-32 |     is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because it appears within the type `pin_project::__private::Wrapper<'_, 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
-  --> $DIR/assert-not-unpin.rs:33:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-33 |     is_unpin::<Foo<(), PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because it appears within the type `pin_project::__private::Wrapper<'_, 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
-  --> $DIR/assert-not-unpin.rs:34:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-34 |     is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because it appears within the type `pin_project::__private::Wrapper<'_, 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
-  --> $DIR/assert-not-unpin.rs:36:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-36 |     is_unpin::<TrivialBounds>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ within `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because it appears within the type `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
-
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/assert-not-unpin.rs:38:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-38 |     is_unpin::<Bar<'_, (), ()>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because it appears within the type `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<'_, (), ()>`
-
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/assert-not-unpin.rs:39:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-39 |     is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because it appears within the type `pin_project::__private::Wrapper<'_, std::marker::PhantomPinned>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
diff --git a/tests/ui/not_unpin/conflict-unpin.rs b/tests/ui/not_unpin/conflict-unpin.rs
index f259f6c..8985f37 100644
--- a/tests/ui/not_unpin/conflict-unpin.rs
+++ b/tests/ui/not_unpin/conflict-unpin.rs
@@ -3,8 +3,8 @@
 #[pin_project(!Unpin)] //~ ERROR E0119
 struct Foo<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 impl<T, U> Unpin for Foo<T, U> where T: Unpin {}
@@ -12,8 +12,8 @@
 #[pin_project(!Unpin)] //~ ERROR E0119
 struct Bar<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 impl<T, U> Unpin for Bar<T, U> {}
@@ -21,8 +21,8 @@
 #[pin_project(!Unpin)] //~ ERROR E0119
 struct Baz<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {}
diff --git a/tests/ui/not_unpin/impl-unsafe-unpin.rs b/tests/ui/not_unpin/impl-unsafe-unpin.rs
index 625dc29..2c078c7 100644
--- a/tests/ui/not_unpin/impl-unsafe-unpin.rs
+++ b/tests/ui/not_unpin/impl-unsafe-unpin.rs
@@ -3,8 +3,8 @@
 #[pin_project(!Unpin)] //~ ERROR E0119
 struct Foo<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 unsafe impl<T, U> UnsafeUnpin for Foo<T, U> where T: Unpin {}
@@ -12,8 +12,8 @@
 #[pin_project(!Unpin)] //~ ERROR E0119
 struct Bar<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 unsafe impl<T, U> UnsafeUnpin for Bar<T, U> {}
@@ -21,8 +21,8 @@
 #[pin_project(!Unpin)] //~ ERROR E0119
 struct Baz<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for Baz<T, U> {}
diff --git a/tests/ui/pin_project/add-attr-to-struct.rs b/tests/ui/pin_project/add-attr-to-struct.rs
index f5364fc..55f1561 100644
--- a/tests/ui/pin_project/add-attr-to-struct.rs
+++ b/tests/ui/pin_project/add-attr-to-struct.rs
@@ -1,4 +1,4 @@
-use auxiliary_macros::add_pin_attr;
+use auxiliary_macro::add_pin_attr;
 use pin_project::pin_project;
 use std::marker::PhantomPinned;
 
@@ -6,14 +6,14 @@
 #[add_pin_attr(struct)] //~ ERROR duplicate #[pin] attribute
 struct Foo {
     #[pin]
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 #[add_pin_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
 #[pin_project]
 struct Bar {
     #[pin]
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 fn main() {}
diff --git a/tests/ui/pin_project/add-pinned-field.rs b/tests/ui/pin_project/add-pinned-field.rs
index 76394cf..c415f9c 100644
--- a/tests/ui/pin_project/add-pinned-field.rs
+++ b/tests/ui/pin_project/add-pinned-field.rs
@@ -1,4 +1,4 @@
-use auxiliary_macros::add_pinned_field;
+use auxiliary_macro::add_pinned_field;
 use pin_project::pin_project;
 
 fn is_unpin<T: Unpin>() {}
@@ -7,14 +7,14 @@
 #[add_pinned_field]
 struct Foo {
     #[pin]
-    field: u32,
+    f: u32,
 }
 
 #[add_pinned_field]
 #[pin_project]
 struct Bar {
     #[pin]
-    field: u32,
+    f: u32,
 }
 
 fn main() {
diff --git a/tests/ui/pin_project/add-pinned-field.stderr b/tests/ui/pin_project/add-pinned-field.stderr
index d6a1dcd..a140694 100644
--- a/tests/ui/pin_project/add-pinned-field.stderr
+++ b/tests/ui/pin_project/add-pinned-field.stderr
@@ -1,23 +1,23 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/add-pinned-field.rs:21:5
    |
 4  | fn is_unpin<T: Unpin>() {}
    |                ----- required by this bound in `is_unpin`
 ...
 21 |     is_unpin::<Foo>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^ within `_::__Foo<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^ within `__Foo<'_>`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
-   = note: required because it appears within the type `_::__Foo<'_>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo`
+   = note: required because it appears within the type `__Foo<'_>`
+   = note: required because of the requirements on the impl of `Unpin` for `Foo`
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/add-pinned-field.rs:22:5
    |
 4  | fn is_unpin<T: Unpin>() {}
    |                ----- required by this bound in `is_unpin`
 ...
 22 |     is_unpin::<Bar>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^ within `_::__Bar<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^ within `__Bar<'_>`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
-   = note: required because it appears within the type `_::__Bar<'_>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar`
+   = note: required because it appears within the type `__Bar<'_>`
+   = note: required because of the requirements on the impl of `Unpin` for `Bar`
diff --git a/tests/ui/pin_project/conflict-drop.rs b/tests/ui/pin_project/conflict-drop.rs
index c965184..908f5c0 100644
--- a/tests/ui/pin_project/conflict-drop.rs
+++ b/tests/ui/pin_project/conflict-drop.rs
@@ -4,8 +4,8 @@
 #[pin_project] //~ ERROR E0119
 struct Foo<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 impl<T, U> Drop for Foo<T, U> {
@@ -15,8 +15,8 @@
 #[pin_project(PinnedDrop)] //~ ERROR E0119
 struct Bar<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 #[pinned_drop]
diff --git a/tests/ui/pin_project/conflict-unpin.rs b/tests/ui/pin_project/conflict-unpin.rs
index 0c48d27..f58c45e 100644
--- a/tests/ui/pin_project/conflict-unpin.rs
+++ b/tests/ui/pin_project/conflict-unpin.rs
@@ -5,8 +5,8 @@
 #[pin_project] //~ ERROR E0119
 struct Foo<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 // conflicting implementations
@@ -17,8 +17,8 @@
 #[pin_project] //~ ERROR E0119
 struct Bar<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 // conflicting implementations
@@ -27,8 +27,8 @@
 #[pin_project] //~ ERROR E0119
 struct Baz<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 // conflicting implementations
diff --git a/tests/ui/pin_project/impl-unsafe-unpin.rs b/tests/ui/pin_project/impl-unsafe-unpin.rs
index 94af322..562c9b6 100644
--- a/tests/ui/pin_project/impl-unsafe-unpin.rs
+++ b/tests/ui/pin_project/impl-unsafe-unpin.rs
@@ -3,8 +3,8 @@
 #[pin_project] //~ ERROR E0119
 struct Foo<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 unsafe impl<T, U> UnsafeUnpin for Foo<T, U> where T: Unpin {}
@@ -12,8 +12,8 @@
 #[pin_project] //~ ERROR E0119
 struct Bar<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 unsafe impl<T, U> UnsafeUnpin for Bar<T, U> {}
@@ -21,8 +21,8 @@
 #[pin_project] //~ ERROR E0119
 struct Baz<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for Baz<T, U> {}
diff --git a/tests/ui/pin_project/import_unnamed.rs b/tests/ui/pin_project/import_unnamed.rs
new file mode 100644
index 0000000..7926e61
--- /dev/null
+++ b/tests/ui/pin_project/import_unnamed.rs
@@ -0,0 +1,30 @@
+/// Only named projected types can be imported.
+/// See visibility.rs for named projected types.
+
+mod pub_ {
+    use pin_project::pin_project;
+
+    #[pin_project]
+    pub struct Default(());
+
+    #[pin_project(project_replace)]
+    pub struct Replace(());
+}
+#[allow(unused_imports)]
+pub mod use_ {
+    #[rustfmt::skip]
+    use crate::pub_::__DefaultProjection; //~ ERROR E0432
+    #[rustfmt::skip]
+    use crate::pub_::__DefaultProjectionRef; //~ ERROR E0432
+    #[rustfmt::skip]
+    use crate::pub_::__ReplaceProjection; //~ ERROR E0432
+    #[rustfmt::skip]
+    use crate::pub_::__ReplaceProjectionOwned; //~ ERROR E0432
+    #[rustfmt::skip]
+    use crate::pub_::__ReplaceProjectionRef; //~ ERROR E0432
+
+    // Confirm that the visibility of the original type is not changed.
+    pub use crate::pub_::{Default, Replace};
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/import_unnamed.stderr b/tests/ui/pin_project/import_unnamed.stderr
new file mode 100644
index 0000000..f54e4c4
--- /dev/null
+++ b/tests/ui/pin_project/import_unnamed.stderr
@@ -0,0 +1,29 @@
+error[E0432]: unresolved import `crate::pub_::__DefaultProjection`
+  --> $DIR/import_unnamed.rs:16:9
+   |
+16 |     use crate::pub_::__DefaultProjection; //~ ERROR E0432
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `__DefaultProjection` in `pub_`
+
+error[E0432]: unresolved import `crate::pub_::__DefaultProjectionRef`
+  --> $DIR/import_unnamed.rs:18:9
+   |
+18 |     use crate::pub_::__DefaultProjectionRef; //~ ERROR E0432
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `__DefaultProjectionRef` in `pub_`
+
+error[E0432]: unresolved import `crate::pub_::__ReplaceProjection`
+  --> $DIR/import_unnamed.rs:20:9
+   |
+20 |     use crate::pub_::__ReplaceProjection; //~ ERROR E0432
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `__ReplaceProjection` in `pub_`
+
+error[E0432]: unresolved import `crate::pub_::__ReplaceProjectionOwned`
+  --> $DIR/import_unnamed.rs:22:9
+   |
+22 |     use crate::pub_::__ReplaceProjectionOwned; //~ ERROR E0432
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `__ReplaceProjectionOwned` in `pub_`
+
+error[E0432]: unresolved import `crate::pub_::__ReplaceProjectionRef`
+  --> $DIR/import_unnamed.rs:24:9
+   |
+24 |     use crate::pub_::__ReplaceProjectionRef; //~ ERROR E0432
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `__ReplaceProjectionRef` in `pub_`
diff --git a/tests/ui/pin_project/invalid.rs b/tests/ui/pin_project/invalid.rs
index 9c51bec..d39a1fd 100644
--- a/tests/ui/pin_project/invalid.rs
+++ b/tests/ui/pin_project/invalid.rs
@@ -4,7 +4,7 @@
     #[pin_project]
     struct Struct {
         #[pin()] //~ ERROR unexpected token
-        field: (),
+        f: (),
     }
 
     #[pin_project]
@@ -19,7 +19,7 @@
     enum EnumStruct {
         V {
             #[pin(foo)] //~ ERROR unexpected token
-            field: (),
+            f: (),
         },
     }
 }
@@ -31,7 +31,7 @@
     struct DuplicateStruct {
         #[pin]
         #[pin] //~ ERROR duplicate #[pin] attribute
-        field: (),
+        f: (),
     }
 
     #[pin_project]
@@ -57,7 +57,7 @@
         V {
             #[pin]
             #[pin] //~ ERROR duplicate #[pin] attribute
-            field: (),
+            f: (),
         },
     }
 }
@@ -69,7 +69,7 @@
     #[pin] //~ ERROR may only be used on fields of structs or variants
     struct Struct {
         #[pin]
-        field: (),
+        f: (),
     }
 
     #[pin_project]
@@ -88,6 +88,9 @@
 mod pin_project_argument {
     use pin_project::pin_project;
 
+    #[pin_project(Replace)] //~ ERROR `Replace` argument was removed, use `project_replace` argument instead
+    struct RemovedReplace(#[pin] ());
+
     #[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
     struct Unexpected1(#[pin] ());
 
@@ -106,9 +109,6 @@
     #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
     struct DuplicatePinnedDrop(#[pin] ());
 
-    #[pin_project(Replace, Replace)] //~ ERROR duplicate `Replace` argument
-    struct DuplicateReplace(#[pin] ());
-
     #[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
     struct DuplicateUnsafeUnpin(#[pin] ());
 
@@ -142,24 +142,12 @@
     #[pin_project(project_replace = A)] // Ok
     struct ProjectReplaceWithoutReplace(#[pin] ());
 
-    #[pin_project(PinnedDrop, Replace)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
-    struct PinnedDropWithReplace1(#[pin] ());
-
-    #[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] ());
 
@@ -198,11 +186,25 @@
 
     #[pin_project(project_replace = !)] //~ ERROR expected identifier
     struct ProjectReplace3(#[pin] ());
+
+    #[pin_project(project_replace)] //~ ERROR `project_replace` argument requires a value when used on enums
+    enum ProjectReplaceEnum {
+        V(#[pin] ()),
+    }
 }
 
 mod pin_project_conflict_naming {
     use pin_project::pin_project;
 
+    #[pin_project(project = OrigAndProj)] //~ ERROR name `OrigAndProj` is the same as the original type name
+    struct OrigAndProj(#[pin] ());
+
+    #[pin_project(project_ref = OrigAndProjRef)] //~ ERROR name `OrigAndProjRef` is the same as the original type name
+    struct OrigAndProjRef(#[pin] ());
+
+    #[pin_project(project_replace = OrigAndProjOwn)] //~ ERROR name `OrigAndProjOwn` is the same as the original type name
+    struct OrigAndProjOwn(#[pin] ());
+
     #[pin_project(project = A, project_ref = A)] //~ ERROR name `A` is already specified by `project` argument
     struct ProjAndProjRef(#[pin] ());
 
@@ -253,6 +255,9 @@
         //~^ ERROR may only be used on structs or enums
         f: (),
     }
+
+    #[pin_project]
+    impl Impl {} //~ ERROR may only be used on structs or enums
 }
 
 // #[repr(packed)] is always detected first, even on unsupported structs.
diff --git a/tests/ui/pin_project/invalid.stderr b/tests/ui/pin_project/invalid.stderr
index 3c6af57..35552bf 100644
--- a/tests/ui/pin_project/invalid.stderr
+++ b/tests/ui/pin_project/invalid.stderr
@@ -64,42 +64,42 @@
 82 |     #[pin] //~ ERROR may only be used on fields of structs or variants
    |     ^^^^^^
 
-error: expected identifier
-  --> $DIR/invalid.rs:91:31
+error: `Replace` argument was removed, use `project_replace` argument instead
+  --> $DIR/invalid.rs:91:19
    |
-91 |     #[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
+91 |     #[pin_project(Replace)] //~ ERROR `Replace` argument was removed, use `project_replace` argument instead
+   |                   ^^^^^^^
+
+error: expected identifier
+  --> $DIR/invalid.rs:94:31
+   |
+94 |     #[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
    |                               ^
 
 error: unexpected argument: Foo
-  --> $DIR/invalid.rs:94:19
+  --> $DIR/invalid.rs:97:19
    |
-94 |     #[pin_project(Foo)] //~ ERROR unexpected argument
+97 |     #[pin_project(Foo)] //~ ERROR unexpected argument
    |                   ^^^
 
 error: expected identifier
-  --> $DIR/invalid.rs:97:19
-   |
-97 |     #[pin_project(,UnsafeUnpin)] //~ ERROR expected identifier
-   |                   ^
+   --> $DIR/invalid.rs:100:19
+    |
+100 |     #[pin_project(,UnsafeUnpin)] //~ ERROR expected identifier
+    |                   ^
 
 error: expected `,`
-   --> $DIR/invalid.rs:103:30
+   --> $DIR/invalid.rs:106:30
     |
-103 |     #[pin_project(PinnedDrop PinnedDrop)] //~ ERROR expected `,`
+106 |     #[pin_project(PinnedDrop PinnedDrop)] //~ ERROR expected `,`
     |                              ^^^^^^^^^^
 
 error: duplicate `PinnedDrop` argument
-   --> $DIR/invalid.rs:106:31
+   --> $DIR/invalid.rs:109:31
     |
-106 |     #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
+109 |     #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
     |                               ^^^^^^^^^^
 
-error: duplicate `Replace` argument
-   --> $DIR/invalid.rs:109:28
-    |
-109 |     #[pin_project(Replace, Replace)] //~ ERROR duplicate `Replace` argument
-    |                            ^^^^^^^
-
 error: duplicate `UnsafeUnpin` argument
    --> $DIR/invalid.rs:112:32
     |
@@ -160,187 +160,205 @@
 139 |     #[pin_project(project_replace = A, project_replace)] //~ ERROR duplicate `project_replace` argument
     |                                        ^^^^^^^^^^^^^^^
 
-error: arguments `PinnedDrop` and `Replace` are mutually exclusive
+error: arguments `PinnedDrop` and `project_replace` are mutually exclusive
    --> $DIR/invalid.rs:145:19
     |
-145 |     #[pin_project(PinnedDrop, Replace)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
-    |                   ^^^^^^^^^^
-
-error: arguments `PinnedDrop` and `Replace` are mutually exclusive
-   --> $DIR/invalid.rs:148:41
-    |
-148 |     #[pin_project(Replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `Replace` are mutually exclusive
-    |                                         ^^^^^^^^^^
-
-error: arguments `PinnedDrop` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:151:19
-    |
-151 |     #[pin_project(PinnedDrop, project_replace)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
+145 |     #[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
+   --> $DIR/invalid.rs:148:49
     |
-154 |     #[pin_project(project_replace, UnsafeUnpin, PinnedDrop)] //~ ERROR arguments `PinnedDrop` and `project_replace` are mutually exclusive
+148 |     #[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
+   --> $DIR/invalid.rs:151:19
     |
-163 |     #[pin_project(UnsafeUnpin, !Unpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
+151 |     #[pin_project(UnsafeUnpin, !Unpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
     |                   ^^^^^^^^^^^
 
 error: arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
-   --> $DIR/invalid.rs:166:39
+   --> $DIR/invalid.rs:154:39
     |
-166 |     #[pin_project(!Unpin, PinnedDrop, UnsafeUnpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
+154 |     #[pin_project(!Unpin, PinnedDrop, UnsafeUnpin)] //~ ERROR arguments `UnsafeUnpin` and `!Unpin` are mutually exclusive
     |                                       ^^^^^^^^^^^
 
 error: expected `!Unpin`, found `!`
-   --> $DIR/invalid.rs:169:19
+   --> $DIR/invalid.rs:157:19
     |
-169 |     #[pin_project(!)] //~ ERROR expected `!Unpin`, found `!`
+157 |     #[pin_project(!)] //~ ERROR expected `!Unpin`, found `!`
     |                   ^
 
 error: unexpected argument: Unpin
-   --> $DIR/invalid.rs:172:19
+   --> $DIR/invalid.rs:160:19
     |
-172 |     #[pin_project(Unpin)] //~ ERROR unexpected argument
+160 |     #[pin_project(Unpin)] //~ ERROR unexpected argument
     |                   ^^^^^
 
 error: expected `project = <identifier>`, found `project`
-   --> $DIR/invalid.rs:175:19
+   --> $DIR/invalid.rs:163:19
     |
-175 |     #[pin_project(project)] //~ ERROR expected `project = <identifier>`, found `project`
+163 |     #[pin_project(project)] //~ ERROR expected `project = <identifier>`, found `project`
     |                   ^^^^^^^
 
 error: expected `project = <identifier>`, found `project =`
-   --> $DIR/invalid.rs:178:19
+   --> $DIR/invalid.rs:166:19
     |
-178 |     #[pin_project(project = )] //~ ERROR expected `project = <identifier>`, found `project =`
+166 |     #[pin_project(project = )] //~ ERROR expected `project = <identifier>`, found `project =`
     |                   ^^^^^^^^^
 
 error: expected identifier
-   --> $DIR/invalid.rs:181:29
+   --> $DIR/invalid.rs:169:29
     |
-181 |     #[pin_project(project = !)] //~ ERROR expected identifier
+169 |     #[pin_project(project = !)] //~ ERROR expected identifier
     |                             ^
 
 error: expected `project_ref = <identifier>`, found `project_ref`
-   --> $DIR/invalid.rs:184:19
+   --> $DIR/invalid.rs:172:19
     |
-184 |     #[pin_project(project_ref)] //~ ERROR expected `project_ref = <identifier>`, found `project_ref`
+172 |     #[pin_project(project_ref)] //~ ERROR expected `project_ref = <identifier>`, found `project_ref`
     |                   ^^^^^^^^^^^
 
 error: expected `project_ref = <identifier>`, found `project_ref =`
-   --> $DIR/invalid.rs:187:19
+   --> $DIR/invalid.rs:175:19
     |
-187 |     #[pin_project(project_ref = )] //~ ERROR expected `project_ref = <identifier>`, found `project_ref =`
+175 |     #[pin_project(project_ref = )] //~ ERROR expected `project_ref = <identifier>`, found `project_ref =`
     |                   ^^^^^^^^^^^^^
 
 error: expected identifier
-   --> $DIR/invalid.rs:190:33
+   --> $DIR/invalid.rs:178:33
     |
-190 |     #[pin_project(project_ref = !)] //~ ERROR expected identifier
+178 |     #[pin_project(project_ref = !)] //~ ERROR expected identifier
     |                                 ^
 
 error: expected `project_replace = <identifier>`, found `project_replace =`
-   --> $DIR/invalid.rs:196:19
+   --> $DIR/invalid.rs:184:19
     |
-196 |     #[pin_project(project_replace = )] //~ ERROR expected `project_replace = <identifier>`, found `project_replace =`
+184 |     #[pin_project(project_replace = )] //~ ERROR expected `project_replace = <identifier>`, found `project_replace =`
     |                   ^^^^^^^^^^^^^^^^^
 
 error: expected identifier
-   --> $DIR/invalid.rs:199:37
+   --> $DIR/invalid.rs:187:37
     |
-199 |     #[pin_project(project_replace = !)] //~ ERROR expected identifier
+187 |     #[pin_project(project_replace = !)] //~ ERROR expected identifier
     |                                     ^
 
-error: name `A` is already specified by `project` argument
-   --> $DIR/invalid.rs:206:46
+error: `project_replace` argument requires a value when used on enums
+   --> $DIR/invalid.rs:190:19
     |
-206 |     #[pin_project(project = A, project_ref = A)] //~ ERROR name `A` is already specified by `project` argument
+190 |     #[pin_project(project_replace)] //~ ERROR `project_replace` argument requires a value when used on enums
+    |                   ^^^^^^^^^^^^^^^
+
+error: name `OrigAndProj` is the same as the original type name
+   --> $DIR/invalid.rs:199:29
+    |
+199 |     #[pin_project(project = OrigAndProj)] //~ ERROR name `OrigAndProj` is the same as the original type name
+    |                             ^^^^^^^^^^^
+
+error: name `OrigAndProjRef` is the same as the original type name
+   --> $DIR/invalid.rs:202:33
+    |
+202 |     #[pin_project(project_ref = OrigAndProjRef)] //~ ERROR name `OrigAndProjRef` is the same as the original type name
+    |                                 ^^^^^^^^^^^^^^
+
+error: name `OrigAndProjOwn` is the same as the original type name
+   --> $DIR/invalid.rs:205:37
+    |
+205 |     #[pin_project(project_replace = OrigAndProjOwn)] //~ ERROR name `OrigAndProjOwn` is the same as the original type name
+    |                                     ^^^^^^^^^^^^^^
+
+error: name `A` is already specified by `project` argument
+   --> $DIR/invalid.rs:208:46
+    |
+208 |     #[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
+   --> $DIR/invalid.rs:211:50
     |
-209 |     #[pin_project(project = A, project_replace = A)] //~ ERROR name `A` is already specified by `project` argument
+211 |     #[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
+   --> $DIR/invalid.rs:214:54
     |
-212 |     #[pin_project(project_ref = A, project_replace = A)] //~ ERROR name `A` is already specified by `project_ref` argument
+214 |     #[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:220:5
+   --> $DIR/invalid.rs:222:5
     |
-220 |     #[pin_project] //~ ERROR duplicate #[pin_project] attribute
+222 |     #[pin_project] //~ ERROR duplicate #[pin_project] attribute
     |     ^^^^^^^^^^^^^^
 
 error: #[pin_project] attribute may not be used on structs with zero fields
-   --> $DIR/invalid.rs:228:19
+   --> $DIR/invalid.rs:230:19
     |
-228 |     struct Struct {} //~ ERROR may not be used on structs with zero fields
+230 |     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:231:23
+   --> $DIR/invalid.rs:233:23
     |
-231 |     struct TupleStruct(); //~ ERROR may not be used on structs with zero fields
+233 |     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:234:12
+   --> $DIR/invalid.rs:236:12
     |
-234 |     struct UnitStruct; //~ ERROR may not be used on structs with zero fields
+236 |     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:237:20
+   --> $DIR/invalid.rs:239:20
     |
-237 |     enum EnumEmpty {} //~ ERROR may not be used on enums without variants
+239 |     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:241:13
+   --> $DIR/invalid.rs:243:13
     |
-241 |         V = 2, //~ ERROR may not be used on enums with discriminants
+243 |         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:246:9
+   --> $DIR/invalid.rs:248:9
     |
-246 | /         Unit, //~ ERROR may not be used on enums with zero fields
-247 | |         Tuple(),
-248 | |         Struct {},
+248 | /         Unit, //~ ERROR may not be used on enums with zero fields
+249 | |         Tuple(),
+250 | |         Struct {},
     | |__________________^
 
 error: #[pin_project] attribute may only be used on structs or enums
-   --> $DIR/invalid.rs:252:5
+   --> $DIR/invalid.rs:254:5
     |
-252 | /     union Union {
-253 | |         //~^ ERROR may only be used on structs or enums
-254 | |         f: (),
-255 | |     }
+254 | /     union Union {
+255 | |         //~^ ERROR may only be used on structs or enums
+256 | |         f: (),
+257 | |     }
     | |_____^
 
-error: #[pin_project] attribute may not be used on #[repr(packed)] types
-   --> $DIR/invalid.rs:263:12
+error: #[pin_project] attribute may only be used on structs or enums
+   --> $DIR/invalid.rs:260:5
     |
-263 |     #[repr(packed)]
+260 |     impl Impl {} //~ ERROR may only be used on structs or enums
+    |     ^^^^^^^^^^^^
+
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+   --> $DIR/invalid.rs:268:12
+    |
+268 |     #[repr(packed)]
     |            ^^^^^^
 
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
-   --> $DIR/invalid.rs:267:12
+   --> $DIR/invalid.rs:272:12
     |
-267 |     #[repr(packed)]
+272 |     #[repr(packed)]
     |            ^^^^^^
 
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
-   --> $DIR/invalid.rs:271:12
+   --> $DIR/invalid.rs:276:12
     |
-271 |     #[repr(packed)]
+276 |     #[repr(packed)]
     |            ^^^^^^
diff --git a/tests/ui/pin_project/overlapping_unpin_struct.rs b/tests/ui/pin_project/overlapping_unpin_struct.rs
index 00fef3c..8db0855 100644
--- a/tests/ui/pin_project/overlapping_unpin_struct.rs
+++ b/tests/ui/pin_project/overlapping_unpin_struct.rs
@@ -2,17 +2,17 @@
 use std::marker::PhantomPinned;
 
 #[pin_project]
-struct Foo<T> {
+struct S<T> {
     #[pin]
-    inner: T,
+    f: T,
 }
 
-struct __Foo {}
+struct __S {}
 
-impl Unpin for __Foo {}
+impl Unpin for __S {}
 
 fn is_unpin<T: Unpin>() {}
 
 fn main() {
-    is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
+    is_unpin::<S<PhantomPinned>>(); //~ ERROR E0277
 }
diff --git a/tests/ui/pin_project/overlapping_unpin_struct.stderr b/tests/ui/pin_project/overlapping_unpin_struct.stderr
index 96a9f51..296b063 100644
--- a/tests/ui/pin_project/overlapping_unpin_struct.stderr
+++ b/tests/ui/pin_project/overlapping_unpin_struct.stderr
@@ -1,11 +1,11 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/overlapping_unpin_struct.rs:17:5
    |
 14 | fn is_unpin<T: Unpin>() {}
    |                ----- required by this bound in `is_unpin`
 ...
-17 |     is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Foo<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+17 |     is_unpin::<S<PhantomPinned>>(); //~ ERROR E0277
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__S<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `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>`
+   = note: required because it appears within the type `_::__S<'_, PhantomPinned>`
+   = note: required because of the requirements on the impl of `Unpin` for `S<PhantomPinned>`
diff --git a/tests/ui/pin_project/packed-enum.stderr b/tests/ui/pin_project/packed-enum.stderr
index 0a5d31b..afc8b30 100644
--- a/tests/ui/pin_project/packed-enum.stderr
+++ b/tests/ui/pin_project/packed-enum.stderr
@@ -1,4 +1,4 @@
-error[E0517]: attribute should be applied to struct or union
+error[E0517]: attribute should be applied to a struct or union
  --> $DIR/packed-enum.rs:3:8
   |
 3 |   #[repr(packed)] //~ ERROR E0517
@@ -8,7 +8,7 @@
 6 | | }
   | |_- not a struct or union
 
-error[E0517]: attribute should be applied to struct or union
+error[E0517]: attribute should be applied to a struct or union
   --> $DIR/packed-enum.rs:9:8
    |
 9  |   #[repr(packed)] //~ ERROR E0517
@@ -18,7 +18,7 @@
 12 | | }
    | |_- not a struct or union
 
-error[E0517]: attribute should be applied to struct or union
+error[E0517]: attribute should be applied to a struct or union
   --> $DIR/packed-enum.rs:14:8
    |
 14 |   #[repr(packed)] //~ ERROR E0517
diff --git a/tests/ui/pin_project/packed.rs b/tests/ui/pin_project/packed.rs
index 86f3ecf..f756605 100644
--- a/tests/ui/pin_project/packed.rs
+++ b/tests/ui/pin_project/packed.rs
@@ -4,7 +4,7 @@
 #[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] types
 struct A {
     #[pin]
-    field: u8,
+    f: u8,
 }
 
 // Test putting 'repr' before the 'pin_project' attribute
@@ -12,14 +12,14 @@
 #[pin_project]
 struct B {
     #[pin]
-    field: u8,
+    f: u8,
 }
 
 #[pin_project]
 #[repr(packed(2))] //~ ERROR may not be used on #[repr(packed)] types
 struct C {
     #[pin]
-    field: u32,
+    f: u32,
 }
 
 fn main() {}
diff --git a/tests/ui/pin_project/packed_sneaky-1.rs b/tests/ui/pin_project/packed_sneaky-1.rs
index dcf5464..38f6fe0 100644
--- a/tests/ui/pin_project/packed_sneaky-1.rs
+++ b/tests/ui/pin_project/packed_sneaky-1.rs
@@ -1,4 +1,4 @@
-use auxiliary_macros::hidden_repr;
+use auxiliary_macro::hidden_repr;
 use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
 use std::pin::Pin;
 
@@ -6,14 +6,14 @@
 #[hidden_repr(packed)]
 struct A {
     #[pin]
-    field: u32,
+    f: u32,
 }
 
 #[pin_project(UnsafeUnpin)] //~ ERROR may not be used on #[repr(packed)] types
 #[hidden_repr(packed)]
 struct C {
     #[pin]
-    field: u32,
+    f: u32,
 }
 
 unsafe impl UnsafeUnpin for C {}
@@ -22,7 +22,7 @@
 #[hidden_repr(packed)]
 struct D {
     #[pin]
-    field: u32,
+    f: u32,
 }
 
 #[pinned_drop]
diff --git a/tests/ui/pin_project/packed_sneaky-1.stderr b/tests/ui/pin_project/packed_sneaky-1.stderr
index 06a4f62..510200e 100644
--- a/tests/ui/pin_project/packed_sneaky-1.stderr
+++ b/tests/ui/pin_project/packed_sneaky-1.stderr
@@ -1,23 +1,17 @@
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
- --> $DIR/packed_sneaky-1.rs:6:1
+ --> $DIR/packed_sneaky-1.rs:6:15
   |
 6 | #[hidden_repr(packed)]
-  | ^^^^^^^^^^^^^^^^^^^^^^
-  |
-  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+  |               ^^^^^^
 
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
-  --> $DIR/packed_sneaky-1.rs:13:1
+  --> $DIR/packed_sneaky-1.rs:13:15
    |
 13 | #[hidden_repr(packed)]
-   | ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+   |               ^^^^^^
 
 error: #[pin_project] attribute may not be used on #[repr(packed)] types
-  --> $DIR/packed_sneaky-1.rs:22:1
+  --> $DIR/packed_sneaky-1.rs:22:15
    |
 22 | #[hidden_repr(packed)]
-   | ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+   |               ^^^^^^
diff --git a/tests/ui/pin_project/packed_sneaky-2.rs b/tests/ui/pin_project/packed_sneaky-2.rs
index d162706..b098358 100644
--- a/tests/ui/pin_project/packed_sneaky-2.rs
+++ b/tests/ui/pin_project/packed_sneaky-2.rs
@@ -1,11 +1,11 @@
-use auxiliary_macros::hidden_repr_macro;
+use auxiliary_macro::hidden_repr_macro;
 use pin_project::pin_project;
 
 hidden_repr_macro! { //~ ERROR may not be used on #[repr(packed)] types
     #[pin_project]
     struct B {
         #[pin]
-        field: u32,
+        f: u32,
     }
 }
 
diff --git a/tests/ui/pin_project/packed_sneaky-2.stderr b/tests/ui/pin_project/packed_sneaky-2.stderr
index d653a4d..51987a2 100644
--- a/tests/ui/pin_project/packed_sneaky-2.stderr
+++ b/tests/ui/pin_project/packed_sneaky-2.stderr
@@ -5,7 +5,7 @@
 5  | |     #[pin_project]
 6  | |     struct B {
 7  | |         #[pin]
-8  | |         field: u32,
+8  | |         f: u32,
 9  | |     }
 10 | | }
    | |_^
diff --git a/tests/ui/pin_project/packed_sneaky-3.rs b/tests/ui/pin_project/packed_sneaky-3.rs
new file mode 100644
index 0000000..d3f00f3
--- /dev/null
+++ b/tests/ui/pin_project/packed_sneaky-3.rs
@@ -0,0 +1,32 @@
+use auxiliary_macro::{hidden_repr_macro, HiddenRepr};
+use pin_project::pin_project;
+
+hidden_repr_macro! {} //~ ERROR expected item after attributes
+#[pin_project]
+struct S1 {
+    #[pin]
+    f: u32,
+}
+
+macro_rules! hidden_repr_macro2 {
+    () => {
+        #[repr(packed)] //~ ERROR expected item after attributes
+    };
+}
+
+hidden_repr_macro2! {}
+#[pin_project]
+struct S2 {
+    #[pin]
+    f: u32,
+}
+
+#[derive(HiddenRepr)] //~ ERROR expected item after attributes
+struct S3 {}
+#[pin_project]
+struct S4 {
+    #[pin]
+    f: u32,
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/packed_sneaky-3.stderr b/tests/ui/pin_project/packed_sneaky-3.stderr
new file mode 100644
index 0000000..b711d05
--- /dev/null
+++ b/tests/ui/pin_project/packed_sneaky-3.stderr
@@ -0,0 +1,30 @@
+error: expected item after attributes
+ --> $DIR/packed_sneaky-3.rs:4:1
+  |
+4 | hidden_repr_macro! {} //~ ERROR expected item after attributes
+  | ^^^^^^^^^^^^^^^^^^^^^
+
+error: expected item after attributes
+  --> $DIR/packed_sneaky-3.rs:13:9
+   |
+13 |         #[repr(packed)] //~ ERROR expected item after attributes
+   |         ^^^^^^^^^^^^^^^
+...
+17 | hidden_repr_macro2! {}
+   | ---------------------- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected item after attributes
+  --> $DIR/packed_sneaky-3.rs:24:10
+   |
+24 | #[derive(HiddenRepr)] //~ ERROR expected item after attributes
+   |          ^^^^^^^^^^
+   |
+   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: proc-macro derive produced unparseable tokens
+  --> $DIR/packed_sneaky-3.rs:24:10
+   |
+24 | #[derive(HiddenRepr)] //~ ERROR expected item after attributes
+   |          ^^^^^^^^^^
diff --git a/tests/ui/pin_project/private_in_public-enum.rs b/tests/ui/pin_project/private_in_public-enum.rs
index cbffa20..15a82a9 100644
--- a/tests/ui/pin_project/private_in_public-enum.rs
+++ b/tests/ui/pin_project/private_in_public-enum.rs
@@ -3,20 +3,20 @@
 #![allow(private_in_public)]
 
 pub enum PublicEnum {
-    Variant(PrivateEnum), //~ ERROR E0446
+    V(PrivateEnum), //~ ERROR E0446
 }
 
 enum PrivateEnum {
-    Variant(u8),
+    V(u8),
 }
 
 mod foo {
     pub(crate) enum CrateEnum {
-        Variant(PrivateEnum), //~ ERROR E0446
+        V(PrivateEnum), //~ ERROR E0446
     }
 
     enum PrivateEnum {
-        Variant(u8),
+        V(u8),
     }
 }
 
diff --git a/tests/ui/pin_project/private_in_public-enum.stderr b/tests/ui/pin_project/private_in_public-enum.stderr
index 6f2988f..6e3316c 100644
--- a/tests/ui/pin_project/private_in_public-enum.stderr
+++ b/tests/ui/pin_project/private_in_public-enum.stderr
@@ -1,17 +1,17 @@
 error[E0446]: private type `PrivateEnum` in public interface
- --> $DIR/private_in_public-enum.rs:6:13
+ --> $DIR/private_in_public-enum.rs:6:7
   |
-6 |     Variant(PrivateEnum), //~ ERROR E0446
-  |             ^^^^^^^^^^^ can't leak private type
+6 |     V(PrivateEnum), //~ ERROR E0446
+  |       ^^^^^^^^^^^ can't leak private type
 ...
 9 | enum PrivateEnum {
-  | - `PrivateEnum` declared as private
+  | ---------------- `PrivateEnum` declared as private
 
 error[E0446]: private type `foo::PrivateEnum` in public interface
-  --> $DIR/private_in_public-enum.rs:15:17
+  --> $DIR/private_in_public-enum.rs:15:11
    |
-15 |         Variant(PrivateEnum), //~ ERROR E0446
-   |                 ^^^^^^^^^^^ can't leak private type
+15 |         V(PrivateEnum), //~ ERROR E0446
+   |           ^^^^^^^^^^^ can't leak private type
 ...
 18 |     enum PrivateEnum {
-   |     - `foo::PrivateEnum` declared as private
+   |     ---------------- `foo::PrivateEnum` declared as private
diff --git a/tests/ui/pin_project/project_replace_unsized.rs b/tests/ui/pin_project/project_replace_unsized.rs
index 706a0c1..20dde12 100644
--- a/tests/ui/pin_project/project_replace_unsized.rs
+++ b/tests/ui/pin_project/project_replace_unsized.rs
@@ -2,7 +2,7 @@
 
 #[pin_project(project_replace)] //~ ERROR E0277
 struct Struct<T: ?Sized> {
-    x: T,
+    f: T,
 }
 
 #[pin_project(project_replace)] //~ ERROR E0277
diff --git a/tests/ui/pin_project/project_replace_unsized.stderr b/tests/ui/pin_project/project_replace_unsized.stderr
index 0395c4e..e40db5f 100644
--- a/tests/ui/pin_project/project_replace_unsized.stderr
+++ b/tests/ui/pin_project/project_replace_unsized.stderr
@@ -4,10 +4,10 @@
 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`
+  |               - this type parameter needs to be `Sized`
   |
   = note: required because it appears within the type `Struct<T>`
-  = help: unsized locals are gated as an unstable feature
+  = help: unsized fn params are gated as an unstable feature
 help: function arguments must have a statically known size, borrowed types always have a known size
   |
 3 | #[pin_project(&project_replace)] //~ ERROR E0277
@@ -17,8 +17,8 @@
    --> $DIR/project_replace_unsized.rs:5:5
     |
 4   | struct Struct<T: ?Sized> {
-    |               - this type parameter needs to be `std::marker::Sized`
-5   |     x: T,
+    |               - this type parameter needs to be `Sized`
+5   |     f: T,
     |     ^ doesn't have a size known at compile-time
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
@@ -27,7 +27,7 @@
 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`
+  |               - this type parameter needs to be `Sized`
   |
   = note: required because it appears within the type `__StructProjectionOwned<T>`
   = note: structs must have a statically known size to be initialized
@@ -39,10 +39,10 @@
 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`
+  |                    - this type parameter needs to be `Sized`
   |
   = note: required because it appears within the type `TupleStruct<T>`
-  = help: unsized locals are gated as an unstable feature
+  = help: unsized fn params are gated as an unstable feature
 help: function arguments must have a statically known size, borrowed types always have a known size
   |
 8 | #[pin_project(&project_replace)] //~ ERROR E0277
@@ -54,7 +54,7 @@
 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`
+    |                    - this type parameter needs to be `Sized`
     |
     = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -62,9 +62,9 @@
  --> $DIR/project_replace_unsized.rs:9:8
   |
 9 | struct TupleStruct<T: ?Sized>(T);
-  |        ^^^^^^^^^^^ - this type parameter needs to be `std::marker::Sized`
+  |        ^^^^^^^^^^^ - this type parameter needs to be `Sized`
   |        |
   |        doesn't have a size known at compile-time
   |
   = note: all function arguments must have a statically known size
-  = help: unsized locals are gated as an unstable feature
+  = help: unsized fn params 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_fn_params.rs
similarity index 83%
rename from tests/ui/pin_project/project_replace_unsized_locals.rs
rename to tests/ui/pin_project/project_replace_unsized_fn_params.rs
index 2546041..e0fa25b 100644
--- a/tests/ui/pin_project/project_replace_unsized_locals.rs
+++ b/tests/ui/pin_project/project_replace_unsized_fn_params.rs
@@ -1,10 +1,10 @@
-#![feature(unsized_locals)]
+#![feature(unsized_fn_params)]
 
 use pin_project::pin_project;
 
 #[pin_project(project_replace)] //~ ERROR E0277
 struct Struct<T: ?Sized> {
-    x: T,
+    f: T,
 }
 
 #[pin_project(project_replace)] //~ ERROR E0277
diff --git a/tests/ui/pin_project/project_replace_unsized_locals.stderr b/tests/ui/pin_project/project_replace_unsized_fn_params.stderr
similarity index 74%
rename from tests/ui/pin_project/project_replace_unsized_locals.stderr
rename to tests/ui/pin_project/project_replace_unsized_fn_params.stderr
index 1266c4d..622d12f 100644
--- a/tests/ui/pin_project/project_replace_unsized_locals.stderr
+++ b/tests/ui/pin_project/project_replace_unsized_fn_params.stderr
@@ -1,53 +1,53 @@
 error[E0277]: the size for values of type `T` cannot be known at compilation time
- --> $DIR/project_replace_unsized_locals.rs:6:8
+ --> $DIR/project_replace_unsized_fn_params.rs:6:8
   |
 6 | struct Struct<T: ?Sized> {
   |        ^^^^^^^-^^^^^^^^^
   |        |      |
-  |        |      this type parameter needs to be `std::marker::Sized`
+  |        |      this type parameter needs to be `Sized`
   |        doesn't have a size known at compile-time
   |
   = 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
+   --> $DIR/project_replace_unsized_fn_params.rs:7:5
     |
 6   | struct Struct<T: ?Sized> {
-    |               - this type parameter needs to be `std::marker::Sized`
-7   |     x: T,
+    |               - this type parameter needs to be `Sized`
+7   |     f: T,
     |     ^ doesn't have a size known at compile-time
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
- --> $DIR/project_replace_unsized_locals.rs:5:1
+ --> $DIR/project_replace_unsized_fn_params.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`
+  |               - this type parameter needs to be `Sized`
   |
   = 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
+  --> $DIR/project_replace_unsized_fn_params.rs:11:8
    |
 11 | struct TupleStruct<T: ?Sized>(T);
    |        ^^^^^^^^^^^^-^^^^^^^^^
    |        |           |
-   |        |           this type parameter needs to be `std::marker::Sized`
+   |        |           this type parameter needs to be `Sized`
    |        doesn't have a size known at compile-time
    |
    = 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
+   --> $DIR/project_replace_unsized_fn_params.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`
+    |                    - this type parameter needs to be `Sized`
     |
     = 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.rs b/tests/ui/pin_project/proper_unpin.rs
deleted file mode 100644
index e61789b..0000000
--- a/tests/ui/pin_project/proper_unpin.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-use pin_project::pin_project;
-use std::marker::PhantomPinned;
-
-struct Inner<T> {
-    val: T,
-}
-
-#[pin_project]
-struct Foo<T, U> {
-    #[pin]
-    inner: Inner<T>,
-    other: U,
-}
-
-#[pin_project]
-struct TrivialBounds {
-    #[pin]
-    field1: PhantomPinned,
-}
-
-#[pin_project]
-struct Bar<'a, T, U> {
-    #[pin]
-    inner: &'a mut Inner<T>,
-    other: U,
-}
-
-fn is_unpin<T: Unpin>() {}
-
-fn main() {
-    is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
-    is_unpin::<Foo<(), PhantomPinned>>(); // Ok
-    is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-
-    is_unpin::<TrivialBounds>(); //~ ERROR E0277
-
-    is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); // Ok
-}
diff --git a/tests/ui/pin_project/proper_unpin.stderr b/tests/ui/pin_project/proper_unpin.stderr
deleted file mode 100644
index 7562597..0000000
--- a/tests/ui/pin_project/proper_unpin.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/proper_unpin.rs:31:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-31 |     is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `_::__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
-  --> $DIR/proper_unpin.rs:33:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-33 |     is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `_::__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
-  --> $DIR/proper_unpin.rs:35:5
-   |
-28 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-35 |     is_unpin::<TrivialBounds>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__TrivialBounds<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = 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 1ecd56f..bec8302 100644
--- a/tests/ui/pin_project/remove-attr-from-field.rs
+++ b/tests/ui/pin_project/remove-attr-from-field.rs
@@ -1,4 +1,4 @@
-use auxiliary_macros::remove_attr;
+use auxiliary_macro::remove_attr;
 use pin_project::pin_project;
 use std::{marker::PhantomPinned, pin::Pin};
 
@@ -8,25 +8,25 @@
 #[remove_attr(field_all)]
 struct A {
     #[pin]
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 #[remove_attr(field_all)]
 #[pin_project]
 struct B {
     #[pin]
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 fn main() {
     is_unpin::<A>();
     is_unpin::<B>();
 
-    let mut x = A { field: PhantomPinned };
+    let mut x = A { f: PhantomPinned };
     let x = Pin::new(&mut x).project();
-    let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
+    let _: Pin<&mut PhantomPinned> = x.f; //~ ERROR E0308
 
-    let mut x = B { field: PhantomPinned };
+    let mut x = B { f: PhantomPinned };
     let x = Pin::new(&mut x).project();
-    let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
+    let _: Pin<&mut PhantomPinned> = x.f; //~ ERROR E0308
 }
diff --git a/tests/ui/pin_project/remove-attr-from-field.stderr b/tests/ui/pin_project/remove-attr-from-field.stderr
index 15195e7..5d8caac 100644
--- a/tests/ui/pin_project/remove-attr-from-field.stderr
+++ b/tests/ui/pin_project/remove-attr-from-field.stderr
@@ -1,21 +1,21 @@
 error[E0308]: mismatched types
   --> $DIR/remove-attr-from-field.rs:27:38
    |
-27 |     let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
-   |            -----------------------   ^^^^^^^ expected struct `std::pin::Pin`, found `&mut std::marker::PhantomPinned`
+27 |     let _: Pin<&mut PhantomPinned> = x.f; //~ ERROR E0308
+   |            -----------------------   ^^^ expected struct `Pin`, found `&mut PhantomPinned`
    |            |
    |            expected due to this
    |
-   = note:         expected struct `std::pin::Pin<&mut std::marker::PhantomPinned>`
-           found mutable reference `&mut std::marker::PhantomPinned`
+   = note:         expected struct `Pin<&mut PhantomPinned>`
+           found mutable reference `&mut PhantomPinned`
 
 error[E0308]: mismatched types
   --> $DIR/remove-attr-from-field.rs:31:38
    |
-31 |     let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
-   |            -----------------------   ^^^^^^^ expected struct `std::pin::Pin`, found `&mut std::marker::PhantomPinned`
+31 |     let _: Pin<&mut PhantomPinned> = x.f; //~ ERROR E0308
+   |            -----------------------   ^^^ expected struct `Pin`, found `&mut PhantomPinned`
    |            |
    |            expected due to this
    |
-   = note:         expected struct `std::pin::Pin<&mut std::marker::PhantomPinned>`
-           found mutable reference `&mut std::marker::PhantomPinned`
+   = note:         expected struct `Pin<&mut PhantomPinned>`
+           found mutable reference `&mut PhantomPinned`
diff --git a/tests/ui/pin_project/remove-attr-from-struct.rs b/tests/ui/pin_project/remove-attr-from-struct.rs
index 0c7af63..0086cf9 100644
--- a/tests/ui/pin_project/remove-attr-from-struct.rs
+++ b/tests/ui/pin_project/remove-attr-from-struct.rs
@@ -1,4 +1,4 @@
-use auxiliary_macros::remove_attr;
+use auxiliary_macro::remove_attr;
 use pin_project::pin_project;
 use std::{marker::PhantomPinned, pin::Pin};
 
@@ -8,26 +8,26 @@
 #[remove_attr(struct_all)]
 struct A {
     #[pin] //~ ERROR cannot find attribute `pin` in this scope
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 #[remove_attr(struct_all)]
 #[pin_project]
 struct B {
     #[pin] //~ ERROR cannot find attribute `pin` in this scope
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 #[pin_project] //~ ERROR has been removed
 #[remove_attr(struct_pin)]
 struct C {
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 #[remove_attr(struct_pin)]
 #[pin_project] // Ok
 struct D {
-    field: PhantomPinned,
+    f: PhantomPinned,
 }
 
 fn main() {
@@ -35,12 +35,12 @@
     is_unpin::<B>(); //~ ERROR E0277
     is_unpin::<D>(); // Ok
 
-    let mut x = A { field: PhantomPinned };
+    let mut x = A { f: PhantomPinned };
     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
 
-    let mut x = B { field: PhantomPinned };
+    let mut x = B { f: PhantomPinned };
     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
 
-    let mut x = D { field: PhantomPinned };
+    let mut x = D { f: 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 112584e..4652b66 100644
--- a/tests/ui/pin_project/remove-attr-from-struct.stderr
+++ b/tests/ui/pin_project/remove-attr-from-struct.stderr
@@ -7,65 +7,65 @@
    = 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
-   |
-10 |     #[pin] //~ ERROR cannot find attribute `pin` in this scope
-   |       ^^^
-
-error: cannot find attribute `pin` in this scope
   --> $DIR/remove-attr-from-struct.rs:17:7
    |
 17 |     #[pin] //~ ERROR cannot find attribute `pin` in this scope
    |       ^^^
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error: cannot find attribute `pin` in this scope
+  --> $DIR/remove-attr-from-struct.rs:10:7
+   |
+10 |     #[pin] //~ ERROR cannot find attribute `pin` in this scope
+   |       ^^^
+
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/remove-attr-from-struct.rs:34:5
    |
 5  | fn is_unpin<T: Unpin>() {}
    |                ----- required by this bound in `is_unpin`
 ...
 34 |     is_unpin::<A>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^ within `A`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^ within `A`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
    = note: required because it appears within the type `A`
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/remove-attr-from-struct.rs:35:5
    |
 5  | fn is_unpin<T: Unpin>() {}
    |                ----- required by this bound in `is_unpin`
 ...
 35 |     is_unpin::<B>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^ within `B`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^ within `B`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
    = note: required because it appears within the type `B`
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/remove-attr-from-struct.rs:39:13
    |
 39 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |             ^^^^^^^^ within `A`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |             ^^^^^^^^ within `A`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
    = note: required because it appears within the type `A`
-   = note: required by `std::pin::Pin::<P>::new`
+   = note: required by `Pin::<P>::new`
 
-error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut A>` in the current scope
+error[E0599]: no method named `project` found for struct `Pin<&mut A>` in the current scope
   --> $DIR/remove-attr-from-struct.rs:39:30
    |
 39 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |                              ^^^^^^^ method not found in `std::pin::Pin<&mut A>`
+   |                              ^^^^^^^ method not found in `Pin<&mut A>`
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/remove-attr-from-struct.rs:42:13
    |
 42 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |             ^^^^^^^^ within `B`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |             ^^^^^^^^ within `B`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
    = note: required because it appears within the type `B`
-   = note: required by `std::pin::Pin::<P>::new`
+   = note: required by `Pin::<P>::new`
 
-error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut B>` in the current scope
+error[E0599]: no method named `project` found for struct `Pin<&mut B>` in the current scope
   --> $DIR/remove-attr-from-struct.rs:42:30
    |
 42 |     let _ = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
-   |                              ^^^^^^^ method not found in `std::pin::Pin<&mut B>`
+   |                              ^^^^^^^ method not found in `Pin<&mut B>`
diff --git a/tests/ui/pin_project/safe_packed_borrows.rs b/tests/ui/pin_project/safe_packed_borrows.rs
index c1a7d55..db4ac2d 100644
--- a/tests/ui/pin_project/safe_packed_borrows.rs
+++ b/tests/ui/pin_project/safe_packed_borrows.rs
@@ -1,21 +1,21 @@
-#![deny(safe_packed_borrows)]
+#![forbid(safe_packed_borrows)]
 
 // Refs: https://github.com/rust-lang/rust/issues/46043
 
 #[repr(packed)]
 struct A {
-    field: u32,
+    f: u32,
 }
 
 #[repr(packed(2))]
 struct B {
-    field: u32,
+    f: u32,
 }
 
 fn main() {
-    let a = A { field: 1 };
-    &a.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+    let a = A { f: 1 };
+    &a.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
 
-    let b = B { field: 1 };
-    &b.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+    let b = B { f: 1 };
+    &b.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
 }
diff --git a/tests/ui/pin_project/safe_packed_borrows.stderr b/tests/ui/pin_project/safe_packed_borrows.stderr
index 7b4cc08..c1f734a 100644
--- a/tests/ui/pin_project/safe_packed_borrows.stderr
+++ b/tests/ui/pin_project/safe_packed_borrows.stderr
@@ -1,14 +1,14 @@
 error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
   --> $DIR/safe_packed_borrows.rs:17:5
    |
-17 |     &a.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
-   |     ^^^^^^^^
+17 |     &a.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+   |     ^^^^
    |
 note: the lint level is defined here
-  --> $DIR/safe_packed_borrows.rs:1:9
+  --> $DIR/safe_packed_borrows.rs:1:11
    |
-1  | #![deny(safe_packed_borrows)]
-   |         ^^^^^^^^^^^^^^^^^^^
+1  | #![forbid(safe_packed_borrows)]
+   |           ^^^^^^^^^^^^^^^^^^^
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
    = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
@@ -16,8 +16,8 @@
 error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
   --> $DIR/safe_packed_borrows.rs:20:5
    |
-20 |     &b.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
-   |     ^^^^^^^^
+20 |     &b.f; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+   |     ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
diff --git a/tests/ui/pin_project/unpin_sneaky.rs b/tests/ui/pin_project/unpin_sneaky.rs
index 3ccb1a9..3f5f32b 100644
--- a/tests/ui/pin_project/unpin_sneaky.rs
+++ b/tests/ui/pin_project/unpin_sneaky.rs
@@ -1,11 +1,11 @@
 use pin_project::pin_project;
 
 #[pin_project]
-struct Foo {
+struct S {
     #[pin]
-    inner: u8,
+    f: u8,
 }
 
-impl Unpin for __Foo {} //~ ERROR E0412,E0321
+impl Unpin for __S {} //~ ERROR E0412,E0321
 
 fn main() {}
diff --git a/tests/ui/pin_project/unpin_sneaky.stderr b/tests/ui/pin_project/unpin_sneaky.stderr
index 0637a66..ab5e794 100644
--- a/tests/ui/pin_project/unpin_sneaky.stderr
+++ b/tests/ui/pin_project/unpin_sneaky.stderr
@@ -1,11 +1,11 @@
-error[E0412]: cannot find type `__Foo` in this scope
+error[E0412]: cannot find type `__S` in this scope
  --> $DIR/unpin_sneaky.rs:9:16
   |
-9 | impl Unpin for __Foo {} //~ ERROR E0412,E0321
-  |                ^^^^^ not found in this scope
+9 | impl Unpin for __S {} //~ ERROR E0412,E0321
+  |                ^^^ not found in this scope
 
-error[E0321]: cross-crate traits with a default impl, like `std::marker::Unpin`, can only be implemented for a struct/enum type, not `[type error]`
+error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `[type error]`
  --> $DIR/unpin_sneaky.rs:9:1
   |
-9 | impl Unpin for __Foo {} //~ ERROR E0412,E0321
-  | ^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
+9 | impl Unpin for __S {} //~ ERROR E0412,E0321
+  | ^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
diff --git a/tests/ui/pin_project/visibility.rs b/tests/ui/pin_project/visibility.rs
index 01c0831..fdff5a6 100644
--- a/tests/ui/pin_project/visibility.rs
+++ b/tests/ui/pin_project/visibility.rs
@@ -1,82 +1,49 @@
+/// Only named projected types can be imported.
+/// See import_unnamed.rs for unnamed projected types.
+
 mod pub_ {
     use pin_project::pin_project;
 
-    #[pin_project]
-    pub struct Default(());
-
-    #[pin_project(project_replace)]
-    pub struct Replace(());
-}
-pub mod pub_use {
-    #[rustfmt::skip]
-    pub use crate::pub_::__DefaultProjection; //~ ERROR E0365
-    #[rustfmt::skip]
-    pub use crate::pub_::__DefaultProjectionRef; //~ ERROR E0365
-    #[rustfmt::skip]
-    pub use crate::pub_::__ReplaceProjection; //~ ERROR E0365
-    #[rustfmt::skip]
-    pub use crate::pub_::__ReplaceProjectionOwned; //~ ERROR E0365
-    #[rustfmt::skip]
-    pub use crate::pub_::__ReplaceProjectionRef; //~ ERROR E0365
-
-    // Confirm that the visibility of the original type is not changed.
-    pub use crate::pub_::{Default, Replace};
-}
-pub mod pub_use2 {
-    // Ok
-    #[allow(unused_imports)]
-    pub(crate) use crate::pub_::{
-        __DefaultProjection, __DefaultProjectionRef, __ReplaceProjection, __ReplaceProjectionOwned,
-        __ReplaceProjectionRef,
-    };
-}
-
-mod pub_crate {
-    use pin_project::pin_project;
-
-    #[pin_project]
-    pub(crate) struct Default(());
-
-    #[pin_project(project_replace)]
-    pub(crate) struct Replace(());
-}
-pub mod pub_crate_use {
-    // Ok
-    #[allow(unused_imports)]
-    pub(crate) use crate::pub_crate::{
-        __DefaultProjection, __DefaultProjectionRef, __ReplaceProjection, __ReplaceProjectionOwned,
-        __ReplaceProjectionRef,
-    };
-}
-
-mod pub_renamed {
-    use pin_project::pin_project;
-
     #[pin_project(project = DProj, project_ref = DProjRef)]
     pub struct Default(());
 
     #[pin_project(project = RProj, project_ref = RProjRef, project_replace = RProjOwn)]
     pub struct Replace(());
 }
-pub mod pub_renamed_use {
+pub mod pub_use {
     #[rustfmt::skip]
-    pub use crate::pub_renamed::DProj; //~ ERROR E0365
+    pub use crate::pub_::DProj; //~ ERROR E0365
     #[rustfmt::skip]
-    pub use crate::pub_renamed::DProjRef; //~ ERROR E0365
+    pub use crate::pub_::DProjRef; //~ ERROR E0365
     #[rustfmt::skip]
-    pub use crate::pub_renamed::RProj; //~ ERROR E0365
+    pub use crate::pub_::RProj; //~ ERROR E0365
     #[rustfmt::skip]
-    pub use crate::pub_renamed::RProjOwn; //~ ERROR E0365
+    pub use crate::pub_::RProjOwn; //~ ERROR E0365
     #[rustfmt::skip]
-    pub use crate::pub_renamed::RProjRef; //~ ERROR E0365
+    pub use crate::pub_::RProjRef; //~ ERROR E0365
 
     // Confirm that the visibility of the original type is not changed.
-    pub use crate::pub_renamed::{Default, Replace};
+    pub use crate::pub_::{Default, Replace};
 }
-pub mod pub_renamed_use2 {
+pub mod pub_use2 {
     // Ok
     #[allow(unused_imports)]
-    pub(crate) use crate::pub_renamed::{DProj, DProjRef, RProj, RProjOwn, RProjRef};
+    pub(crate) use crate::pub_::{DProj, DProjRef, RProj, RProjOwn, RProjRef};
+}
+
+mod pub_crate {
+    use pin_project::pin_project;
+
+    #[pin_project(project = DProj, project_ref = DProjRef)]
+    pub(crate) struct Default(());
+
+    #[pin_project(project = RProj, project_ref = RProjRef, project_replace = RProjOwn)]
+    pub(crate) struct Replace(());
+}
+pub mod pub_crate_use {
+    // Ok
+    #[allow(unused_imports)]
+    pub(crate) use crate::pub_crate::{DProj, DProjRef, RProj, RProjOwn, RProjRef};
 }
 
 fn main() {}
diff --git a/tests/ui/pin_project/visibility.stderr b/tests/ui/pin_project/visibility.stderr
index cab0e2e..a1f0423 100644
--- a/tests/ui/pin_project/visibility.stderr
+++ b/tests/ui/pin_project/visibility.stderr
@@ -1,79 +1,39 @@
-error[E0365]: `__DefaultProjection` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:12:13
-   |
-12 |     pub use crate::pub_::__DefaultProjection; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `__DefaultProjection`
-   |
-   = note: consider declaring type or module `__DefaultProjection` with `pub`
-
-error[E0365]: `__DefaultProjectionRef` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:14:13
-   |
-14 |     pub use crate::pub_::__DefaultProjectionRef; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `__DefaultProjectionRef`
-   |
-   = note: consider declaring type or module `__DefaultProjectionRef` with `pub`
-
-error[E0365]: `__ReplaceProjection` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:16:13
-   |
-16 |     pub use crate::pub_::__ReplaceProjection; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `__ReplaceProjection`
-   |
-   = note: consider declaring type or module `__ReplaceProjection` with `pub`
-
-error[E0365]: `__ReplaceProjectionOwned` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:18:13
-   |
-18 |     pub use crate::pub_::__ReplaceProjectionOwned; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `__ReplaceProjectionOwned`
-   |
-   = note: consider declaring type or module `__ReplaceProjectionOwned` with `pub`
-
-error[E0365]: `__ReplaceProjectionRef` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:20:13
-   |
-20 |     pub use crate::pub_::__ReplaceProjectionRef; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `__ReplaceProjectionRef`
-   |
-   = note: consider declaring type or module `__ReplaceProjectionRef` with `pub`
-
 error[E0365]: `DProj` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:63:13
+  --> $DIR/visibility.rs:15:13
    |
-63 |     pub use crate::pub_renamed::DProj; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `DProj`
+15 |     pub use crate::pub_::DProj; //~ ERROR E0365
+   |             ^^^^^^^^^^^^^^^^^^ re-export of private `DProj`
    |
    = note: consider declaring type or module `DProj` with `pub`
 
 error[E0365]: `DProjRef` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:65:13
+  --> $DIR/visibility.rs:17:13
    |
-65 |     pub use crate::pub_renamed::DProjRef; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `DProjRef`
+17 |     pub use crate::pub_::DProjRef; //~ ERROR E0365
+   |             ^^^^^^^^^^^^^^^^^^^^^ re-export of private `DProjRef`
    |
    = note: consider declaring type or module `DProjRef` with `pub`
 
 error[E0365]: `RProj` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:67:13
+  --> $DIR/visibility.rs:19:13
    |
-67 |     pub use crate::pub_renamed::RProj; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `RProj`
+19 |     pub use crate::pub_::RProj; //~ ERROR E0365
+   |             ^^^^^^^^^^^^^^^^^^ re-export of private `RProj`
    |
    = note: consider declaring type or module `RProj` with `pub`
 
 error[E0365]: `RProjOwn` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:69:13
+  --> $DIR/visibility.rs:21:13
    |
-69 |     pub use crate::pub_renamed::RProjOwn; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `RProjOwn`
+21 |     pub use crate::pub_::RProjOwn; //~ ERROR E0365
+   |             ^^^^^^^^^^^^^^^^^^^^^ re-export of private `RProjOwn`
    |
    = note: consider declaring type or module `RProjOwn` with `pub`
 
 error[E0365]: `RProjRef` is private, and cannot be re-exported
-  --> $DIR/visibility.rs:71:13
+  --> $DIR/visibility.rs:23:13
    |
-71 |     pub use crate::pub_renamed::RProjRef; //~ ERROR E0365
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ re-export of private `RProjRef`
+23 |     pub use crate::pub_::RProjRef; //~ ERROR E0365
+   |             ^^^^^^^^^^^^^^^^^^^^^ re-export of private `RProjRef`
    |
    = note: consider declaring type or module `RProjRef` with `pub`
diff --git a/tests/ui/pinned_drop/call-drop-inner.rs b/tests/ui/pinned_drop/call-drop-inner.rs
index c953acb..4171ed5 100644
--- a/tests/ui/pinned_drop/call-drop-inner.rs
+++ b/tests/ui/pinned_drop/call-drop-inner.rs
@@ -3,7 +3,7 @@
 
 #[pin_project(PinnedDrop)]
 struct Struct {
-    dropped: bool,
+    f: bool,
 }
 
 #[pinned_drop]
diff --git a/tests/ui/pinned_drop/call-drop-inner.stderr b/tests/ui/pinned_drop/call-drop-inner.stderr
index eb55ce7..53194b0 100644
--- a/tests/ui/pinned_drop/call-drop-inner.stderr
+++ b/tests/ui/pinned_drop/call-drop-inner.stderr
@@ -1,10 +1,14 @@
 error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/call-drop-inner.rs:12:9
    |
-9  | #[pinned_drop]
-   | -------------- defined here
-...
 12 |         __drop_inner(__self);
    |         ^^^^^^^^^^^^ ------ supplied 1 argument
    |         |
    |         expected 0 arguments
+   |
+note: function defined here
+  --> $DIR/call-drop-inner.rs:9:1
+   |
+9  | #[pinned_drop]
+   | ^^^^^^^^^^^^^^
+   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pinned_drop/conditional-drop-impl.rs b/tests/ui/pinned_drop/conditional-drop-impl.rs
index 42d18b7..fecfd50 100644
--- a/tests/ui/pinned_drop/conditional-drop-impl.rs
+++ b/tests/ui/pinned_drop/conditional-drop-impl.rs
@@ -4,7 +4,7 @@
 // In `Drop` impl, the implementor must specify the same requirement as type definition.
 
 struct DropImpl<T> {
-    field: T,
+    f: T,
 }
 
 impl<T: Unpin> Drop for DropImpl<T> {
@@ -15,7 +15,7 @@
 #[pin_project(PinnedDrop)] //~ ERROR E0277
 struct PinnedDropImpl<T> {
     #[pin]
-    field: T,
+    f: T,
 }
 
 #[pinned_drop]
diff --git a/tests/ui/pinned_drop/conditional-drop-impl.stderr b/tests/ui/pinned_drop/conditional-drop-impl.stderr
index ad8fb69..6381a29 100644
--- a/tests/ui/pinned_drop/conditional-drop-impl.stderr
+++ b/tests/ui/pinned_drop/conditional-drop-impl.stderr
@@ -1,4 +1,4 @@
-error[E0367]: `Drop` impl requires `T: std::marker::Unpin` but the struct it is implemented for does not
+error[E0367]: `Drop` impl requires `T: Unpin` but the struct it is implemented for does not
   --> $DIR/conditional-drop-impl.rs:10:9
    |
 10 | impl<T: Unpin> Drop for DropImpl<T> {
@@ -8,7 +8,7 @@
   --> $DIR/conditional-drop-impl.rs:6:1
    |
 6  | / struct DropImpl<T> {
-7  | |     field: T,
+7  | |     f: T,
 8  | | }
    | |_^
 
@@ -16,11 +16,11 @@
   --> $DIR/conditional-drop-impl.rs:15:15
    |
 15 | #[pin_project(PinnedDrop)] //~ ERROR E0277
-   |               ^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `T`
+   |               ^^^^^^^^^^ the trait `Unpin` is not implemented for `T`
    |
-   = note: required because of the requirements on the impl of `pin_project::__private::PinnedDrop` for `PinnedDropImpl<T>`
+   = note: required because of the requirements on the impl of `PinnedDrop` for `PinnedDropImpl<T>`
    = note: required by `pin_project::__private::PinnedDrop::drop`
 help: consider restricting type parameter `T`
    |
-16 | struct PinnedDropImpl<T: std::marker::Unpin> {
-   |                        ^^^^^^^^^^^^^^^^^^^^
+16 | struct PinnedDropImpl<T: Unpin> {
+   |                        ^^^^^^^
diff --git a/tests/ui/pinned_drop/forget-pinned-drop-impl.rs b/tests/ui/pinned_drop/forget-pinned-drop-impl.rs
index 6c9f718..e31f46f 100644
--- a/tests/ui/pinned_drop/forget-pinned-drop-impl.rs
+++ b/tests/ui/pinned_drop/forget-pinned-drop-impl.rs
@@ -3,7 +3,7 @@
 #[pin_project(PinnedDrop)] //~ ERROR E0277
 struct Struct {
     #[pin]
-    field: u8,
+    f: u8,
 }
 
 fn main() {}
diff --git a/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr b/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr
index 67bdbe1..9fd7cdb 100644
--- a/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr
+++ b/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr
@@ -1,7 +1,7 @@
-error[E0277]: the trait bound `Struct: pin_project::__private::PinnedDrop` is not satisfied
+error[E0277]: the trait bound `Struct: PinnedDrop` is not satisfied
  --> $DIR/forget-pinned-drop-impl.rs:3:15
   |
 3 | #[pin_project(PinnedDrop)] //~ ERROR E0277
-  |               ^^^^^^^^^^ the trait `pin_project::__private::PinnedDrop` is not implemented for `Struct`
+  |               ^^^^^^^^^^ the trait `PinnedDrop` is not implemented for `Struct`
   |
   = note: required by `pin_project::__private::PinnedDrop::drop`
diff --git a/tests/ui/pinned_drop/invalid-self.rs b/tests/ui/pinned_drop/invalid-self.rs
index 73d3b43..783167f 100644
--- a/tests/ui/pinned_drop/invalid-self.rs
+++ b/tests/ui/pinned_drop/invalid-self.rs
@@ -2,13 +2,13 @@
 
 use std::pin::Pin;
 
-struct Struct {}
+struct S {}
 
-impl Struct {
+impl S {
     fn take_ref_self(ref self: Pin<&mut Self>) {} //~ ERROR expected identifier, found keyword `self`
     fn take_ref_mut_self(ref mut self: Pin<&mut Self>) {} //~ ERROR expected identifier, found keyword `self`
 
-    fn self_subpat(self @ Struct {}: Self) {} //~ ERROR expected one of `)`, `,`, or `:`, found `@`
+    fn self_subpat(self @ S {}: Self) {} //~ ERROR expected one of `)`, `,`, or `:`, found `@`
 }
 
 fn main() {}
diff --git a/tests/ui/pinned_drop/invalid-self.stderr b/tests/ui/pinned_drop/invalid-self.stderr
index a43e91d..3248704 100644
--- a/tests/ui/pinned_drop/invalid-self.stderr
+++ b/tests/ui/pinned_drop/invalid-self.stderr
@@ -13,13 +13,13 @@
 error: expected parameter name, found `@`
   --> $DIR/invalid-self.rs:11:25
    |
-11 |     fn self_subpat(self @ Struct {}: Self) {} //~ ERROR expected one of `)`, `,`, or `:`, found `@`
+11 |     fn self_subpat(self @ S {}: Self) {} //~ ERROR expected one of `)`, `,`, or `:`, found `@`
    |                         ^ expected parameter name
 
 error: expected one of `)`, `,`, or `:`, found `@`
   --> $DIR/invalid-self.rs:11:25
    |
-11 |     fn self_subpat(self @ Struct {}: Self) {} //~ ERROR expected one of `)`, `,`, or `:`, found `@`
+11 |     fn self_subpat(self @ S {}: Self) {} //~ ERROR expected one of `)`, `,`, or `:`, found `@`
    |                        -^ expected one of `)`, `,`, or `:`
    |                        |
    |                        help: missing `,`
diff --git a/tests/ui/pinned_drop/invalid.rs b/tests/ui/pinned_drop/invalid.rs
index 7065ec9..7e36750 100644
--- a/tests/ui/pinned_drop/invalid.rs
+++ b/tests/ui/pinned_drop/invalid.rs
@@ -48,7 +48,7 @@
     impl InherentImpl {} //~ ERROR may only be used on implementation for the `PinnedDrop` trait
 
     #[pinned_drop]
-    fn drop(_: Pin<&mut ()>) {} //~ ERROR expected `impl`
+    fn func(_: Pin<&mut ()>) {} //~ ERROR expected `impl`
 }
 
 mod unsafety {
@@ -200,7 +200,7 @@
 
     #[pinned_drop]
     impl PinnedDrop for InvalidName {
-        fn pinned_drop(&mut self) {} //~ ERROR method `pinned_drop` is not a member of trait `PinnedDrop
+        fn pinned_drop(self: Pin<&mut Self>) {} //~ ERROR method `pinned_drop` is not a member of trait `PinnedDrop
     }
 }
 
diff --git a/tests/ui/pinned_drop/invalid.stderr b/tests/ui/pinned_drop/invalid.stderr
index 65ef9ff..277a2fa 100644
--- a/tests/ui/pinned_drop/invalid.stderr
+++ b/tests/ui/pinned_drop/invalid.stderr
@@ -25,7 +25,7 @@
 error: expected `impl`
   --> $DIR/invalid.rs:51:5
    |
-51 |     fn drop(_: Pin<&mut ()>) {} //~ ERROR expected `impl`
+51 |     fn func(_: Pin<&mut ()>) {} //~ ERROR expected `impl`
    |     ^^
 
 error: implementing the trait `PinnedDrop` is not unsafe
@@ -121,7 +121,7 @@
 error: method `pinned_drop` is not a member of trait `PinnedDrop
    --> $DIR/invalid.rs:203:12
     |
-203 |         fn pinned_drop(&mut self) {} //~ ERROR method `pinned_drop` is not a member of trait `PinnedDrop
+203 |         fn pinned_drop(self: Pin<&mut Self>) {} //~ ERROR method `pinned_drop` is not a member of trait `PinnedDrop
     |            ^^^^^^^^^^^
 
 error: implementing the trait `PinnedDrop` on this type is unsupported
diff --git a/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs b/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs
index 1241b5b..f9db79c 100644
--- a/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs
+++ b/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs
@@ -2,13 +2,14 @@
 use std::pin::Pin;
 
 #[pin_project]
-struct Foo {
+struct S {
     #[pin]
-    field: u8,
+    f: u8,
 }
 
 #[pinned_drop]
-impl PinnedDrop for Foo { //~ ERROR E0119
+impl PinnedDrop for S {
+    //~^ ERROR E0119
     fn drop(self: Pin<&mut Self>) {}
 }
 
diff --git a/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr b/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr
index 7353dc4..6f868bf 100644
--- a/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr
+++ b/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr
@@ -1,8 +1,8 @@
-error[E0119]: conflicting implementations of trait `pin_project::__private::PinnedDrop` for type `Foo`:
+error[E0119]: conflicting implementations of trait `pin_project::__private::PinnedDrop` for type `S`:
   --> $DIR/pinned-drop-no-attr-arg.rs:11:1
    |
 4  | #[pin_project]
    | -------------- first implementation here
 ...
-11 | impl PinnedDrop for Foo { //~ ERROR E0119
-   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Foo`
+11 | impl PinnedDrop for S {
+   | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S`
diff --git a/tests/ui/pinned_drop/self.rs b/tests/ui/pinned_drop/self.rs
index 9176066..03825ca 100644
--- a/tests/ui/pinned_drop/self.rs
+++ b/tests/ui/pinned_drop/self.rs
@@ -3,12 +3,12 @@
     use std::pin::Pin;
 
     #[pin_project(PinnedDrop)]
-    pub struct Struct {
-        x: (),
+    pub struct S {
+        f: (),
     }
 
     #[pinned_drop]
-    impl PinnedDrop for Struct {
+    impl PinnedDrop for S {
         fn drop(self: Pin<&mut Self>) {
             macro_rules! t {
                 () => {{
@@ -28,7 +28,7 @@
 
     #[pin_project(PinnedDrop)]
     pub struct S {
-        x: (),
+        f: (),
     }
 
     #[pinned_drop]
@@ -41,7 +41,7 @@
 
     #[pin_project(PinnedDrop)]
     pub enum E {
-        V { x: () },
+        V { f: () },
     }
 
     #[pinned_drop]
diff --git a/tests/ui/pinned_drop/self.stderr b/tests/ui/pinned_drop/self.stderr
index 4ac0e63..edab117 100644
--- a/tests/ui/pinned_drop/self.stderr
+++ b/tests/ui/pinned_drop/self.stderr
@@ -26,34 +26,34 @@
   --> $DIR/self.rs:38:27
    |
 30 | /     pub struct S {
-31 | |         x: (),
+31 | |         f: (),
 32 | |     }
    | |_____- `S` defined here
 ...
 38 |               let _: Self = Self; //~ ERROR E0423
-   |                             ^^^^ help: use struct literal syntax instead: `S { x: val }`
+   |                             ^^^^ help: use struct literal syntax instead: `S { f: val }`
 
 error[E0308]: mismatched types
   --> $DIR/self.rs:37:25
    |
 37 |             let _: () = self; //~ ERROR E0308
-   |                    --   ^^^^ expected `()`, found struct `std::pin::Pin`
+   |                    --   ^^^^ expected `()`, found struct `Pin`
    |                    |
    |                    expected due to this
    |
    = note: expected unit type `()`
-                 found struct `std::pin::Pin<&mut self_span::S>`
+                 found struct `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 `()`, found struct `Pin`
    |                    |
    |                    expected due to this
    |
    = note: expected unit type `()`
-                 found struct `std::pin::Pin<&mut self_span::E>`
+                 found struct `Pin<&mut E>`
 
 error[E0533]: expected unit struct, unit variant or constant, found struct variant `Self::V`
   --> $DIR/self.rs:51:27
diff --git a/tests/ui/pinned_drop/unsafe-call.rs b/tests/ui/pinned_drop/unsafe-call.rs
index 2f400c1..7faf0fa 100644
--- a/tests/ui/pinned_drop/unsafe-call.rs
+++ b/tests/ui/pinned_drop/unsafe-call.rs
@@ -2,15 +2,15 @@
 use std::pin::Pin;
 
 #[pin_project(PinnedDrop)]
-struct Struct {
+struct S {
     #[pin]
-    field: u8,
+    f: u8,
 }
 
 #[pinned_drop]
-impl PinnedDrop for Struct {
+impl PinnedDrop for S {
     fn drop(self: Pin<&mut Self>) {
-        self.project().field.get_unchecked_mut(); //~ ERROR call to unsafe function is unsafe and requires unsafe function or block [E0133]
+        self.project().f.get_unchecked_mut(); //~ ERROR call to unsafe function is unsafe and requires unsafe function or block [E0133]
     }
 }
 
diff --git a/tests/ui/pinned_drop/unsafe-call.stderr b/tests/ui/pinned_drop/unsafe-call.stderr
index 4e8e00b..cd5e572 100644
--- a/tests/ui/pinned_drop/unsafe-call.stderr
+++ b/tests/ui/pinned_drop/unsafe-call.stderr
@@ -1,7 +1,7 @@
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
   --> $DIR/unsafe-call.rs:13:9
    |
-13 |         self.project().field.get_unchecked_mut(); //~ ERROR call to unsafe function is unsafe and requires unsafe function or block [E0133]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+13 |         self.project().f.get_unchecked_mut(); //~ ERROR call to unsafe function is unsafe and requires unsafe function or block [E0133]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
    |
    = note: consult the function's documentation for information on how to avoid undefined behavior
diff --git a/tests/ui/project/ambiguous-let.rs b/tests/ui/project/ambiguous-let.rs
deleted file mode 100644
index bbb3a2c..0000000
--- a/tests/ui/project/ambiguous-let.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-#![allow(deprecated)]
-
-use pin_project::{pin_project, project};
-
-#[pin_project]
-enum Enum<A, B> {
-    A(#[pin] A),
-    B(B),
-}
-
-struct Struct<T>(T);
-
-#[project]
-fn foo() {
-    let mut foo: Enum<bool, bool> = Enum::A(true);
-
-    #[project]
-    let Struct(x) = match Pin::new(&mut foo).project() {
-        //~^ ERROR Both initializer expression and pattern are replaceable, you need to split the initializer expression into separate let bindings to avoid ambiguity
-        Enum::A(_) => Struct(true),
-        Enum::B(_) => unreachable!(),
-    };
-    assert!(x);
-}
-
-fn main() {}
diff --git a/tests/ui/project/ambiguous-let.stderr b/tests/ui/project/ambiguous-let.stderr
deleted file mode 100644
index 2e66484..0000000
--- a/tests/ui/project/ambiguous-let.stderr
+++ /dev/null
@@ -1,5 +0,0 @@
-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:18:9
-   |
-18 |     let Struct(x) = match Pin::new(&mut foo).project() {
-   |         ^^^^^^^^^
diff --git a/tests/ui/project/deprecated.rs b/tests/ui/project/deprecated.rs
deleted file mode 100644
index 78d593d..0000000
--- a/tests/ui/project/deprecated.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-#![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
deleted file mode 100644
index 015b8df..0000000
--- a/tests/ui/project/deprecated.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644
index e72f84c..0000000
--- a/tests/ui/project/invalid.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-#![allow(deprecated)]
-
-mod argument {
-    use pin_project::{pin_project, project};
-
-    #[pin_project]
-    struct A(#[pin] ());
-
-    #[project]
-    fn unexpected_local1() {
-        let mut x = A(());
-        #[project()] //~ ERROR unexpected token
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project]
-    fn unexpected_local1() {
-        let mut x = A(());
-        #[project(foo)] //~ ERROR unexpected token
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project]
-    fn unexpected_expr1() {
-        let mut x = A(());
-        #[project()] //~ ERROR unexpected token
-        match Pin::new(&mut x).project() {
-            A(_) => {}
-        }
-    }
-
-    #[project]
-    fn unexpected_expr1() {
-        let mut x = A(());
-        #[project(foo)] //~ ERROR unexpected token
-        match Pin::new(&mut x).project() {
-            A(_) => {}
-        }
-    }
-
-    #[project()] // Ok
-    fn unexpected_item1() {}
-
-    #[project(foo)] //~ ERROR unexpected token
-    fn unexpected_item2() {}
-}
-
-mod attribute {
-    use pin_project::{pin_project, project, project_ref, project_replace};
-
-    #[pin_project(project_replace)]
-    struct A(#[pin] ());
-
-    #[project]
-    fn duplicate_stmt_project() {
-        let mut x = A(());
-        #[project]
-        #[project] //~ ERROR duplicate #[project] attribute
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_ref]
-    fn duplicate_stmt_project_ref() {
-        let mut x = A(());
-        #[project_ref]
-        #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_replace]
-    fn duplicate_stmt_project_replace() {
-        let mut x = A(());
-        #[project_replace]
-        #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project]
-    fn combine_stmt_project1() {
-        let mut x = A(());
-        #[project]
-        #[project_ref] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project]
-    fn combine_stmt_project2() {
-        let mut x = A(());
-        #[project]
-        #[project_replace] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project]
-    fn combine_stmt_project3() {
-        let mut x = A(());
-        #[project_ref]
-        #[project_replace] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_ref]
-    fn combine_stmt_project_ref1() {
-        let mut x = A(());
-        #[project]
-        #[project_ref] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_ref]
-    fn combine_stmt_project_ref2() {
-        let mut x = A(());
-        #[project]
-        #[project_replace] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_ref]
-    fn combine_stmt_project_ref3() {
-        let mut x = A(());
-        #[project_ref]
-        #[project_replace] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_replace]
-    fn combine_stmt_project_replace1() {
-        let mut x = A(());
-        #[project]
-        #[project_ref] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_replace]
-    fn combine_stmt_project_replace2() {
-        let mut x = A(());
-        #[project]
-        #[project_replace] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project_replace]
-    fn combine_stmt_project_replace3() {
-        let mut x = A(());
-        #[project_ref]
-        #[project_replace] //~ ERROR are mutually exclusive
-        let A(_) = Pin::new(&mut x).project();
-    }
-
-    #[project]
-    #[project] //~ ERROR duplicate #[project] attribute
-    fn duplicate_fn_project() {}
-
-    #[project_ref]
-    #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-    fn duplicate_fn_project_ref() {}
-
-    #[project_replace]
-    #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-    fn duplicate_fn_project_replace() {}
-
-    #[project]
-    #[project] //~ ERROR duplicate #[project] attribute
-    impl A {}
-
-    #[project_ref]
-    #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-    impl A {}
-
-    #[project_replace]
-    #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-    impl A {}
-
-    #[allow(unused_imports)]
-    mod use_ {
-        use pin_project::{project, project_ref, project_replace};
-
-        #[project]
-        #[project] //~ ERROR duplicate #[project] attribute
-        use super::A;
-
-        #[project_ref]
-        #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-        use super::A;
-
-        #[project_replace]
-        #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-        use super::A;
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/project/invalid.stderr b/tests/ui/project/invalid.stderr
deleted file mode 100644
index e1dc388..0000000
--- a/tests/ui/project/invalid.stderr
+++ /dev/null
@@ -1,155 +0,0 @@
-error: unexpected token: ()
-  --> $DIR/invalid.rs:12:18
-   |
-12 |         #[project()] //~ ERROR unexpected token
-   |                  ^^
-
-error: unexpected token: (foo)
-  --> $DIR/invalid.rs:19:18
-   |
-19 |         #[project(foo)] //~ ERROR unexpected token
-   |                  ^^^^^
-
-error: unexpected token: ()
-  --> $DIR/invalid.rs:26:18
-   |
-26 |         #[project()] //~ ERROR unexpected token
-   |                  ^^
-
-error: unexpected token: (foo)
-  --> $DIR/invalid.rs:35:18
-   |
-35 |         #[project(foo)] //~ ERROR unexpected token
-   |                  ^^^^^
-
-error: unexpected token: foo
-  --> $DIR/invalid.rs:44:15
-   |
-44 |     #[project(foo)] //~ ERROR unexpected token
-   |               ^^^
-
-error: duplicate #[project] attribute
-  --> $DIR/invalid.rs:58:9
-   |
-58 |         #[project] //~ ERROR duplicate #[project] attribute
-   |         ^^^^^^^^^^
-
-error: duplicate #[project_ref] attribute
-  --> $DIR/invalid.rs:66:9
-   |
-66 |         #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-   |         ^^^^^^^^^^^^^^
-
-error: duplicate #[project_replace] attribute
-  --> $DIR/invalid.rs:74:9
-   |
-74 |         #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-   |         ^^^^^^^^^^^^^^^^^^
-
-error: attributes `project` and `project_ref` are mutually exclusive
-  --> $DIR/invalid.rs:82:9
-   |
-82 |         #[project_ref] //~ ERROR are mutually exclusive
-   |         ^^^^^^^^^^^^^^
-
-error: attributes `project` and `project_replace` are mutually exclusive
-  --> $DIR/invalid.rs:90:9
-   |
-90 |         #[project_replace] //~ ERROR are mutually exclusive
-   |         ^^^^^^^^^^^^^^^^^^
-
-error: attributes `project_ref` and `project_replace` are mutually exclusive
-  --> $DIR/invalid.rs:98:9
-   |
-98 |         #[project_replace] //~ ERROR are mutually exclusive
-   |         ^^^^^^^^^^^^^^^^^^
-
-error: attributes `project` and `project_ref` are mutually exclusive
-   --> $DIR/invalid.rs:106:9
-    |
-106 |         #[project_ref] //~ ERROR are mutually exclusive
-    |         ^^^^^^^^^^^^^^
-
-error: attributes `project` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:114:9
-    |
-114 |         #[project_replace] //~ ERROR are mutually exclusive
-    |         ^^^^^^^^^^^^^^^^^^
-
-error: attributes `project_ref` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:122:9
-    |
-122 |         #[project_replace] //~ ERROR are mutually exclusive
-    |         ^^^^^^^^^^^^^^^^^^
-
-error: attributes `project` and `project_ref` are mutually exclusive
-   --> $DIR/invalid.rs:130:9
-    |
-130 |         #[project_ref] //~ ERROR are mutually exclusive
-    |         ^^^^^^^^^^^^^^
-
-error: attributes `project` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:138:9
-    |
-138 |         #[project_replace] //~ ERROR are mutually exclusive
-    |         ^^^^^^^^^^^^^^^^^^
-
-error: attributes `project_ref` and `project_replace` are mutually exclusive
-   --> $DIR/invalid.rs:146:9
-    |
-146 |         #[project_replace] //~ ERROR are mutually exclusive
-    |         ^^^^^^^^^^^^^^^^^^
-
-error: duplicate #[project] attribute
-   --> $DIR/invalid.rs:151:5
-    |
-151 |     #[project] //~ ERROR duplicate #[project] attribute
-    |     ^^^^^^^^^^
-
-error: duplicate #[project_ref] attribute
-   --> $DIR/invalid.rs:155:5
-    |
-155 |     #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-    |     ^^^^^^^^^^^^^^
-
-error: duplicate #[project_replace] attribute
-   --> $DIR/invalid.rs:159:5
-    |
-159 |     #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-    |     ^^^^^^^^^^^^^^^^^^
-
-error: duplicate #[project] attribute
-   --> $DIR/invalid.rs:163:5
-    |
-163 |     #[project] //~ ERROR duplicate #[project] attribute
-    |     ^^^^^^^^^^
-
-error: duplicate #[project_ref] attribute
-   --> $DIR/invalid.rs:167:5
-    |
-167 |     #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-    |     ^^^^^^^^^^^^^^
-
-error: duplicate #[project_replace] attribute
-   --> $DIR/invalid.rs:171:5
-    |
-171 |     #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-    |     ^^^^^^^^^^^^^^^^^^
-
-error: duplicate #[project] attribute
-   --> $DIR/invalid.rs:179:9
-    |
-179 |         #[project] //~ ERROR duplicate #[project] attribute
-    |         ^^^^^^^^^^
-
-error: duplicate #[project_ref] attribute
-   --> $DIR/invalid.rs:183:9
-    |
-183 |         #[project_ref] //~ ERROR duplicate #[project_ref] attribute
-    |         ^^^^^^^^^^^^^^
-
-error: duplicate #[project_replace] attribute
-   --> $DIR/invalid.rs:187:9
-    |
-187 |         #[project_replace] //~ ERROR duplicate #[project_replace] attribute
-    |         ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/project/type-mismatch.rs b/tests/ui/project/type-mismatch.rs
deleted file mode 100644
index 0e40c83..0000000
--- a/tests/ui/project/type-mismatch.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-#![allow(deprecated)]
-#![feature(proc_macro_hygiene, stmt_expr_attributes)]
-
-use pin_project::{pin_project, project};
-use std::pin::Pin;
-
-#[project]
-fn type_mismatch() {
-    #[pin_project]
-    enum Enum<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
-            #[pin]
-            field1: C,
-            field2: D,
-        },
-        None,
-    }
-
-    let mut foo = Enum::Variant1(1, 2);
-    let mut foo = Pin::new(&mut foo).project();
-
-    #[project]
-    match &mut foo {
-        Enum::Variant1(x, y) => {
-            let x: &mut Pin<&mut i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &mut &mut i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Enum::Variant2 { field1, field2 } => {
-            let _x: &mut Pin<&mut i32> = field1;
-            let _y: &mut &mut i32 = field2;
-        }
-        None => {} //~ ERROR mismatched types
-    }
-}
-
-fn type_mismatch_span_issue() {
-    #[pin_project]
-    enum Enum<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
-            #[pin]
-            field1: C,
-            field2: D,
-        },
-        None,
-    }
-
-    let mut foo = Enum::Variant1(1, 2);
-    let mut foo = Pin::new(&mut foo).project();
-
-    #[project]
-    match &mut foo {
-        Enum::Variant1(x, y) => {
-            let x: &mut Pin<&mut i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &mut &mut i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Enum::Variant2 { field1, field2 } => {
-            let _x: &mut Pin<&mut i32> = field1;
-            let _y: &mut &mut i32 = field2;
-        }
-        None => {} //~ ERROR mismatched types
-    }
-}
-
-fn main() {}
diff --git a/tests/ui/project/type-mismatch.stderr b/tests/ui/project/type-mismatch.stderr
deleted file mode 100644
index 4199c17..0000000
--- a/tests/ui/project/type-mismatch.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/type-mismatch.rs:36:9
-   |
-24 |     match &mut foo {
-   |           -------- this expression has type `&mut type_mismatch::__EnumProjection<'_, {integer}, {integer}, _, _>`
-...
-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
-  --> $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
deleted file mode 100644
index aa82a95..0000000
--- a/tests/ui/project/use-public.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#![allow(deprecated)]
-
-use pin_project::pin_project;
-
-#[pin_project]
-struct A {
-    field: u8,
-}
-
-pub mod b {
-    use pin_project::project;
-
-    #[project]
-    pub use crate::A; //~ ERROR E0365
-}
-
-fn main() {}
diff --git a/tests/ui/project/use-public.stderr b/tests/ui/project/use-public.stderr
deleted file mode 100644
index 6956656..0000000
--- a/tests/ui/project/use-public.stderr
+++ /dev/null
@@ -1,7 +0,0 @@
-error[E0365]: `__AProjection` is private, and cannot be re-exported
-  --> $DIR/use-public.rs:14:13
-   |
-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
deleted file mode 100644
index ba56382..0000000
--- a/tests/ui/project/use.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-#![allow(deprecated)]
-
-use pin_project::pin_project;
-
-#[pin_project]
-struct A {
-    field: u8,
-}
-
-mod b {
-    use pin_project::project;
-
-    #[project]
-    use crate::A as B; //~ ERROR #[project] attribute may not be used on renamed imports
-    #[project]
-    use crate::*; //~ ERROR #[project] attribute may not be used on glob imports
-}
-
-fn main() {}
diff --git a/tests/ui/project/use.stderr b/tests/ui/project/use.stderr
deleted file mode 100644
index daddb16..0000000
--- a/tests/ui/project/use.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: #[project] attribute may not be used on renamed imports
-  --> $DIR/use.rs:14:16
-   |
-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:16:16
-   |
-16 |     use crate::*; //~ ERROR #[project] attribute may not be used on glob imports
-   |                ^
diff --git a/tests/ui/unsafe_unpin/conflict-unpin.rs b/tests/ui/unsafe_unpin/conflict-unpin.rs
index e0c8a7b..ac9d1f8 100644
--- a/tests/ui/unsafe_unpin/conflict-unpin.rs
+++ b/tests/ui/unsafe_unpin/conflict-unpin.rs
@@ -3,8 +3,8 @@
 #[pin_project(UnsafeUnpin)] //~ ERROR E0119
 struct Foo<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 impl<T, U> Unpin for Foo<T, U> where T: Unpin {}
@@ -12,8 +12,8 @@
 #[pin_project(UnsafeUnpin)] //~ ERROR E0119
 struct Bar<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 impl<T, U> Unpin for Bar<T, U> {}
@@ -21,8 +21,8 @@
 #[pin_project(UnsafeUnpin)] //~ ERROR E0119
 struct Baz<T, U> {
     #[pin]
-    future: T,
-    field: U,
+    f1: T,
+    f2: U,
 }
 
 impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {}
diff --git a/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs b/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs
deleted file mode 100644
index 429d60f..0000000
--- a/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use pin_project::pin_project;
-
-#[pin_project(UnsafeUnpin)]
-struct Struct<T, U> {
-    #[pin]
-    inner: T,
-    other: U,
-}
-
-fn is_unpin<T: Unpin>() {}
-
-fn main() {
-    is_unpin::<Struct<(), ()>>(); //~ ERROR E0277
-}
diff --git a/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr b/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr
deleted file mode 100644
index 0baefe3..0000000
--- a/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0277]: the trait bound `Struct<(), ()>: pin_project::UnsafeUnpin` is not satisfied
-  --> $DIR/not-implement-unsafe-unpin.rs:13:16
-   |
-10 | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-13 |     is_unpin::<Struct<(), ()>>(); //~ ERROR E0277
-   |                ^^^^^^^^^^^^^^ the trait `pin_project::UnsafeUnpin` is not implemented for `Struct<(), ()>`
-   |
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, Struct<(), ()>>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Struct<(), ()>`
diff --git a/tests/ui/unsafe_unpin/proper_unpin.rs b/tests/ui/unsafe_unpin/proper_unpin.rs
deleted file mode 100644
index 6573aec..0000000
--- a/tests/ui/unsafe_unpin/proper_unpin.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-use pin_project::{pin_project, UnsafeUnpin};
-use std::marker::PhantomPinned;
-
-fn is_unpin<T: Unpin>() {}
-
-#[pin_project(UnsafeUnpin)]
-struct Blah<T, U> {
-    field1: U,
-    #[pin]
-    field2: T,
-}
-
-unsafe impl<T: Unpin, U> UnsafeUnpin for Blah<T, U> {}
-
-#[pin_project(UnsafeUnpin)]
-struct TrivialBounds {
-    #[pin]
-    field1: PhantomPinned,
-}
-
-#[pin_project(UnsafeUnpin)]
-struct OverlappingLifetimeNames<'pin, T, U> {
-    #[pin]
-    field1: U,
-    #[pin]
-    field2: Option<T>,
-    field3: &'pin (),
-}
-
-unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for OverlappingLifetimeNames<'_, T, U> {}
-
-fn main() {
-    is_unpin::<Blah<PhantomPinned, ()>>(); //~ ERROR E0277
-    is_unpin::<Blah<(), PhantomPinned>>(); // Ok
-    is_unpin::<Blah<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-
-    is_unpin::<TrivialBounds>(); //~ ERROR E0277
-
-    is_unpin::<OverlappingLifetimeNames<'_, PhantomPinned, ()>>(); //~ ERROR E0277
-    is_unpin::<OverlappingLifetimeNames<'_, (), PhantomPinned>>(); //~ ERROR E0277
-}
diff --git a/tests/ui/unsafe_unpin/proper_unpin.stderr b/tests/ui/unsafe_unpin/proper_unpin.stderr
deleted file mode 100644
index 410dd0e..0000000
--- a/tests/ui/unsafe_unpin/proper_unpin.stderr
+++ /dev/null
@@ -1,63 +0,0 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/proper_unpin.rs:33:5
-   |
-4  | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-33 |     is_unpin::<Blah<PhantomPinned, ()>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `Blah<std::marker::PhantomPinned, ()>`
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, Blah<std::marker::PhantomPinned, ()>>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Blah<std::marker::PhantomPinned, ()>`
-
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/proper_unpin.rs:35:5
-   |
-4  | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-35 |     is_unpin::<Blah<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `Blah<std::marker::PhantomPinned, std::marker::PhantomPinned>`
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, Blah<std::marker::PhantomPinned, std::marker::PhantomPinned>>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `Blah<std::marker::PhantomPinned, std::marker::PhantomPinned>`
-
-error[E0277]: the trait bound `TrivialBounds: pin_project::UnsafeUnpin` is not satisfied
-  --> $DIR/proper_unpin.rs:37:16
-   |
-4  | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-37 |     is_unpin::<TrivialBounds>(); //~ ERROR E0277
-   |                ^^^^^^^^^^^^^ the trait `pin_project::UnsafeUnpin` is not implemented for `TrivialBounds`
-   |
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, TrivialBounds>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
-
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/proper_unpin.rs:39:5
-   |
-4  | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-39 |     is_unpin::<OverlappingLifetimeNames<'_, PhantomPinned, ()>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `OverlappingLifetimeNames<'_, std::marker::PhantomPinned, ()>`
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, OverlappingLifetimeNames<'_, std::marker::PhantomPinned, ()>>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `OverlappingLifetimeNames<'_, std::marker::PhantomPinned, ()>`
-
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/proper_unpin.rs:40:5
-   |
-4  | fn is_unpin<T: Unpin>() {}
-   |                ----- required by this bound in `is_unpin`
-...
-40 |     is_unpin::<OverlappingLifetimeNames<'_, (), PhantomPinned>>(); //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
-   |
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `OverlappingLifetimeNames<'_, (), std::marker::PhantomPinned>`
-   = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, OverlappingLifetimeNames<'_, (), std::marker::PhantomPinned>>`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `OverlappingLifetimeNames<'_, (), std::marker::PhantomPinned>`
diff --git a/tests/ui/unstable-features/README.md b/tests/ui/unstable-features/README.md
index b9215b6..96f370c 100644
--- a/tests/ui/unstable-features/README.md
+++ b/tests/ui/unstable-features/README.md
@@ -1,5 +1,7 @@
 # UI tests for unstable features
 
-These tests check how the guarantees and features provided by pin-project interact with unstable language features.
+These tests check how the guarantees and features provided by pin-project
+interact with unstable language features.
 
-The names of the files contained in this directory need to begin with the name of the feature.
+The names of the files contained in this directory need to begin with the name
+of the feature.
diff --git a/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs b/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs
index fa4b01e..8860f4f 100644
--- a/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs
+++ b/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs
@@ -6,7 +6,7 @@
 #[pin_project] //~ ERROR E0119
 struct Struct<T> {
     #[pin]
-    x: T,
+    f: T,
 }
 
 // unsound Unpin impl
diff --git a/tests/ui/unstable-features/marker_trait_attr.rs b/tests/ui/unstable-features/marker_trait_attr.rs
index 0b8b30a..a6ca357 100644
--- a/tests/ui/unstable-features/marker_trait_attr.rs
+++ b/tests/ui/unstable-features/marker_trait_attr.rs
@@ -12,7 +12,7 @@
 #[pin_project] //~ ERROR E0119
 struct Struct<T> {
     #[pin]
-    x: T,
+    f: T,
 }
 
 // unsound Unpin impl
diff --git a/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs b/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs
index 0bd4a32..3af3cf0 100644
--- a/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs
+++ b/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs
@@ -6,7 +6,7 @@
 #[pin_project] //~ ERROR E0119
 struct Struct<T> {
     #[pin]
-    x: T,
+    f: T,
 }
 
 // unsound Unpin impl
diff --git a/tests/ui/unstable-features/overlapping_marker_traits.rs b/tests/ui/unstable-features/overlapping_marker_traits.rs
index 27d37a3..c897d1c 100644
--- a/tests/ui/unstable-features/overlapping_marker_traits.rs
+++ b/tests/ui/unstable-features/overlapping_marker_traits.rs
@@ -16,7 +16,7 @@
 #[pin_project]
 struct Struct<T> {
     #[pin]
-    x: T,
+    f: T,
 }
 
 // unsound Unpin impl
diff --git a/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs b/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs
deleted file mode 100644
index 2b6377a..0000000
--- a/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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)]
-// stmt_expr_attributes
-// Tracking issue: https://github.com/rust-lang/rust/issues/15701
-#![feature(stmt_expr_attributes)]
-
-use pin_project::{pin_project, project};
-use std::pin::Pin;
-
-fn project_stmt_expr_nightly() {
-    #[pin_project]
-    enum Baz<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
-            #[pin]
-            field1: C,
-            field2: D,
-        },
-        None,
-    }
-
-    let mut baz = Baz::Variant1(1, 2);
-
-    let mut baz = Pin::new(&mut baz).project();
-
-    #[project]
-    match &mut baz {
-        Baz::Variant1(x, y) => {
-            let x: &mut Pin<&mut i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &mut &mut i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Baz::Variant2 { field1, field2 } => {
-            let _x: &mut Pin<&mut i32> = field1;
-            let _y: &mut &mut i32 = field2;
-        }
-        Baz::None => {}
-    }
-
-    let () = #[project]
-    match &mut baz {
-        Baz::Variant1(x, y) => {
-            let x: &mut Pin<&mut i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &mut &mut i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Baz::Variant2 { field1, field2 } => {
-            let _x: &mut Pin<&mut i32> = field1;
-            let _y: &mut &mut i32 = field2;
-        }
-        Baz::None => {}
-    };
-}
-
-fn main() {}
diff --git a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs b/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs
deleted file mode 100644
index 5dbe523..0000000
--- a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-// 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;
-
-fn project_stmt_expr_nightly() {
-    #[pin_project]
-    enum Enum<A, B, C, D> {
-        Variant1(#[pin] A, B),
-        Variant2 {
-            #[pin]
-            field1: C,
-            field2: D,
-        },
-        None,
-    }
-
-    let mut baz = Enum::Variant1(1, 2);
-
-    let mut baz = Pin::new(&mut baz).project();
-
-    #[project] //~ ERROR E0658
-    match &mut baz {
-        Enum::Variant1(x, y) => {
-            let x: &mut Pin<&mut i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &mut &mut i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Enum::Variant2 { field1, field2 } => {
-            let _x: &mut Pin<&mut i32> = field1;
-            let _y: &mut &mut i32 = field2;
-        }
-        Enum::None => {}
-    }
-
-    let () = #[project] //~ ERROR E0658
-    match &mut baz {
-        Enum::Variant1(x, y) => {
-            let x: &mut Pin<&mut i32> = x;
-            assert_eq!(**x, 1);
-
-            let y: &mut &mut i32 = y;
-            assert_eq!(**y, 2);
-        }
-        Enum::Variant2 { field1, field2 } => {
-            let _x: &mut Pin<&mut i32> = field1;
-            let _y: &mut &mut i32 = field2;
-        }
-        Enum::None => {}
-    };
-}
-
-fn main() {}
diff --git a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr b/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr
deleted file mode 100644
index 3c0501a..0000000
--- a/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr
+++ /dev/null
@@ -1,35 +0,0 @@
-error[E0658]: attributes on expressions are experimental
-  --> $DIR/stmt_expr_attributes-feature-gate.rs:24:5
-   |
-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:40:14
-   |
-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:24:5
-   |
-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:40:14
-   |
-40 |     let () = #[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
diff --git a/tests/ui/unstable-features/trivial_bounds-bug.stderr b/tests/ui/unstable-features/trivial_bounds-bug.stderr
index 8370c45..fff09f9 100644
--- a/tests/ui/unstable-features/trivial_bounds-bug.stderr
+++ b/tests/ui/unstable-features/trivial_bounds-bug.stderr
@@ -1,5 +1,5 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
    --> $DIR/trivial_bounds-bug.rs:13:43
     |
 13  |     impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
-    |                                           ^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+    |                                           ^^^^^ the trait `Unpin` is not implemented for `PhantomPinned`
diff --git a/tests/ui/unstable-features/trivial_bounds-feature-gate.rs b/tests/ui/unstable-features/trivial_bounds-feature-gate.rs
index 0453a3f..ccdb182 100644
--- a/tests/ui/unstable-features/trivial_bounds-feature-gate.rs
+++ b/tests/ui/unstable-features/trivial_bounds-feature-gate.rs
@@ -21,8 +21,7 @@
 
     struct C(PhantomPinned);
 
-    impl<'a> Unpin for C where WrapperWithLifetime<'a, PhantomPinned>: Unpin {}
-    // Ok
+    impl<'a> Unpin for C where WrapperWithLifetime<'a, PhantomPinned>: Unpin {} // Ok
 }
 
 mod inner {
diff --git a/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr b/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr
index 70450dc..dd151b0 100644
--- a/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr
+++ b/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr
@@ -1,45 +1,45 @@
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
  --> $DIR/trivial_bounds-feature-gate.rs:8:5
   |
 8 |     impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
-  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `PhantomPinned`
   |
   = help: see issue #48214
   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
    --> $DIR/trivial_bounds-feature-gate.rs:8:43
     |
 8   |     impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
-    |                                           ^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+    |                                           ^^^^^ the trait `Unpin` is not implemented for `PhantomPinned`
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+error[E0277]: `PhantomPinned` cannot be unpinned
   --> $DIR/trivial_bounds-feature-gate.rs:16:5
    |
 16 |     impl Unpin for B where Wrapper<PhantomPinned>: Unpin {} //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `PhantomPinned`
    |
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `phantom_pinned::Wrapper<std::marker::PhantomPinned>`
+   = note: required because of the requirements on the impl of `Unpin` for `phantom_pinned::Wrapper<PhantomPinned>`
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/trivial_bounds-feature-gate.rs:35:5
+error[E0277]: `PhantomPinned` cannot be unpinned
+  --> $DIR/trivial_bounds-feature-gate.rs:34:5
    |
-35 |     impl Unpin for A where Inner: Unpin {} //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `inner::Inner`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+34 |     impl Unpin for A where Inner: Unpin {} //~ ERROR E0277
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Inner`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
-   = note: required because it appears within the type `inner::Inner`
+   = note: required because it appears within the type `Inner`
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
 
-error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
-  --> $DIR/trivial_bounds-feature-gate.rs:43:5
+error[E0277]: `PhantomPinned` cannot be unpinned
+  --> $DIR/trivial_bounds-feature-gate.rs:42:5
    |
-43 |     impl Unpin for B where Wrapper<Inner>: Unpin {} //~ ERROR E0277
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `inner::Inner`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+42 |     impl Unpin for B where Wrapper<Inner>: Unpin {} //~ ERROR E0277
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Inner`, the trait `Unpin` is not implemented for `PhantomPinned`
    |
-   = note: required because it appears within the type `inner::Inner`
-   = note: required because of the requirements on the impl of `std::marker::Unpin` for `inner::Wrapper<inner::Inner>`
+   = note: required because it appears within the type `Inner`
+   = note: required because of the requirements on the impl of `Unpin` for `inner::Wrapper<Inner>`
    = help: see issue #48214
    = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
diff --git a/tests/ui/unstable-features/trivial_bounds.stderr b/tests/ui/unstable-features/trivial_bounds.stderr
index 03d0161..6a3bb94 100644
--- a/tests/ui/unstable-features/trivial_bounds.stderr
+++ b/tests/ui/unstable-features/trivial_bounds.stderr
@@ -1,4 +1,4 @@
-error: Trait bound inner::Inner: std::marker::Unpin does not depend on any type or lifetime parameters
+error: Trait bound Inner: Unpin does not depend on any type or lifetime parameters
   --> $DIR/trivial_bounds.rs:15:35
    |
 15 |     impl Unpin for A where Inner: Unpin {} //~ ERROR std::marker::Unpin does not depend on any type or lifetime parameters
@@ -10,7 +10,7 @@
 6  | #![deny(trivial_bounds)]
    |         ^^^^^^^^^^^^^^
 
-error: Trait bound inner::Wrapper<inner::Inner>: std::marker::Unpin does not depend on any type or lifetime parameters
+error: Trait bound Wrapper<Inner>: Unpin does not depend on any type or lifetime parameters
   --> $DIR/trivial_bounds.rs:23:44
    |
 23 |     impl Unpin for B where Wrapper<Inner>: Unpin {} //~ ERROR std::marker::Unpin does not depend on any type or lifetime parameters
diff --git a/tests/unsafe_unpin.rs b/tests/unsafe_unpin.rs
index 5e0e7cf..1bd6c0b 100644
--- a/tests/unsafe_unpin.rs
+++ b/tests/unsafe_unpin.rs
@@ -1,53 +1,49 @@
 #![warn(rust_2018_idioms, single_use_lifetimes)]
 #![allow(dead_code)]
 
-use pin_project::{pin_project, UnsafeUnpin};
-use std::{marker::PhantomPinned, pin::Pin};
+#[macro_use]
+mod auxiliary;
 
-fn is_unpin<T: Unpin>() {}
+use pin_project::{pin_project, UnsafeUnpin};
+use std::marker::PhantomPinned;
 
 #[pin_project(UnsafeUnpin)]
 pub struct Blah<T, U> {
-    field1: U,
+    f1: U,
     #[pin]
-    field2: T,
+    f2: T,
 }
 
 unsafe impl<T: Unpin, U> UnsafeUnpin for Blah<T, U> {}
 
+assert_unpin!(Blah<(), ()>);
+assert_unpin!(Blah<(), PhantomPinned>);
+assert_not_unpin!(Blah<PhantomPinned, ()>);
+assert_not_unpin!(Blah<PhantomPinned, PhantomPinned>);
+
 #[pin_project(UnsafeUnpin)]
-pub struct OverlappingLifetimeNames<'pin, T, U> {
+struct OverlappingLifetimeNames<'pin, T, U> {
     #[pin]
-    field1: T,
-    field2: U,
-    field3: &'pin (),
+    f1: U,
+    #[pin]
+    f2: Option<T>,
+    f3: &'pin (),
 }
 
-unsafe impl<T: Unpin, U> UnsafeUnpin for OverlappingLifetimeNames<'_, T, U> {}
+unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for OverlappingLifetimeNames<'_, T, U> {}
 
-#[test]
-fn unsafe_unpin() {
-    is_unpin::<Blah<(), PhantomPinned>>();
-    is_unpin::<OverlappingLifetimeNames<'_, (), ()>>();
-}
+assert_unpin!(OverlappingLifetimeNames<'_, (), ()>);
+assert_not_unpin!(OverlappingLifetimeNames<'_, PhantomPinned, ()>);
+assert_not_unpin!(OverlappingLifetimeNames<'_, (), PhantomPinned>);
+assert_not_unpin!(OverlappingLifetimeNames<'_, PhantomPinned, PhantomPinned>);
 
 #[test]
 fn trivial_bounds() {
     #[pin_project(UnsafeUnpin)]
     pub struct NotImplementUnsafUnpin {
         #[pin]
-        field: PhantomPinned,
+        f: PhantomPinned,
     }
-}
 
-#[test]
-fn test() {
-    let mut x = OverlappingLifetimeNames { field1: 0, field2: 1, field3: &() };
-    let x = Pin::new(&mut x);
-    let y = x.as_ref().project_ref();
-    let _: Pin<&u8> = y.field1;
-    let _: &u8 = y.field2;
-    let y = x.project();
-    let _: Pin<&mut u8> = y.field1;
-    let _: &mut u8 = y.field2;
+    assert_not_unpin!(NotImplementUnsafUnpin);
 }