Import pin-project-lite 0.2.9 upstream upstream/0.2.9
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 6 Mar 2023 02:33:25 +0000 (11:33 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 6 Mar 2023 02:33:25 +0000 (11:33 +0900)
71 files changed:
.cargo_vcs_info.json [new file with mode: 0644]
CHANGELOG.md [new file with mode: 0644]
Cargo.toml [new file with mode: 0644]
Cargo.toml.orig [new file with mode: 0644]
LICENSE-APACHE [new file with mode: 0644]
LICENSE-MIT [new file with mode: 0644]
README.md [new file with mode: 0644]
src/lib.rs [new file with mode: 0644]
tests/README.md [new file with mode: 0644]
tests/auxiliary/mod.rs [new file with mode: 0644]
tests/compiletest.rs [new file with mode: 0644]
tests/drop_order.rs [new file with mode: 0644]
tests/expand/default/enum.expanded.rs [new file with mode: 0644]
tests/expand/default/enum.rs [new file with mode: 0644]
tests/expand/default/struct.expanded.rs [new file with mode: 0644]
tests/expand/default/struct.rs [new file with mode: 0644]
tests/expand/multifields/enum.expanded.rs [new file with mode: 0644]
tests/expand/multifields/enum.rs [new file with mode: 0644]
tests/expand/multifields/struct.expanded.rs [new file with mode: 0644]
tests/expand/multifields/struct.rs [new file with mode: 0644]
tests/expand/naming/enum-all.expanded.rs [new file with mode: 0644]
tests/expand/naming/enum-all.rs [new file with mode: 0644]
tests/expand/naming/enum-mut.expanded.rs [new file with mode: 0644]
tests/expand/naming/enum-mut.rs [new file with mode: 0644]
tests/expand/naming/enum-none.expanded.rs [new file with mode: 0644]
tests/expand/naming/enum-none.rs [new file with mode: 0644]
tests/expand/naming/enum-ref.expanded.rs [new file with mode: 0644]
tests/expand/naming/enum-ref.rs [new file with mode: 0644]
tests/expand/naming/struct-all.expanded.rs [new file with mode: 0644]
tests/expand/naming/struct-all.rs [new file with mode: 0644]
tests/expand/naming/struct-mut.expanded.rs [new file with mode: 0644]
tests/expand/naming/struct-mut.rs [new file with mode: 0644]
tests/expand/naming/struct-none.expanded.rs [new file with mode: 0644]
tests/expand/naming/struct-none.rs [new file with mode: 0644]
tests/expand/naming/struct-ref.expanded.rs [new file with mode: 0644]
tests/expand/naming/struct-ref.rs [new file with mode: 0644]
tests/expand/pinned_drop/enum.expanded.rs [new file with mode: 0644]
tests/expand/pinned_drop/enum.rs [new file with mode: 0644]
tests/expand/pinned_drop/struct.expanded.rs [new file with mode: 0644]
tests/expand/pinned_drop/struct.rs [new file with mode: 0644]
tests/expand/pub/enum.expanded.rs [new file with mode: 0644]
tests/expand/pub/enum.rs [new file with mode: 0644]
tests/expand/pub/struct.expanded.rs [new file with mode: 0644]
tests/expand/pub/struct.rs [new file with mode: 0644]
tests/expandtest.rs [new file with mode: 0644]
tests/include/basic.rs [new file with mode: 0644]
tests/lint.rs [new file with mode: 0644]
tests/proper_unpin.rs [new file with mode: 0644]
tests/test.rs [new file with mode: 0644]
tests/ui/pin_project/conflict-drop.rs [new file with mode: 0644]
tests/ui/pin_project/conflict-drop.stderr [new file with mode: 0644]
tests/ui/pin_project/conflict-unpin.rs [new file with mode: 0644]
tests/ui/pin_project/conflict-unpin.stderr [new file with mode: 0644]
tests/ui/pin_project/invalid-bounds.rs [new file with mode: 0644]
tests/ui/pin_project/invalid-bounds.stderr [new file with mode: 0644]
tests/ui/pin_project/invalid.rs [new file with mode: 0644]
tests/ui/pin_project/invalid.stderr [new file with mode: 0644]
tests/ui/pin_project/overlapping_lifetime_names.rs [new file with mode: 0644]
tests/ui/pin_project/overlapping_lifetime_names.stderr [new file with mode: 0644]
tests/ui/pin_project/overlapping_unpin_struct.rs [new file with mode: 0644]
tests/ui/pin_project/overlapping_unpin_struct.stderr [new file with mode: 0644]
tests/ui/pin_project/packed.rs [new file with mode: 0644]
tests/ui/pin_project/packed.stderr [new file with mode: 0644]
tests/ui/pin_project/unpin_sneaky.rs [new file with mode: 0644]
tests/ui/pin_project/unpin_sneaky.stderr [new file with mode: 0644]
tests/ui/pin_project/unsupported.rs [new file with mode: 0644]
tests/ui/pin_project/unsupported.stderr [new file with mode: 0644]
tests/ui/pinned_drop/call-drop-inner.rs [new file with mode: 0644]
tests/ui/pinned_drop/call-drop-inner.stderr [new file with mode: 0644]
tests/ui/pinned_drop/conditional-drop-impl.rs [new file with mode: 0644]
tests/ui/pinned_drop/conditional-drop-impl.stderr [new file with mode: 0644]

diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644 (file)
index 0000000..b377c22
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "git": {
+    "sha1": "1ccf058c2ba13fd7eee2154951ac64a84590d886"
+  },
+  "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644 (file)
index 0000000..127e467
--- /dev/null
@@ -0,0 +1,222 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+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]
+
+## [0.2.9] - 2022-04-26
+
+- Improve compile time of `pin_project!` calls. (#71, thanks @nnethercote)
+
+## [0.2.8] - 2021-12-31
+
+- Fix handling of trailing commas in `PinnedDrop` impl. ([#64](https://github.com/taiki-e/pin-project-lite/pull/64), thanks @Michael-J-Ward)
+
+## [0.2.7] - 2021-06-26
+
+- [Support custom Drop implementation.](https://github.com/taiki-e/pin-project-lite/pull/25) See [#25](https://github.com/taiki-e/pin-project-lite/pull/25) for details.
+
+## [0.2.6] - 2021-03-04
+
+- Support item attributes in any order. ([#57](https://github.com/taiki-e/pin-project-lite/pull/57), thanks @SabrinaJewson)
+
+## [0.2.5] - 2021-03-02
+
+- [Prepare for removal of `safe_packed_borrows` lint.](https://github.com/taiki-e/pin-project-lite/pull/55) See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+## [0.2.4] - 2021-01-11
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- Add `project_replace`. ([#43](https://github.com/taiki-e/pin-project-lite/pull/43), thanks @Marwes)
+
+## [0.2.3] - 2021-01-09
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Suppress `clippy::unknown_clippy_lints` lint in generated code.](https://github.com/taiki-e/pin-project-lite/pull/47)
+
+## [0.2.2] - 2021-01-09
+
+**Note:** This release has been yanked.** See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Suppress `clippy::ref_option_ref` lint in generated code.](https://github.com/taiki-e/pin-project-lite/pull/45)
+
+## [0.2.1] - 2021-01-05
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- Exclude unneeded files from crates.io.
+
+## [0.2.0] - 2020-11-13
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [`pin_project!` macro now supports enums.](https://github.com/taiki-e/pin-project-lite/pull/28)
+
+  To use `pin_project!` on enums, you need to name the projection type returned from the method.
+
+  ```rust
+  use pin_project_lite::pin_project;
+  use std::pin::Pin;
+
+  pin_project! {
+      #[project = EnumProj]
+      enum Enum<T, U> {
+          Variant { #[pin] pinned: T, unpinned: U },
+      }
+  }
+
+  impl<T, U> Enum<T, U> {
+      fn method(self: Pin<&mut Self>) {
+          match self.project() {
+              EnumProj::Variant { pinned, unpinned } => {
+                  let _: Pin<&mut T> = pinned;
+                  let _: &mut U = unpinned;
+              }
+          }
+      }
+  }
+  ```
+
+- [Support naming the projection types.](https://github.com/taiki-e/pin-project-lite/pull/28)
+
+  By passing an attribute with the same name as the method, you can name the projection type returned from the method:
+
+  ```rust
+  use pin_project_lite::pin_project;
+  use std::pin::Pin;
+
+  pin_project! {
+      #[project = StructProj]
+      struct Struct<T> {
+          #[pin]
+          field: T,
+      }
+  }
+
+  fn func<T>(x: Pin<&mut Struct<T>>) {
+      let StructProj { field } = x.project();
+      let _: Pin<&mut T> = field;
+  }
+  ```
+
+## [0.1.12] - 2021-03-02
+
+- [Prepare for removal of `safe_packed_borrows` lint.](https://github.com/taiki-e/pin-project-lite/pull/55) See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+## [0.1.11] - 2020-10-20
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- Suppress `clippy::redundant_pub_crate` lint in generated code.
+
+- Documentation improvements.
+
+## [0.1.10] - 2020-10-01
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- Suppress `drop_bounds` lint, which will be added to rustc in the future. See [taiki-e/pin-project#272](https://github.com/taiki-e/pin-project/issues/272) for more details.
+
+## [0.1.9] - 2020-09-29
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Fix trailing comma support in generics.](https://github.com/taiki-e/pin-project-lite/pull/32)
+
+## [0.1.8] - 2020-09-26
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Fix compatibility of generated code with `forbid(future_incompatible)`.](https://github.com/taiki-e/pin-project-lite/pull/30)
+
+  Note: This does not guarantee compatibility with `forbid(future_incompatible)` in the future.
+  If rustc adds a new lint, we may not be able to keep this.
+
+## [0.1.7] - 2020-06-04
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Support `?Sized` bounds in where clauses.](https://github.com/taiki-e/pin-project-lite/pull/22)
+
+- [Fix lifetime inference error when an associated type is used in fields.](https://github.com/taiki-e/pin-project-lite/pull/20)
+
+- Suppress `clippy::used_underscore_binding` lint in generated code.
+
+- Documentation improvements.
+
+## [0.1.6] - 2020-05-31
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Support lifetime bounds in where clauses.](https://github.com/taiki-e/pin-project-lite/pull/18)
+
+- Documentation improvements.
+
+## [0.1.5] - 2020-05-07
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Support overwriting the name of `core` crate.](https://github.com/taiki-e/pin-project-lite/pull/14)
+
+## [0.1.4] - 2020-01-20
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Support ?Sized bounds in generic parameters.](https://github.com/taiki-e/pin-project-lite/pull/9)
+
+## [0.1.3] - 2020-01-20
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [Support lifetime bounds in generic parameters.](https://github.com/taiki-e/pin-project-lite/pull/7)
+
+## [0.1.2] - 2020-01-05
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- Support recognizing default generic parameters. ([#6](https://github.com/taiki-e/pin-project-lite/pull/6), thanks @kennytm)
+
+## [0.1.1] - 2019-11-15
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+- [`pin_project!` macro now determines the visibility of the projection type/method is based on the original type.](https://github.com/taiki-e/pin-project-lite/pull/5)
+
+## [0.1.0] - 2019-10-22
+
+**Note:** This release has been yanked. See [#55](https://github.com/taiki-e/pin-project-lite/pull/55) for details.
+
+Initial release
+
+[Unreleased]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.9...HEAD
+[0.2.9]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.8...v0.2.9
+[0.2.8]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.7...v0.2.8
+[0.2.7]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.6...v0.2.7
+[0.2.6]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.5...v0.2.6
+[0.2.5]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.4...v0.2.5
+[0.2.4]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.3...v0.2.4
+[0.2.3]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.2...v0.2.3
+[0.2.2]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.1...v0.2.2
+[0.2.1]: https://github.com/taiki-e/pin-project-lite/compare/v0.2.0...v0.2.1
+[0.2.0]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.11...v0.2.0
+[0.1.12]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.11...v0.1.12
+[0.1.11]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.10...v0.1.11
+[0.1.10]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.9...v0.1.10
+[0.1.9]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.8...v0.1.9
+[0.1.8]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.7...v0.1.8
+[0.1.7]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.6...v0.1.7
+[0.1.6]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.5...v0.1.6
+[0.1.5]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.4...v0.1.5
+[0.1.4]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.3...v0.1.4
+[0.1.3]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.2...v0.1.3
+[0.1.2]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.1...v0.1.2
+[0.1.1]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.0...v0.1.1
+[0.1.0]: https://github.com/taiki-e/pin-project-lite/releases/tag/v0.1.0
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644 (file)
index 0000000..8a9436d
--- /dev/null
@@ -0,0 +1,45 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.37"
+name = "pin-project-lite"
+version = "0.2.9"
+exclude = [
+    "/.*",
+    "/tools",
+]
+description = """
+A lightweight version of pin-project written with declarative macros.
+"""
+keywords = [
+    "pin",
+    "macros",
+]
+categories = [
+    "no-std",
+    "rust-patterns",
+]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/taiki-e/pin-project-lite"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dev-dependencies.rustversion]
+version = "1"
+
+[dev-dependencies.static_assertions]
+version = "1"
+
+[dev-dependencies.trybuild]
+version = "1.0.49"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644 (file)
index 0000000..3528633
--- /dev/null
@@ -0,0 +1,29 @@
+[package]
+name = "pin-project-lite"
+version = "0.2.9"
+edition = "2018"
+rust-version = "1.37"
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/taiki-e/pin-project-lite"
+keywords = ["pin", "macros"]
+categories = ["no-std", "rust-patterns"]
+exclude = ["/.*", "/tools"]
+description = """
+A lightweight version of pin-project written with declarative macros.
+"""
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[workspace]
+members = [
+    "tests/doc",
+    "tests/no-core",
+    "tests/no-std",
+]
+
+[dev-dependencies]
+macrotest = { git = "https://github.com/taiki-e/macrotest.git", rev = "779cfa5" } # https://github.com/eupn/macrotest/pull/69
+rustversion = "1"
+static_assertions = "1"
+trybuild = "1.0.49"
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644 (file)
index 0000000..f433b1a
--- /dev/null
@@ -0,0 +1,177 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644 (file)
index 0000000..31aa793
--- /dev/null
@@ -0,0 +1,23 @@
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..78adb7e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,125 @@
+# pin-project-lite
+
+[![crates.io](https://img.shields.io/crates/v/pin-project-lite?style=flat-square&logo=rust)](https://crates.io/crates/pin-project-lite)
+[![docs.rs](https://img.shields.io/badge/docs.rs-pin--project--lite-blue?style=flat-square)](https://docs.rs/pin-project-lite)
+[![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license)
+[![rustc](https://img.shields.io/badge/rustc-1.37+-blue?style=flat-square&logo=rust)](https://www.rust-lang.org)
+[![build status](https://img.shields.io/github/workflow/status/taiki-e/pin-project-lite/CI/main?style=flat-square&logo=github)](https://github.com/taiki-e/pin-project-lite/actions)
+
+A lightweight version of [pin-project] written with declarative macros.
+
+## Usage
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+pin-project-lite = "0.2"
+```
+
+*Compiler support: requires rustc 1.37+*
+
+## Examples
+
+[`pin_project!`] macro creates a projection type covering all the fields of
+struct.
+
+```rust
+use std::pin::Pin;
+
+use pin_project_lite::pin_project;
+
+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
+    }
+}
+```
+
+To use [`pin_project!`] on enums, you need to name the projection type
+returned from the method.
+
+```rust
+use std::pin::Pin;
+
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project = EnumProj]
+    enum Enum<T, U> {
+        Variant { #[pin] pinned: T, unpinned: U },
+    }
+}
+
+impl<T, U> Enum<T, U> {
+    fn method(self: Pin<&mut Self>) {
+        match self.project() {
+            EnumProj::Variant { pinned, unpinned } => {
+                let _: Pin<&mut T> = pinned;
+                let _: &mut U = unpinned;
+            }
+        }
+    }
+}
+```
+
+## [pin-project] vs pin-project-lite
+
+Here are some similarities and differences compared to [pin-project].
+
+### Similar: Safety
+
+pin-project-lite guarantees safety in much the same way as [pin-project].
+Both are completely safe unless you write other unsafe code.
+
+### Different: Minimal design
+
+This library does not tackle as expansive of a range of use cases as
+[pin-project] does. If your use case is not already covered, please use
+[pin-project].
+
+### Different: No proc-macro related dependencies
+
+This is the **only** reason to use this crate. However, **if you already
+have proc-macro related dependencies in your crate's dependency graph, there
+is no benefit from using this crate.** (Note: There is almost no difference
+in the amount of code generated between [pin-project] and pin-project-lite.)
+
+### Different: No useful error messages
+
+This macro does not handle any invalid input. So error messages are not to
+be useful in most cases. If you do need useful error messages, then upon
+error you can pass the same input to [pin-project] to receive a helpful
+description of the compile error.
+
+### Different: No support for custom Unpin implementation
+
+pin-project supports this by [`UnsafeUnpin`][unsafe-unpin] and [`!Unpin`][not-unpin].
+
+### Different: No support for tuple structs and tuple variants
+
+pin-project supports this.
+
+[`pin_project!`]: https://docs.rs/pin-project-lite/0.2/pin_project_lite/macro.pin_project.html
+[not-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin
+[pin-project]: https://github.com/taiki-e/pin-project
+[unsafe-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unsafeunpin
+
+## License
+
+Licensed under either of [Apache License, Version 2.0](LICENSE-APACHE) or
+[MIT license](LICENSE-MIT) at your option.
+
+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/src/lib.rs b/src/lib.rs
new file mode 100644 (file)
index 0000000..f5ecc99
--- /dev/null
@@ -0,0 +1,1559 @@
+//! A lightweight version of [pin-project] written with declarative macros.
+//!
+//! # Examples
+//!
+//! [`pin_project!`] macro creates a projection type covering all the fields of struct.
+//!
+//! ```rust
+//! use std::pin::Pin;
+//!
+//! use pin_project_lite::pin_project;
+//!
+//! 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
+//!     }
+//! }
+//! ```
+//!
+//! To use [`pin_project!`] on enums, you need to name the projection type
+//! returned from the method.
+//!
+//! ```rust
+//! use std::pin::Pin;
+//!
+//! use pin_project_lite::pin_project;
+//!
+//! pin_project! {
+//!     #[project = EnumProj]
+//!     enum Enum<T, U> {
+//!         Variant { #[pin] pinned: T, unpinned: U },
+//!     }
+//! }
+//!
+//! impl<T, U> Enum<T, U> {
+//!     fn method(self: Pin<&mut Self>) {
+//!         match self.project() {
+//!             EnumProj::Variant { pinned, unpinned } => {
+//!                 let _: Pin<&mut T> = pinned;
+//!                 let _: &mut U = unpinned;
+//!             }
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! # [pin-project] vs pin-project-lite
+//!
+//! Here are some similarities and differences compared to [pin-project].
+//!
+//! ## Similar: Safety
+//!
+//! pin-project-lite guarantees safety in much the same way as [pin-project].
+//! Both are completely safe unless you write other unsafe code.
+//!
+//! ## Different: Minimal design
+//!
+//! This library does not tackle as expansive of a range of use cases as
+//! [pin-project] does. If your use case is not already covered, please use
+//! [pin-project].
+//!
+//! ## Different: No proc-macro related dependencies
+//!
+//! This is the **only** reason to use this crate. However, **if you already
+//! have proc-macro related dependencies in your crate's dependency graph, there
+//! is no benefit from using this crate.** (Note: There is almost no difference
+//! in the amount of code generated between [pin-project] and pin-project-lite.)
+//!
+//! ## Different: No useful error messages
+//!
+//! This macro does not handle any invalid input. So error messages are not to
+//! be useful in most cases. If you do need useful error messages, then upon
+//! error you can pass the same input to [pin-project] to receive a helpful
+//! description of the compile error.
+//!
+//! ## Different: No support for custom Unpin implementation
+//!
+//! pin-project supports this by [`UnsafeUnpin`][unsafe-unpin] and [`!Unpin`][not-unpin].
+//!
+//! ## Different: No support for tuple structs and tuple variants
+//!
+//! pin-project supports this.
+//!
+//! [not-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin
+//! [pin-project]: https://github.com/taiki-e/pin-project
+//! [unsafe-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unsafeunpin
+
+#![no_std]
+#![doc(test(
+    no_crate_inject,
+    attr(
+        deny(warnings, rust_2018_idioms, single_use_lifetimes),
+        allow(dead_code, unused_variables)
+    )
+))]
+#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(clippy::default_trait_access, clippy::wildcard_imports)]
+
+/// A macro that creates a projection type covering all the fields of struct.
+///
+/// This macro creates a projection type according to the following rules:
+///
+/// - For the field that uses `#[pin]` attribute, makes the pinned reference to the field.
+/// - For the other fields, makes the unpinned reference to the field.
+///
+/// And the following methods are implemented on the original type:
+///
+/// ```rust
+/// # use std::pin::Pin;
+/// # type Projection<'a> = &'a ();
+/// # type ProjectionRef<'a> = &'a ();
+/// # trait Dox {
+/// fn project(self: Pin<&mut Self>) -> Projection<'_>;
+/// fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;
+/// # }
+/// ```
+///
+/// By passing an attribute with the same name as the method to the macro,
+/// you can name the projection type returned from the method. This allows you
+/// to use pattern matching on the projected types.
+///
+/// ```rust
+/// # use pin_project_lite::pin_project;
+/// # use std::pin::Pin;
+/// pin_project! {
+///     #[project = EnumProj]
+///     enum Enum<T> {
+///         Variant { #[pin] field: T },
+///     }
+/// }
+///
+/// impl<T> Enum<T> {
+///     fn method(self: Pin<&mut Self>) {
+///         let this: EnumProj<'_, T> = self.project();
+///         match this {
+///             EnumProj::Variant { field } => {
+///                 let _: Pin<&mut T> = field;
+///             }
+///         }
+///     }
+/// }
+/// ```
+///
+/// By passing the `#[project_replace = MyProjReplace]` attribute you may create an additional
+/// method which allows the contents of `Pin<&mut Self>` to be replaced while simultaneously moving
+/// out all unpinned fields in `Self`.
+///
+/// ```rust
+/// # use std::pin::Pin;
+/// # type MyProjReplace = ();
+/// # trait Dox {
+/// fn project_replace(self: Pin<&mut Self>, replacement: Self) -> MyProjReplace;
+/// # }
+/// ```
+///
+/// Also, note that the projection types returned by `project` and `project_ref` have
+/// an additional lifetime at the beginning of generics.
+///
+/// ```text
+/// let this: EnumProj<'_, T> = self.project();
+///                    ^^
+/// ```
+///
+/// The visibility of the projected types and projection methods is based on the
+/// original type. However, if the visibility of the original type is `pub`, the
+/// visibility of the projected types and the projection methods is downgraded
+/// to `pub(crate)`.
+///
+/// # Safety
+///
+/// `pin_project!` macro guarantees safety in much the same way as [pin-project] crate.
+/// Both are completely safe unless you write other unsafe code.
+///
+/// See [pin-project] crate for more details.
+///
+/// # Examples
+///
+/// ```rust
+/// use std::pin::Pin;
+///
+/// use pin_project_lite::pin_project;
+///
+/// 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
+///     }
+/// }
+/// ```
+///
+/// To use `pin_project!` on enums, you need to name the projection type
+/// returned from the method.
+///
+/// ```rust
+/// use std::pin::Pin;
+///
+/// use pin_project_lite::pin_project;
+///
+/// pin_project! {
+///     #[project = EnumProj]
+///     enum Enum<T> {
+///         Struct {
+///             #[pin]
+///             field: T,
+///         },
+///         Unit,
+///     }
+/// }
+///
+/// impl<T> Enum<T> {
+///     fn method(self: Pin<&mut Self>) {
+///         match self.project() {
+///             EnumProj::Struct { field } => {
+///                 let _: Pin<&mut T> = field;
+///             }
+///             EnumProj::Unit => {}
+///         }
+///     }
+/// }
+/// ```
+///
+/// If you want to call the `project()` method multiple times or later use the
+/// original [`Pin`] type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid
+/// consuming the [`Pin`].
+///
+/// ```rust
+/// use std::pin::Pin;
+///
+/// use pin_project_lite::pin_project;
+///
+/// pin_project! {
+///     struct Struct<T> {
+///         #[pin]
+///         field: T,
+///     }
+/// }
+///
+/// impl<T> Struct<T> {
+///     fn call_project_twice(mut self: Pin<&mut Self>) {
+///         // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
+///         self.as_mut().project();
+///         self.as_mut().project();
+///     }
+/// }
+/// ```
+///
+/// # `!Unpin`
+///
+/// If you want to ensure that [`Unpin`] is not implemented, use `#[pin]`
+/// attribute for a [`PhantomPinned`] field.
+///
+/// ```rust
+/// use std::marker::PhantomPinned;
+///
+/// use pin_project_lite::pin_project;
+///
+/// pin_project! {
+///     struct Struct<T> {
+///         field: T,
+///         #[pin] // <------ This `#[pin]` is required to make `Struct` to `!Unpin`.
+///         _pin: PhantomPinned,
+///     }
+/// }
+/// ```
+///
+/// Note that using [`PhantomPinned`] without `#[pin]` attribute has no effect.
+///
+/// [`PhantomPinned`]: core::marker::PhantomPinned
+/// [`Pin::as_mut`]: core::pin::Pin::as_mut
+/// [`Pin`]: core::pin::Pin
+/// [pin-project]: https://github.com/taiki-e/pin-project
+#[macro_export]
+macro_rules! pin_project {
+    ($($tt:tt)*) => {
+        $crate::__pin_project_internal! {
+            [][][][]
+            $($tt)*
+        }
+    };
+}
+
+// limitations:
+// - no support for tuple structs and tuple variant (wontfix).
+// - no support for multiple trait/lifetime bounds.
+// - no support for `Self` in where clauses. (wontfix)
+// - no support for overlapping lifetime names. (wontfix)
+// - no interoperability with other field attributes.
+// - no useful error messages. (wontfix)
+// etc...
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_expand {
+    (
+        [$($proj_mut_ident:ident)?]
+        [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
+        [$proj_vis:vis]
+        [$(#[$attrs:meta])* $vis:vis $struct_ty_ident:ident $ident:ident]
+        [$($def_generics:tt)*]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $($body_data:tt)*
+        }
+        $(impl $($pinned_drop:tt)*)?
+    ) => {
+        $crate::__pin_project_reconstruct! {
+            [$(#[$attrs])* $vis $struct_ty_ident $ident]
+            [$($def_generics)*] [$($impl_generics)*]
+            [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $($body_data)*
+            }
+        }
+
+        $crate::__pin_project_make_proj_ty! {
+            [$($proj_mut_ident)?]
+            [$proj_vis $struct_ty_ident $ident]
+            [__pin_project_make_proj_field_mut]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $($body_data)*
+            }
+        }
+        $crate::__pin_project_make_proj_ty! {
+            [$($proj_ref_ident)?]
+            [$proj_vis $struct_ty_ident $ident]
+            [__pin_project_make_proj_field_ref]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $($body_data)*
+            }
+        }
+        $crate::__pin_project_make_proj_replace_ty! {
+            [$($proj_replace_ident)?]
+            [$proj_vis $struct_ty_ident]
+            [__pin_project_make_proj_field_replace]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $($body_data)*
+            }
+        }
+
+        $crate::__pin_project_constant! {
+            [$(#[$attrs])* $vis $struct_ty_ident $ident]
+            [$($proj_mut_ident)?] [$($proj_ref_ident)?] [$($proj_replace_ident)?]
+            [$proj_vis]
+            [$($def_generics)*] [$($impl_generics)*]
+            [$($ty_generics)*] [$(where $($where_clause)*)?]
+            {
+                $($body_data)*
+            }
+            $(impl $($pinned_drop)*)?
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_constant {
+    (
+        [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
+        [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]
+        [$proj_vis:vis]
+        [$($def_generics:tt)*]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident: $field_ty:ty
+            ),+ $(,)?
+        }
+        $(impl $($pinned_drop:tt)*)?
+    ) => {
+        #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::used_underscore_binding)]
+        const _: () = {
+            $crate::__pin_project_make_proj_ty! {
+                [$($proj_mut_ident)? Projection]
+                [$proj_vis struct $ident]
+                [__pin_project_make_proj_field_mut]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                {
+                    $(
+                        $(#[$pin])?
+                        $field_vis $field: $field_ty
+                    ),+
+                }
+            }
+            $crate::__pin_project_make_proj_ty! {
+                [$($proj_ref_ident)? ProjectionRef]
+                [$proj_vis struct $ident]
+                [__pin_project_make_proj_field_ref]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                {
+                    $(
+                        $(#[$pin])?
+                        $field_vis $field: $field_ty
+                    ),+
+                }
+            }
+
+            impl <$($impl_generics)*> $ident <$($ty_generics)*>
+            $(where
+                $($where_clause)*)?
+            {
+                $crate::__pin_project_struct_make_proj_method! {
+                    [$($proj_mut_ident)? Projection]
+                    [$proj_vis]
+                    [project get_unchecked_mut mut]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field_vis $field
+                        ),+
+                    }
+                }
+                $crate::__pin_project_struct_make_proj_method! {
+                    [$($proj_ref_ident)? ProjectionRef]
+                    [$proj_vis]
+                    [project_ref get_ref]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field_vis $field
+                        ),+
+                    }
+                }
+                $crate::__pin_project_struct_make_proj_replace_method! {
+                    [$($proj_replace_ident)?]
+                    [$proj_vis]
+                    [ProjectionReplace]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field_vis $field
+                        ),+
+                    }
+                }
+            }
+
+            $crate::__pin_project_make_unpin_impl! {
+                [$vis $ident]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                $(
+                    $field: $crate::__pin_project_make_unpin_bound!(
+                        $(#[$pin])? $field_ty
+                    )
+                ),+
+            }
+
+            $crate::__pin_project_make_drop_impl! {
+                [$ident]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                $(impl $($pinned_drop)*)?
+            }
+
+            // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+            //
+            // Taking a reference to a packed field is UB, and applying
+            // `#[forbid(unaligned_references)]` makes sure that doing this 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.
+            //
+            // Note:
+            // - Lint-based tricks aren't perfect, but they're much better than nothing:
+            //   https://github.com/taiki-e/pin-project-lite/issues/26
+            //
+            // - Enable both unaligned_references and safe_packed_borrows lints
+            //   because unaligned_references lint does not exist in older compilers:
+            //   https://github.com/taiki-e/pin-project-lite/pull/55
+            //   https://github.com/rust-lang/rust/pull/82525
+            #[forbid(unaligned_references, safe_packed_borrows)]
+            fn __assert_not_repr_packed <$($impl_generics)*> (this: &$ident <$($ty_generics)*>)
+            $(where
+                $($where_clause)*)?
+            {
+                $(
+                    let _ = &this.$field;
+                )+
+            }
+        };
+    };
+    (
+        [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
+        [$($proj_mut_ident:ident)?] [$($proj_ref_ident:ident)?] [$($proj_replace_ident:ident)?]
+        [$proj_vis:vis]
+        [$($def_generics:tt)*]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$variant_attrs:meta])*
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident: $field_ty:ty
+                    ),+ $(,)?
+                })?
+            ),+ $(,)?
+        }
+        $(impl $($pinned_drop:tt)*)?
+    ) => {
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
+        #[allow(clippy::used_underscore_binding)]
+        const _: () = {
+            impl <$($impl_generics)*> $ident <$($ty_generics)*>
+            $(where
+                $($where_clause)*)?
+            {
+                $crate::__pin_project_enum_make_proj_method! {
+                    [$($proj_mut_ident)?]
+                    [$proj_vis]
+                    [project get_unchecked_mut mut]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $variant $({
+                                $(
+                                    $(#[$pin])?
+                                    $field
+                                ),+
+                            })?
+                        ),+
+                    }
+                }
+                $crate::__pin_project_enum_make_proj_method! {
+                    [$($proj_ref_ident)?]
+                    [$proj_vis]
+                    [project_ref get_ref]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $variant $({
+                                $(
+                                    $(#[$pin])?
+                                    $field
+                                ),+
+                            })?
+                        ),+
+                    }
+                }
+                $crate::__pin_project_enum_make_proj_replace_method! {
+                    [$($proj_replace_ident)?]
+                    [$proj_vis]
+                    [$($ty_generics)*]
+                    {
+                        $(
+                            $variant $({
+                                $(
+                                    $(#[$pin])?
+                                    $field
+                                ),+
+                            })?
+                        ),+
+                    }
+                }
+            }
+
+            $crate::__pin_project_make_unpin_impl! {
+                [$vis $ident]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                $(
+                    $variant: ($(
+                        $(
+                            $crate::__pin_project_make_unpin_bound!(
+                                $(#[$pin])? $field_ty
+                            )
+                        ),+
+                    )?)
+                ),+
+            }
+
+            $crate::__pin_project_make_drop_impl! {
+                [$ident]
+                [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+                $(impl $($pinned_drop)*)?
+            }
+
+            // We don't need to check for '#[repr(packed)]',
+            // since it does not apply to enums.
+        };
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_reconstruct {
+    (
+        [$(#[$attrs:meta])* $vis:vis struct $ident:ident]
+        [$($def_generics:tt)*] [$($impl_generics:tt)*]
+        [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident: $field_ty:ty
+            ),+ $(,)?
+        }
+    ) => {
+        $(#[$attrs])*
+        $vis struct $ident $($def_generics)*
+        $(where
+            $($where_clause)*)?
+        {
+            $(
+                $field_vis $field: $field_ty
+            ),+
+        }
+    };
+    (
+        [$(#[$attrs:meta])* $vis:vis enum $ident:ident]
+        [$($def_generics:tt)*] [$($impl_generics:tt)*]
+        [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$variant_attrs:meta])*
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident: $field_ty:ty
+                    ),+ $(,)?
+                })?
+            ),+ $(,)?
+        }
+    ) => {
+        $(#[$attrs])*
+        $vis enum $ident $($def_generics)*
+        $(where
+            $($where_clause)*)?
+        {
+            $(
+                $(#[$variant_attrs])*
+                $variant $({
+                    $(
+                        $field: $field_ty
+                    ),+
+                })?
+            ),+
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_ty {
+    ([] $($field:tt)*) => {};
+    (
+        [$proj_ty_ident:ident $default_ident:ident]
+        [$proj_vis:vis struct $ident:ident]
+        $($field:tt)*
+    ) => {};
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis struct $ident:ident]
+        [$__pin_project_make_proj_field:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident: $field_ty:ty
+            ),+ $(,)?
+        }
+    ) => {
+        $crate::__pin_project_make_proj_ty_body! {
+            [$proj_ty_ident]
+            [$proj_vis struct $ident]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            [
+                $(
+                    $field_vis $field: $crate::$__pin_project_make_proj_field!(
+                        $(#[$pin])? $field_ty
+                    )
+                ),+
+            ]
+        }
+    };
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis enum $ident:ident]
+        [$__pin_project_make_proj_field:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$variant_attrs:meta])*
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident: $field_ty:ty
+                    ),+ $(,)?
+                })?
+            ),+ $(,)?
+        }
+    ) => {
+        $crate::__pin_project_make_proj_ty_body! {
+            [$proj_ty_ident]
+            [$proj_vis enum $ident]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            [
+                $(
+                    $variant $({
+                        $(
+                            $field: $crate::$__pin_project_make_proj_field!(
+                                $(#[$pin])? $field_ty
+                            )
+                        ),+
+                    })?
+                ),+
+            ]
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_ty_body {
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis $struct_ty_ident:ident $ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        [$($body_data:tt)+]
+    ) => {
+        #[allow(dead_code)] // This lint warns unused fields/variants.
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        // This lint warns of `clippy::*` generated by external macros.
+        // We allow this lint for compatibility with older compilers.
+        #[allow(clippy::unknown_clippy_lints)]
+        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::ref_option_ref)] // This lint warns `&Option<&<ty>>`. (only needed for project_ref)
+        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+        $proj_vis $struct_ty_ident $proj_ty_ident <'__pin, $($impl_generics)*>
+        where
+            $ident <$($ty_generics)*>: '__pin
+            $(, $($where_clause)*)?
+        {
+            $($body_data)+
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_replace_ty {
+    ([] $($field:tt)*) => {};
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis struct]
+        [$__pin_project_make_proj_field:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident: $field_ty:ty
+            ),+ $(,)?
+        }
+    ) => {
+        $crate::__pin_project_make_proj_replace_ty_body! {
+            [$proj_ty_ident]
+            [$proj_vis struct]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            [
+                $(
+                    $field_vis $field: $crate::$__pin_project_make_proj_field!(
+                        $(#[$pin])? $field_ty
+                    )
+                ),+
+            ]
+        }
+    };
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis enum]
+        [$__pin_project_make_proj_field:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        {
+            $(
+                $(#[$variant_attrs:meta])*
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident: $field_ty:ty
+                    ),+ $(,)?
+                })?
+            ),+ $(,)?
+        }
+    ) => {
+        $crate::__pin_project_make_proj_replace_ty_body! {
+            [$proj_ty_ident]
+            [$proj_vis enum]
+            [$($impl_generics)*] [$($ty_generics)*] [$(where $($where_clause)*)?]
+            [
+                $(
+                    $variant $({
+                        $(
+                            $field: $crate::$__pin_project_make_proj_field!(
+                                $(#[$pin])? $field_ty
+                            )
+                        ),+
+                    })?
+                ),+
+            ]
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_replace_ty_body {
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis $struct_ty_ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        [$($body_data:tt)+]
+    ) => {
+        #[allow(dead_code)] // This lint warns unused fields/variants.
+        #[allow(single_use_lifetimes)] // https://github.com/rust-lang/rust/issues/55058
+        #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`. (only needed for project)
+        #[allow(clippy::redundant_pub_crate)] // This lint warns `pub(crate)` field in private struct.
+        #[allow(clippy::type_repetition_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/4326
+        $proj_vis $struct_ty_ident $proj_ty_ident <$($impl_generics)*>
+        where
+            $($($where_clause)*)?
+        {
+            $($body_data)+
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_replace_block {
+    (
+        [$($proj_path:tt)+]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident
+            ),+
+        }
+    ) => {
+        let result = $($proj_path)* {
+            $(
+                $field: $crate::__pin_project_make_replace_field_proj!(
+                    $(#[$pin])? $field
+                )
+            ),+
+        };
+
+        {
+            ( $(
+                $crate::__pin_project_make_unsafe_drop_in_place_guard!(
+                    $(#[$pin])? $field
+                ),
+            )* );
+        }
+
+        result
+    };
+    ([$($proj_path:tt)+]) => { $($proj_path)* };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_struct_make_proj_method {
+    ([] $($variant:tt)*) => {};
+    (
+        [$proj_ty_ident:ident $_ignored_default_arg:ident]
+        [$proj_vis:vis]
+        [$method_ident:ident $get_method:ident $($mut:ident)?]
+        [$($ty_generics:tt)*]
+        $($variant:tt)*
+    ) => {
+        $crate::__pin_project_struct_make_proj_method! {
+            [$proj_ty_ident]
+            [$proj_vis]
+            [$method_ident $get_method $($mut)?]
+            [$($ty_generics)*]
+            $($variant)*
+        }
+    };
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis]
+        [$method_ident:ident $get_method:ident $($mut:ident)?]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident
+            ),+
+        }
+    ) => {
+        $proj_vis fn $method_ident<'__pin>(
+            self: $crate::__private::Pin<&'__pin $($mut)? Self>,
+        ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
+            unsafe {
+                let Self { $($field),* } = self.$get_method();
+                $proj_ty_ident {
+                    $(
+                        $field: $crate::__pin_project_make_unsafe_field_proj!(
+                            $(#[$pin])? $field
+                        )
+                    ),+
+                }
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_struct_make_proj_replace_method {
+    ([] $($field:tt)*) => {};
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis]
+        [$_proj_ty_ident:ident]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $(#[$pin:ident])?
+                $field_vis:vis $field:ident
+            ),+
+        }
+    ) => {
+        $proj_vis fn project_replace(
+            self: $crate::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> $proj_ty_ident <$($ty_generics)*> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+                // Destructors will run in reverse order, so next create a guard to overwrite
+                // `self` with the replacement value without calling destructors.
+                let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
+
+                let Self { $($field),* } = &mut *__self_ptr;
+
+                $crate::__pin_project_make_proj_replace_block! {
+                    [$proj_ty_ident]
+                    {
+                        $(
+                            $(#[$pin])?
+                            $field
+                        ),+
+                    }
+                }
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_enum_make_proj_method {
+    ([] $($variant:tt)*) => {};
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis]
+        [$method_ident:ident $get_method:ident $($mut:ident)?]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident
+                    ),+
+                })?
+            ),+
+        }
+    ) => {
+        $proj_vis fn $method_ident<'__pin>(
+            self: $crate::__private::Pin<&'__pin $($mut)? Self>,
+        ) -> $proj_ty_ident <'__pin, $($ty_generics)*> {
+            unsafe {
+                match self.$get_method() {
+                    $(
+                        Self::$variant $({
+                            $($field),+
+                        })? => {
+                            $proj_ty_ident::$variant $({
+                                $(
+                                    $field: $crate::__pin_project_make_unsafe_field_proj!(
+                                        $(#[$pin])? $field
+                                    )
+                                ),+
+                            })?
+                        }
+                    ),+
+                }
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_enum_make_proj_replace_method {
+    ([] $($field:tt)*) => {};
+    (
+        [$proj_ty_ident:ident]
+        [$proj_vis:vis]
+        [$($ty_generics:tt)*]
+        {
+            $(
+                $variant:ident $({
+                    $(
+                        $(#[$pin:ident])?
+                        $field:ident
+                    ),+
+                })?
+            ),+
+        }
+    ) => {
+        $proj_vis fn project_replace(
+            self: $crate::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> $proj_ty_ident <$($ty_generics)*> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+
+                // Destructors will run in reverse order, so next create a guard to overwrite
+                // `self` with the replacement value without calling destructors.
+                let __guard = $crate::__private::UnsafeOverwriteGuard::new(__self_ptr, replacement);
+
+                match &mut *__self_ptr {
+                    $(
+                        Self::$variant $({
+                            $($field),+
+                        })? => {
+                            $crate::__pin_project_make_proj_replace_block! {
+                                [$proj_ty_ident :: $variant]
+                                $({
+                                    $(
+                                        $(#[$pin])?
+                                        $field
+                                    ),+
+                                })?
+                            }
+                        }
+                    ),+
+                }
+            }
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_unpin_impl {
+    (
+        [$vis:vis $ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+        $($field:tt)*
+    ) => {
+        // Automatically create the appropriate conditional `Unpin` implementation.
+        //
+        // Basically this is equivalent to the following code:
+        // ```rust
+        // impl<T, U> Unpin for Struct<T, U> where T: Unpin {}
+        // ```
+        //
+        // However, if struct is public and there is a private type field,
+        // this would cause an E0446 (private type in public interface).
+        //
+        // When RFC 2145 is implemented (rust-lang/rust#48054),
+        // this will become a lint, rather then a hard error.
+        //
+        // As a workaround for this, we generate a new struct, containing all of the pinned
+        // fields from our #[pin_project] type. This struct is declared within
+        // a function, which makes it impossible to be named by user code.
+        // This guarantees that it will use the default auto-trait impl for Unpin -
+        // that is, it will implement Unpin iff all of its fields implement Unpin.
+        // This type can be safely declared as 'public', satisfying the privacy
+        // checker without actually allowing user code to access it.
+        //
+        // This allows users to apply the #[pin_project] attribute to types
+        // regardless of the privacy of the types of their fields.
+        //
+        // See also https://github.com/taiki-e/pin-project/pull/53.
+        #[allow(non_snake_case)]
+        $vis struct __Origin <'__pin, $($impl_generics)*>
+        $(where
+            $($where_clause)*)?
+        {
+            __dummy_lifetime: $crate::__private::PhantomData<&'__pin ()>,
+            $($field)*
+        }
+        impl <'__pin, $($impl_generics)*> $crate::__private::Unpin for $ident <$($ty_generics)*>
+        where
+            __Origin <'__pin, $($ty_generics)*>: $crate::__private::Unpin
+            $(, $($where_clause)*)?
+        {
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_drop_impl {
+    (
+        [$_ident:ident]
+        [$($_impl_generics:tt)*] [$($_ty_generics:tt)*] [$(where $($_where_clause:tt)*)?]
+        impl $(<
+            $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
+            $( $generics:ident
+                $(: $generics_bound:path)?
+                $(: ?$generics_unsized_bound:path)?
+                $(: $generics_lifetime_bound:lifetime)?
+            ),*
+        >)? PinnedDrop for $self_ty:ty
+        $(where
+            $( $where_clause_ty:ty
+                $(: $where_clause_bound:path)?
+                $(: ?$where_clause_unsized_bound:path)?
+                $(: $where_clause_lifetime_bound:lifetime)?
+            ),* $(,)?
+        )?
+        {
+            fn drop($($arg:ident)+: Pin<&mut Self>) {
+                $($tt:tt)*
+            }
+        }
+    ) => {
+        impl $(<
+            $( $lifetime $(: $lifetime_bound)? ,)*
+            $( $generics
+                $(: $generics_bound)?
+                $(: ?$generics_unsized_bound)?
+                $(: $generics_lifetime_bound)?
+            ),*
+        >)? $crate::__private::Drop for $self_ty
+        $(where
+            $( $where_clause_ty
+                $(: $where_clause_bound)?
+                $(: ?$where_clause_unsized_bound)?
+                $(: $where_clause_lifetime_bound)?
+            ),*
+        )?
+        {
+            fn drop(&mut self) {
+                // Implementing `__DropInner::__drop_inner` 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).
+                //
+                // `__drop_inner` is defined as a safe method, but this is fine since
+                // `__drop_inner` is not accessible by the users and we call `__drop_inner` only
+                // once.
+                //
+                // Users can implement [`Drop`] safely using `pin_project!` and can drop a
+                // type that implements `PinnedDrop` using the [`drop`] function safely.
+                fn __drop_inner $(<
+                    $( $lifetime $(: $lifetime_bound)? ,)*
+                    $( $generics
+                        $(: $generics_bound)?
+                        $(: ?$generics_unsized_bound)?
+                        $(: $generics_lifetime_bound)?
+                    ),*
+                >)? (
+                    $($arg)+: $crate::__private::Pin<&mut $self_ty>,
+                )
+                $(where
+                    $( $where_clause_ty
+                        $(: $where_clause_bound)?
+                        $(: ?$where_clause_unsized_bound)?
+                        $(: $where_clause_lifetime_bound)?
+                    ),*
+                )?
+                {
+                    // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`.
+                    fn __drop_inner() {}
+                    $($tt)*
+                }
+
+                // Safety - we're in 'drop', so we know that 'self' will
+                // never move again.
+                let pinned_self: $crate::__private::Pin<&mut Self>
+                    = unsafe { $crate::__private::Pin::new_unchecked(self) };
+                // We call `__drop_inner` only once. Since `__DropInner::__drop_inner`
+                // is not accessible by the users, it is never called again.
+                __drop_inner(pinned_self);
+            }
+        }
+    };
+    (
+        [$ident:ident]
+        [$($impl_generics:tt)*] [$($ty_generics:tt)*] [$(where $($where_clause:tt)*)?]
+    ) => {
+        // Ensure that struct does not implement `Drop`.
+        //
+        // There are two possible cases:
+        // 1. The user type does not implement Drop. In this case,
+        // the first blanked impl will not apply to it. This code
+        // will compile, as there is only one impl of MustNotImplDrop for the user type
+        // 2. The user type does impl Drop. This will make the blanket impl applicable,
+        // which will then conflict with the explicit MustNotImplDrop impl below.
+        // This will result in a compilation error, which is exactly what we want.
+        trait MustNotImplDrop {}
+        #[allow(clippy::drop_bounds, drop_bounds)]
+        impl<T: $crate::__private::Drop> MustNotImplDrop for T {}
+        impl <$($impl_generics)*> MustNotImplDrop for $ident <$($ty_generics)*>
+        $(where
+            $($where_clause)*)?
+        {
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_unpin_bound {
+    (#[pin] $field_ty:ty) => {
+        $field_ty
+    };
+    ($field_ty:ty) => {
+        $crate::__private::AlwaysUnpin<$field_ty>
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_unsafe_field_proj {
+    (#[pin] $field:ident) => {
+        $crate::__private::Pin::new_unchecked($field)
+    };
+    ($field:ident) => {
+        $field
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_replace_field_proj {
+    (#[pin] $field:ident) => {
+        $crate::__private::PhantomData
+    };
+    ($field:ident) => {
+        $crate::__private::ptr::read($field)
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_unsafe_drop_in_place_guard {
+    (#[pin] $field:ident) => {
+        $crate::__private::UnsafeDropInPlaceGuard::new($field)
+    };
+    ($field:ident) => {
+        ()
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_field_mut {
+    (#[pin] $field_ty:ty) => {
+        $crate::__private::Pin<&'__pin mut ($field_ty)>
+    };
+    ($field_ty:ty) => {
+        &'__pin mut ($field_ty)
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_field_ref {
+    (#[pin] $field_ty:ty) => {
+        $crate::__private::Pin<&'__pin ($field_ty)>
+    };
+    ($field_ty:ty) => {
+        &'__pin ($field_ty)
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_make_proj_field_replace {
+    (#[pin] $field_ty:ty) => {
+        $crate::__private::PhantomData<$field_ty>
+    };
+    ($field_ty:ty) => {
+        $field_ty
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_internal {
+    // parsing proj_mut_ident
+    (
+        []
+        [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
+        [$($attrs:tt)*]
+
+        #[project = $proj_mut_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$proj_mut_ident]
+            [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
+            [$($attrs)*]
+            $($tt)*
+        }
+    };
+    // parsing proj_ref_ident
+    (
+        [$($proj_mut_ident:ident)?]
+        []
+        [$($proj_replace_ident:ident)?]
+        [$($attrs:tt)*]
+
+        #[project_ref = $proj_ref_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$($proj_mut_ident)?]
+            [$proj_ref_ident]
+            [$($proj_replace_ident)?]
+            [$($attrs)*]
+            $($tt)*
+        }
+    };
+    // parsing proj_replace_ident
+    (
+        [$($proj_mut_ident:ident)?]
+        [$($proj_ref_ident:ident)?]
+        []
+        [$($attrs:tt)*]
+
+        #[project_replace = $proj_replace_ident:ident]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$($proj_mut_ident)?]
+            [$($proj_ref_ident)?]
+            [$proj_replace_ident]
+            [$($attrs)*]
+            $($tt)*
+        }
+    };
+    // this is actually part of a recursive step that picks off a single non-`pin_project_lite` attribute
+    // there could be more to parse
+    (
+        [$($proj_mut_ident:ident)?]
+        [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
+        [$($attrs:tt)*]
+
+        #[$($attr:tt)*]
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_internal! {
+            [$($proj_mut_ident)?]
+            [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
+            [$($attrs)* #[$($attr)*]]
+            $($tt)*
+        }
+    };
+    // now determine visibility
+    // if public, downgrade
+    (
+        [$($proj_mut_ident:ident)?]
+        [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
+        [$($attrs:tt)*]
+        pub $struct_ty_ident:ident $ident:ident
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_parse_generics! {
+            [$($proj_mut_ident)?]
+            [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
+            [$($attrs)*]
+            [pub $struct_ty_ident $ident pub(crate)]
+            $($tt)*
+        }
+    };
+    (
+        [$($proj_mut_ident:ident)?]
+        [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
+        [$($attrs:tt)*]
+        $vis:vis $struct_ty_ident:ident $ident:ident
+        $($tt:tt)*
+    ) => {
+        $crate::__pin_project_parse_generics! {
+            [$($proj_mut_ident)?]
+            [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
+            [$($attrs)*]
+            [$vis $struct_ty_ident $ident $vis]
+            $($tt)*
+        }
+    };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __pin_project_parse_generics {
+    (
+        [$($proj_mut_ident:ident)?]
+        [$($proj_ref_ident:ident)?]
+        [$($proj_replace_ident:ident)?]
+        [$($attrs:tt)*]
+        [$vis:vis $struct_ty_ident:ident $ident:ident $proj_ty_vis:vis]
+        $(<
+            $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)?
+            $( $generics:ident
+                $(: $generics_bound:path)?
+                $(: ?$generics_unsized_bound:path)?
+                $(: $generics_lifetime_bound:lifetime)?
+                $(= $generics_default:ty)?
+            ),* $(,)?
+        >)?
+        $(where
+            $( $where_clause_ty:ty
+                $(: $where_clause_bound:path)?
+                $(: ?$where_clause_unsized_bound:path)?
+                $(: $where_clause_lifetime_bound:lifetime)?
+            ),* $(,)?
+        )?
+        {
+            $($body_data:tt)*
+        }
+        $(impl $($pinned_drop:tt)*)?
+    ) => {
+        $crate::__pin_project_expand! {
+            [$($proj_mut_ident)?]
+            [$($proj_ref_ident)?]
+            [$($proj_replace_ident)?]
+            [$proj_ty_vis]
+            [$($attrs)* $vis $struct_ty_ident $ident]
+            [$(<
+                $( $lifetime $(: $lifetime_bound)? ,)*
+                $( $generics
+                    $(: $generics_bound)?
+                    $(: ?$generics_unsized_bound)?
+                    $(: $generics_lifetime_bound)?
+                    $(= $generics_default)?
+                ),*
+            >)?]
+            [$(
+                $( $lifetime $(: $lifetime_bound)? ,)*
+                $( $generics
+                    $(: $generics_bound)?
+                    $(: ?$generics_unsized_bound)?
+                    $(: $generics_lifetime_bound)?
+                ),*
+            )?]
+            [$( $( $lifetime ,)* $( $generics ),* )?]
+            [$(where $( $where_clause_ty
+                $(: $where_clause_bound)?
+                $(: ?$where_clause_unsized_bound)?
+                $(: $where_clause_lifetime_bound)?
+            ),* )?]
+            {
+                $($body_data)*
+            }
+            $(impl $($pinned_drop)*)?
+        }
+    };
+}
+
+#[doc(hidden)]
+pub mod __private {
+    use core::mem::ManuallyDrop;
+    #[doc(hidden)]
+    pub use core::{
+        marker::{PhantomData, Unpin},
+        ops::Drop,
+        pin::Pin,
+        ptr,
+    };
+
+    // This is an internal helper struct used by `pin_project!`.
+    #[doc(hidden)]
+    pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);
+
+    impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
+
+    // This is an internal helper used to ensure a value is dropped.
+    #[doc(hidden)]
+    pub struct UnsafeDropInPlaceGuard<T: ?Sized>(*mut T);
+
+    impl<T: ?Sized> UnsafeDropInPlaceGuard<T> {
+        #[doc(hidden)]
+        pub unsafe fn new(ptr: *mut T) -> Self {
+            Self(ptr)
+        }
+    }
+
+    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> {
+        target: *mut T,
+        value: ManuallyDrop<T>,
+    }
+
+    impl<T> UnsafeOverwriteGuard<T> {
+        #[doc(hidden)]
+        pub unsafe fn new(target: *mut T, value: T) -> Self {
+            Self { target, value: ManuallyDrop::new(value) }
+        }
+    }
+
+    impl<T> Drop for UnsafeOverwriteGuard<T> {
+        fn drop(&mut self) {
+            unsafe {
+                ptr::write(self.target, ptr::read(&*self.value));
+            }
+        }
+    }
+}
diff --git a/tests/README.md b/tests/README.md
new file mode 100644 (file)
index 0000000..4721616
--- /dev/null
@@ -0,0 +1,46 @@
+# Tests
+
+Many of the tests in this repository are based on [pin-project's tests](https://github.com/taiki-e/pin-project/tree/HEAD/tests).
+
+To run all tests, run the following command:
+
+```sh
+cargo +nightly test --all
+```
+
+## UI tests (`ui`, `compiletest.rs`)
+
+This checks errors detected by the macro or the Rust compiler in the resulting
+expanded code.
+
+To run this test, run the following command:
+
+```sh
+cargo +nightly test --test compiletest
+```
+
+Locally, this test updates the files in the `ui` directory if there are
+changes to the generated code. If there are any changes to the files in the
+`ui` directory after running the test, please commit them.
+
+See also [`trybuild` documentation](https://docs.rs/trybuild).
+
+## Expansion tests (`expand`, `expandtest.rs`)
+
+Similar to ui tests, but instead of checking the compiler output, this checks
+the code generated by macros.
+
+See pin-project's [examples](https://github.com/taiki-e/pin-project/tree/HEAD/examples)
+for descriptions of what the generated code does, and why it needs to be generated.
+
+To run this test, run the following command:
+
+```sh
+cargo +nightly test --test expandtest
+```
+
+Locally, this test updates the files in the `expand` directory if there are
+changes to the generated code. If there are any changes to the files in the
+`expand` directory after running the test, please commit them.
+
+See also [`macrotest` documentation](https://docs.rs/macrotest).
diff --git a/tests/auxiliary/mod.rs b/tests/auxiliary/mod.rs
new file mode 100644 (file)
index 0000000..1457099
--- /dev/null
@@ -0,0 +1,12 @@
+#![allow(dead_code, unused_macros)]
+
+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);
+    };
+}
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
new file mode 100644 (file)
index 0000000..70d2358
--- /dev/null
@@ -0,0 +1,15 @@
+#![cfg(not(miri))]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+use std::env;
+
+#[rustversion::attr(not(nightly), ignore)]
+#[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/**/*.rs");
+}
diff --git a/tests/drop_order.rs b/tests/drop_order.rs
new file mode 100644 (file)
index 0000000..6e5deaf
--- /dev/null
@@ -0,0 +1,169 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+// Refs: https://doc.rust-lang.org/reference/destructors.html
+
+use std::{cell::Cell, panic, pin::Pin, thread};
+
+use pin_project_lite::pin_project;
+
+struct D<'a>(&'a Cell<usize>, usize);
+
+impl Drop for D<'_> {
+    fn drop(&mut self) {
+        if !thread::panicking() {
+            let old = self.0.replace(self.1);
+            assert_eq!(old, self.1 - 1);
+        }
+    }
+}
+
+pin_project! {
+#[project = StructPinnedProj]
+#[project_ref = StructPinnedProjRef]
+#[project_replace = StructPinnedProjReplace]
+struct StructPinned<'a> {
+    #[pin]
+    f1: D<'a>,
+    #[pin]
+    f2: D<'a>,
+}
+}
+
+pin_project! {
+#[project = StructUnpinnedProj]
+#[project_ref = StructUnpinnedProjRef]
+#[project_replace = StructUnpinnedProjReplace]
+struct StructUnpinned<'a> {
+    f1: D<'a>,
+    f2: D<'a>,
+}
+}
+
+pin_project! {
+#[project_replace = EnumProjReplace]
+enum Enum<'a> {
+    #[allow(dead_code)] // false positive that fixed in Rust 1.38
+    StructPinned {
+        #[pin]
+        f1: D<'a>,
+        #[pin]
+        f2: D<'a>,
+    },
+    #[allow(dead_code)] // false positive that fixed in Rust 1.38
+    StructUnpinned {
+        f1: D<'a>,
+        f2: D<'a>,
+    },
+}
+}
+
+#[test]
+fn struct_pinned() {
+    {
+        let c = Cell::new(0);
+        let _x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+#[test]
+fn struct_unpinned() {
+    {
+        let c = Cell::new(0);
+        let _x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+#[test]
+fn enum_struct() {
+    {
+        let c = Cell::new(0);
+        let _x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::StructPinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::StructPinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+
+    {
+        let c = Cell::new(0);
+        let _x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+    }
+    {
+        let c = Cell::new(0);
+        let mut x = Enum::StructUnpinned { f1: D(&c, 1), f2: D(&c, 2) };
+        let y = Pin::new(&mut x);
+        let _z = y.project_replace(Enum::StructUnpinned { f1: D(&c, 3), f2: D(&c, 4) });
+    }
+}
+
+// https://github.com/rust-lang/rust/issues/47949
+// https://github.com/taiki-e/pin-project/pull/194#discussion_r419098111
+#[allow(clippy::many_single_char_names)]
+#[test]
+fn project_replace_panic() {
+    pin_project! {
+    #[project_replace = SProjReplace]
+    struct S<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+    }
+
+    struct D<'a>(&'a mut bool, bool);
+    impl Drop for D<'_> {
+        fn drop(&mut self) {
+            *self.0 = true;
+            if self.1 {
+                panic!();
+            }
+        }
+    }
+
+    let (mut a, mut b, mut c, mut d) = (false, false, false, false);
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        let mut x = S { pinned: D(&mut a, true), unpinned: D(&mut b, false) };
+        let _y = Pin::new(&mut x)
+            .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
+        // Previous `x.pinned` was dropped and panicked when `project_replace` is
+        // called, so this is unreachable.
+        unreachable!();
+    }));
+    assert!(res.is_err());
+    assert!(a);
+    assert!(b);
+    assert!(c);
+    assert!(d);
+
+    let (mut a, mut b, mut c, mut d) = (false, false, false, false);
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        let mut x = S { pinned: D(&mut a, false), unpinned: D(&mut b, true) };
+        {
+            let _y = Pin::new(&mut x)
+                .project_replace(S { pinned: D(&mut c, false), unpinned: D(&mut d, false) });
+            // `_y` (previous `x.unpinned`) live to the end of this scope, so
+            // this is not unreachable.
+            // unreachable!();
+        }
+        unreachable!();
+    }));
+    assert!(res.is_err());
+    assert!(a);
+    assert!(b);
+    assert!(c);
+    assert!(d);
+}
diff --git a/tests/expand/default/enum.expanded.rs b/tests/expand/default/enum.expanded.rs
new file mode 100644 (file)
index 0000000..eae0aac
--- /dev/null
@@ -0,0 +1,127 @@
+use pin_project_lite::pin_project;
+enum Enum<T, U> {
+    Struct { pinned: T, unpinned: U },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProj<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProjRef<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProjReplace<T, U> {
+    Struct {
+        pinned: ::pin_project_lite::__private::PhantomData<T>,
+        unpinned: U,
+    },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> EnumProj<'__pin, T, U> {
+            unsafe {
+                match self.get_unchecked_mut() {
+                    Self::Struct { pinned, unpinned } => EnumProj::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProj::Unit,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> EnumProjRef<'__pin, T, U> {
+            unsafe {
+                match self.get_ref() {
+                    Self::Struct { pinned, unpinned } => EnumProjRef::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProjRef::Unit,
+                }
+            }
+        }
+        fn project_replace(
+            self: ::pin_project_lite::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> EnumProjReplace<T, U> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+                let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new(
+                    __self_ptr,
+                    replacement,
+                );
+                match &mut *__self_ptr {
+                    Self::Struct { pinned, unpinned } => {
+                        let result = EnumProjReplace::Struct {
+                            pinned: ::pin_project_lite::__private::PhantomData,
+                            unpinned: ::pin_project_lite::__private::ptr::read(unpinned),
+                        };
+                        {
+                            (
+                                ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new(pinned),
+                                (),
+                            );
+                        }
+                        result
+                    }
+                    Self::Unit => EnumProjReplace::Unit,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (T, ::pin_project_lite::__private::AlwaysUnpin<U>),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Enum<T, U> {}
+};
+fn main() {}
diff --git a/tests/expand/default/enum.rs b/tests/expand/default/enum.rs
new file mode 100644 (file)
index 0000000..90d6860
--- /dev/null
@@ -0,0 +1,17 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project = EnumProj]
+    #[project_ref = EnumProjRef]
+    #[project_replace = EnumProjReplace]
+    enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/default/struct.expanded.rs b/tests/expand/default/struct.expanded.rs
new file mode 100644 (file)
index 0000000..8ab318c
--- /dev/null
@@ -0,0 +1,84 @@
+use pin_project_lite::pin_project;
+struct Struct<T, U> {
+    pinned: T,
+    unpinned: U,
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct Projection<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    }
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct ProjectionRef<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    }
+    impl<T, U> Struct<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> Projection<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_unchecked_mut();
+                Projection {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> ProjectionRef<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_ref();
+                ProjectionRef {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned: T,
+        unpinned: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Struct<T, U> {}
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+};
+fn main() {}
diff --git a/tests/expand/default/struct.rs b/tests/expand/default/struct.rs
new file mode 100644 (file)
index 0000000..e5447c7
--- /dev/null
@@ -0,0 +1,11 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct Struct<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/multifields/enum.expanded.rs b/tests/expand/multifields/enum.expanded.rs
new file mode 100644 (file)
index 0000000..fca0feb
--- /dev/null
@@ -0,0 +1,88 @@
+use pin_project_lite::pin_project;
+enum Enum<T, U> {
+    Struct {
+        pinned1: T,
+        pinned2: T,
+        unpinned1: U,
+        unpinned2: U,
+    },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProjReplace<T, U> {
+    Struct {
+        pinned1: ::pin_project_lite::__private::PhantomData<T>,
+        pinned2: ::pin_project_lite::__private::PhantomData<T>,
+        unpinned1: U,
+        unpinned2: U,
+    },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {
+        fn project_replace(
+            self: ::pin_project_lite::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> EnumProjReplace<T, U> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+                let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new(
+                    __self_ptr,
+                    replacement,
+                );
+                match &mut *__self_ptr {
+                    Self::Struct {
+                        pinned1,
+                        pinned2,
+                        unpinned1,
+                        unpinned2,
+                    } => {
+                        let result = EnumProjReplace::Struct {
+                            pinned1: ::pin_project_lite::__private::PhantomData,
+                            pinned2: ::pin_project_lite::__private::PhantomData,
+                            unpinned1: ::pin_project_lite::__private::ptr::read(unpinned1),
+                            unpinned2: ::pin_project_lite::__private::ptr::read(unpinned2),
+                        };
+                        {
+                            (
+                                ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new(pinned1),
+                                ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new(pinned2),
+                                (),
+                                (),
+                            );
+                        }
+                        result
+                    }
+                    Self::Unit => EnumProjReplace::Unit,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (
+            T,
+            T,
+            ::pin_project_lite::__private::AlwaysUnpin<U>,
+            ::pin_project_lite::__private::AlwaysUnpin<U>,
+        ),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Enum<T, U> {}
+};
+fn main() {}
diff --git a/tests/expand/multifields/enum.rs b/tests/expand/multifields/enum.rs
new file mode 100644 (file)
index 0000000..c713362
--- /dev/null
@@ -0,0 +1,18 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+#[project_replace = EnumProjReplace]
+enum Enum<T, U> {
+    Struct {
+        #[pin]
+        pinned1: T,
+        #[pin]
+        pinned2: T,
+        unpinned1: U,
+        unpinned2: U,
+    },
+    Unit,
+}
+}
+
+fn main() {}
diff --git a/tests/expand/multifields/struct.expanded.rs b/tests/expand/multifields/struct.expanded.rs
new file mode 100644 (file)
index 0000000..4320f68
--- /dev/null
@@ -0,0 +1,152 @@
+use pin_project_lite::pin_project;
+struct Struct<T, U> {
+    pinned1: T,
+    pinned2: T,
+    unpinned1: U,
+    unpinned2: U,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::type_repetition_in_bounds)]
+struct StructProjReplace<T, U> {
+    pinned1: ::pin_project_lite::__private::PhantomData<T>,
+    pinned2: ::pin_project_lite::__private::PhantomData<T>,
+    unpinned1: U,
+    unpinned2: U,
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct Projection<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned1: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        pinned2: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned1: &'__pin mut (U),
+        unpinned2: &'__pin mut (U),
+    }
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct ProjectionRef<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned1: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        pinned2: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned1: &'__pin (U),
+        unpinned2: &'__pin (U),
+    }
+    impl<T, U> Struct<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> Projection<'__pin, T, U> {
+            unsafe {
+                let Self {
+                    pinned1,
+                    pinned2,
+                    unpinned1,
+                    unpinned2,
+                } = self.get_unchecked_mut();
+                Projection {
+                    pinned1: ::pin_project_lite::__private::Pin::new_unchecked(pinned1),
+                    pinned2: ::pin_project_lite::__private::Pin::new_unchecked(pinned2),
+                    unpinned1: unpinned1,
+                    unpinned2: unpinned2,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> ProjectionRef<'__pin, T, U> {
+            unsafe {
+                let Self {
+                    pinned1,
+                    pinned2,
+                    unpinned1,
+                    unpinned2,
+                } = self.get_ref();
+                ProjectionRef {
+                    pinned1: ::pin_project_lite::__private::Pin::new_unchecked(pinned1),
+                    pinned2: ::pin_project_lite::__private::Pin::new_unchecked(pinned2),
+                    unpinned1: unpinned1,
+                    unpinned2: unpinned2,
+                }
+            }
+        }
+        fn project_replace(
+            self: ::pin_project_lite::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> StructProjReplace<T, U> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+                let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new(
+                    __self_ptr,
+                    replacement,
+                );
+                let Self {
+                    pinned1,
+                    pinned2,
+                    unpinned1,
+                    unpinned2,
+                } = &mut *__self_ptr;
+                let result = StructProjReplace {
+                    pinned1: ::pin_project_lite::__private::PhantomData,
+                    pinned2: ::pin_project_lite::__private::PhantomData,
+                    unpinned1: ::pin_project_lite::__private::ptr::read(unpinned1),
+                    unpinned2: ::pin_project_lite::__private::ptr::read(unpinned2),
+                };
+                {
+                    (
+                        ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new(pinned1),
+                        ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new(pinned2),
+                        (),
+                        (),
+                    );
+                }
+                result
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned1: T,
+        pinned2: T,
+        unpinned1: ::pin_project_lite::__private::AlwaysUnpin<U>,
+        unpinned2: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Struct<T, U> {}
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned1;
+        let _ = &this.pinned2;
+        let _ = &this.unpinned1;
+        let _ = &this.unpinned2;
+    }
+};
+fn main() {}
diff --git a/tests/expand/multifields/struct.rs b/tests/expand/multifields/struct.rs
new file mode 100644 (file)
index 0000000..a1d45d1
--- /dev/null
@@ -0,0 +1,15 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+#[project_replace = StructProjReplace]
+struct Struct<T, U> {
+    #[pin]
+    pinned1: T,
+    #[pin]
+    pinned2: T,
+    unpinned1: U,
+    unpinned2: U,
+}
+}
+
+fn main() {}
diff --git a/tests/expand/naming/enum-all.expanded.rs b/tests/expand/naming/enum-all.expanded.rs
new file mode 100644 (file)
index 0000000..eae0aac
--- /dev/null
@@ -0,0 +1,127 @@
+use pin_project_lite::pin_project;
+enum Enum<T, U> {
+    Struct { pinned: T, unpinned: U },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProj<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProjRef<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProjReplace<T, U> {
+    Struct {
+        pinned: ::pin_project_lite::__private::PhantomData<T>,
+        unpinned: U,
+    },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> EnumProj<'__pin, T, U> {
+            unsafe {
+                match self.get_unchecked_mut() {
+                    Self::Struct { pinned, unpinned } => EnumProj::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProj::Unit,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> EnumProjRef<'__pin, T, U> {
+            unsafe {
+                match self.get_ref() {
+                    Self::Struct { pinned, unpinned } => EnumProjRef::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProjRef::Unit,
+                }
+            }
+        }
+        fn project_replace(
+            self: ::pin_project_lite::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> EnumProjReplace<T, U> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+                let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new(
+                    __self_ptr,
+                    replacement,
+                );
+                match &mut *__self_ptr {
+                    Self::Struct { pinned, unpinned } => {
+                        let result = EnumProjReplace::Struct {
+                            pinned: ::pin_project_lite::__private::PhantomData,
+                            unpinned: ::pin_project_lite::__private::ptr::read(unpinned),
+                        };
+                        {
+                            (
+                                ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new(pinned),
+                                (),
+                            );
+                        }
+                        result
+                    }
+                    Self::Unit => EnumProjReplace::Unit,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (T, ::pin_project_lite::__private::AlwaysUnpin<U>),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Enum<T, U> {}
+};
+fn main() {}
diff --git a/tests/expand/naming/enum-all.rs b/tests/expand/naming/enum-all.rs
new file mode 100644 (file)
index 0000000..90d6860
--- /dev/null
@@ -0,0 +1,17 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project = EnumProj]
+    #[project_ref = EnumProjRef]
+    #[project_replace = EnumProjReplace]
+    enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/naming/enum-mut.expanded.rs b/tests/expand/naming/enum-mut.expanded.rs
new file mode 100644 (file)
index 0000000..7c4d6af
--- /dev/null
@@ -0,0 +1,57 @@
+use pin_project_lite::pin_project;
+enum Enum<T, U> {
+    Struct { pinned: T, unpinned: U },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProj<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> EnumProj<'__pin, T, U> {
+            unsafe {
+                match self.get_unchecked_mut() {
+                    Self::Struct { pinned, unpinned } => EnumProj::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProj::Unit,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (T, ::pin_project_lite::__private::AlwaysUnpin<U>),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Enum<T, U> {}
+};
+fn main() {}
diff --git a/tests/expand/naming/enum-mut.rs b/tests/expand/naming/enum-mut.rs
new file mode 100644 (file)
index 0000000..69beecd
--- /dev/null
@@ -0,0 +1,15 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project = EnumProj]
+    enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/naming/enum-none.expanded.rs b/tests/expand/naming/enum-none.expanded.rs
new file mode 100644 (file)
index 0000000..28ce97d
--- /dev/null
@@ -0,0 +1,26 @@
+use pin_project_lite::pin_project;
+enum Enum<T, U> {
+    Struct { pinned: T, unpinned: U },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {}
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (T, ::pin_project_lite::__private::AlwaysUnpin<U>),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Enum<T, U> {}
+};
+fn main() {}
diff --git a/tests/expand/naming/enum-none.rs b/tests/expand/naming/enum-none.rs
new file mode 100644 (file)
index 0000000..b2e3f9d
--- /dev/null
@@ -0,0 +1,14 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/naming/enum-ref.expanded.rs b/tests/expand/naming/enum-ref.expanded.rs
new file mode 100644 (file)
index 0000000..a1a013b
--- /dev/null
@@ -0,0 +1,57 @@
+use pin_project_lite::pin_project;
+enum Enum<T, U> {
+    Struct { pinned: T, unpinned: U },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProjRef<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> EnumProjRef<'__pin, T, U> {
+            unsafe {
+                match self.get_ref() {
+                    Self::Struct { pinned, unpinned } => EnumProjRef::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProjRef::Unit,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (T, ::pin_project_lite::__private::AlwaysUnpin<U>),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Enum<T, U> {}
+};
+fn main() {}
diff --git a/tests/expand/naming/enum-ref.rs b/tests/expand/naming/enum-ref.rs
new file mode 100644 (file)
index 0000000..480d592
--- /dev/null
@@ -0,0 +1,15 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project_ref = EnumProjRef]
+    enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/naming/struct-all.expanded.rs b/tests/expand/naming/struct-all.expanded.rs
new file mode 100644 (file)
index 0000000..b91c24e
--- /dev/null
@@ -0,0 +1,117 @@
+use pin_project_lite::pin_project;
+struct Struct<T, U> {
+    pinned: T,
+    unpinned: U,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+struct StructProj<'__pin, T, U>
+where
+    Struct<T, U>: '__pin,
+{
+    pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+    unpinned: &'__pin mut (U),
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+struct StructProjRef<'__pin, T, U>
+where
+    Struct<T, U>: '__pin,
+{
+    pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+    unpinned: &'__pin (U),
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::type_repetition_in_bounds)]
+struct StructProjReplace<T, U> {
+    pinned: ::pin_project_lite::__private::PhantomData<T>,
+    unpinned: U,
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Struct<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> StructProj<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_unchecked_mut();
+                StructProj {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> StructProjRef<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_ref();
+                StructProjRef {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        fn project_replace(
+            self: ::pin_project_lite::__private::Pin<&mut Self>,
+            replacement: Self,
+        ) -> StructProjReplace<T, U> {
+            unsafe {
+                let __self_ptr: *mut Self = self.get_unchecked_mut();
+                let __guard = ::pin_project_lite::__private::UnsafeOverwriteGuard::new(
+                    __self_ptr,
+                    replacement,
+                );
+                let Self { pinned, unpinned } = &mut *__self_ptr;
+                let result = StructProjReplace {
+                    pinned: ::pin_project_lite::__private::PhantomData,
+                    unpinned: ::pin_project_lite::__private::ptr::read(unpinned),
+                };
+                {
+                    (
+                        ::pin_project_lite::__private::UnsafeDropInPlaceGuard::new(pinned),
+                        (),
+                    );
+                }
+                result
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned: T,
+        unpinned: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Struct<T, U> {}
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+};
+fn main() {}
diff --git a/tests/expand/naming/struct-all.rs b/tests/expand/naming/struct-all.rs
new file mode 100644 (file)
index 0000000..cb08753
--- /dev/null
@@ -0,0 +1,14 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project = StructProj]
+    #[project_ref = StructProjRef]
+    #[project_replace = StructProjReplace]
+    struct Struct<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/naming/struct-mut.expanded.rs b/tests/expand/naming/struct-mut.expanded.rs
new file mode 100644 (file)
index 0000000..aaa41cd
--- /dev/null
@@ -0,0 +1,84 @@
+use pin_project_lite::pin_project;
+struct Struct<T, U> {
+    pinned: T,
+    unpinned: U,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+struct StructProj<'__pin, T, U>
+where
+    Struct<T, U>: '__pin,
+{
+    pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+    unpinned: &'__pin mut (U),
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct ProjectionRef<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    }
+    impl<T, U> Struct<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> StructProj<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_unchecked_mut();
+                StructProj {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> ProjectionRef<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_ref();
+                ProjectionRef {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned: T,
+        unpinned: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Struct<T, U> {}
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+};
+fn main() {}
diff --git a/tests/expand/naming/struct-mut.rs b/tests/expand/naming/struct-mut.rs
new file mode 100644 (file)
index 0000000..59db445
--- /dev/null
@@ -0,0 +1,12 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project = StructProj]
+    struct Struct<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/naming/struct-none.expanded.rs b/tests/expand/naming/struct-none.expanded.rs
new file mode 100644 (file)
index 0000000..8ab318c
--- /dev/null
@@ -0,0 +1,84 @@
+use pin_project_lite::pin_project;
+struct Struct<T, U> {
+    pinned: T,
+    unpinned: U,
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct Projection<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    }
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct ProjectionRef<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    }
+    impl<T, U> Struct<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> Projection<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_unchecked_mut();
+                Projection {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> ProjectionRef<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_ref();
+                ProjectionRef {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned: T,
+        unpinned: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Struct<T, U> {}
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+};
+fn main() {}
diff --git a/tests/expand/naming/struct-none.rs b/tests/expand/naming/struct-none.rs
new file mode 100644 (file)
index 0000000..e5447c7
--- /dev/null
@@ -0,0 +1,11 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct Struct<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/naming/struct-ref.expanded.rs b/tests/expand/naming/struct-ref.expanded.rs
new file mode 100644 (file)
index 0000000..3d97ab8
--- /dev/null
@@ -0,0 +1,84 @@
+use pin_project_lite::pin_project;
+struct Struct<T, U> {
+    pinned: T,
+    unpinned: U,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+struct StructProjRef<'__pin, T, U>
+where
+    Struct<T, U>: '__pin,
+{
+    pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+    unpinned: &'__pin (U),
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct Projection<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    }
+    impl<T, U> Struct<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> Projection<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_unchecked_mut();
+                Projection {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> StructProjRef<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_ref();
+                StructProjRef {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned: T,
+        unpinned: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Struct<T, U> {}
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+};
+fn main() {}
diff --git a/tests/expand/naming/struct-ref.rs b/tests/expand/naming/struct-ref.rs
new file mode 100644 (file)
index 0000000..6821af8
--- /dev/null
@@ -0,0 +1,12 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project_ref = StructProjRef]
+    struct Struct<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/pinned_drop/enum.expanded.rs b/tests/expand/pinned_drop/enum.expanded.rs
new file mode 100644 (file)
index 0000000..665ff63
--- /dev/null
@@ -0,0 +1,95 @@
+use pin_project_lite::pin_project;
+use std::pin::Pin;
+enum Enum<T, U> {
+    Struct { pinned: T, unpinned: U },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProj<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+enum EnumProjRef<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> EnumProj<'__pin, T, U> {
+            unsafe {
+                match self.get_unchecked_mut() {
+                    Self::Struct { pinned, unpinned } => EnumProj::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProj::Unit,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> EnumProjRef<'__pin, T, U> {
+            unsafe {
+                match self.get_ref() {
+                    Self::Struct { pinned, unpinned } => EnumProjRef::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProjRef::Unit,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (T, ::pin_project_lite::__private::AlwaysUnpin<U>),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    impl<T, U> ::pin_project_lite::__private::Drop for Enum<T, U> {
+        fn drop(&mut self) {
+            fn __drop_inner<T, U>(this: ::pin_project_lite::__private::Pin<&mut Enum<T, U>>) {
+                fn __drop_inner() {}
+                let _ = this;
+            }
+            let pinned_self: ::pin_project_lite::__private::Pin<&mut Self> =
+                unsafe { ::pin_project_lite::__private::Pin::new_unchecked(self) };
+            __drop_inner(pinned_self);
+        }
+    }
+};
+fn main() {}
diff --git a/tests/expand/pinned_drop/enum.rs b/tests/expand/pinned_drop/enum.rs
new file mode 100644 (file)
index 0000000..1855cb7
--- /dev/null
@@ -0,0 +1,22 @@
+use pin_project_lite::pin_project;
+use std::pin::Pin;
+
+pin_project! {
+    #[project = EnumProj]
+    #[project_ref = EnumProjRef]
+    enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+    impl<T, U> PinnedDrop for Enum<T, U> {
+        fn drop(this: Pin<&mut Self>) {
+            let _ = this;
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/pinned_drop/struct.expanded.rs b/tests/expand/pinned_drop/struct.expanded.rs
new file mode 100644 (file)
index 0000000..5b82b7a
--- /dev/null
@@ -0,0 +1,92 @@
+use pin_project_lite::pin_project;
+use std::pin::Pin;
+struct Struct<T, U> {
+    pinned: T,
+    unpinned: U,
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct Projection<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    }
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    struct ProjectionRef<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    }
+    impl<T, U> Struct<T, U> {
+        fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> Projection<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_unchecked_mut();
+                Projection {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> ProjectionRef<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_ref();
+                ProjectionRef {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned: T,
+        unpinned: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    impl<T, U> ::pin_project_lite::__private::Drop for Struct<T, U> {
+        fn drop(&mut self) {
+            fn __drop_inner<T, U>(this: ::pin_project_lite::__private::Pin<&mut Struct<T, U>>) {
+                fn __drop_inner() {}
+                let _ = this;
+            }
+            let pinned_self: ::pin_project_lite::__private::Pin<&mut Self> =
+                unsafe { ::pin_project_lite::__private::Pin::new_unchecked(self) };
+            __drop_inner(pinned_self);
+        }
+    }
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+};
+fn main() {}
diff --git a/tests/expand/pinned_drop/struct.rs b/tests/expand/pinned_drop/struct.rs
new file mode 100644 (file)
index 0000000..0cc7567
--- /dev/null
@@ -0,0 +1,17 @@
+use pin_project_lite::pin_project;
+use std::pin::Pin;
+
+pin_project! {
+    struct Struct<T, U> {
+        #[pin]
+        pinned: T,
+        unpinned: U,
+    }
+    impl<T, U> PinnedDrop for Struct<T, U> {
+        fn drop(this: Pin<&mut Self>) {
+            let _ = this;
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/pub/enum.expanded.rs b/tests/expand/pub/enum.expanded.rs
new file mode 100644 (file)
index 0000000..6f190cb
--- /dev/null
@@ -0,0 +1,87 @@
+use pin_project_lite::pin_project;
+pub enum Enum<T, U> {
+    Struct { pinned: T, unpinned: U },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+pub(crate) enum EnumProj<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        unpinned: &'__pin mut (U),
+    },
+    Unit,
+}
+#[allow(dead_code)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::mut_mut)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::ref_option_ref)]
+#[allow(clippy::type_repetition_in_bounds)]
+pub(crate) enum EnumProjRef<'__pin, T, U>
+where
+    Enum<T, U>: '__pin,
+{
+    Struct {
+        pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        unpinned: &'__pin (U),
+    },
+    Unit,
+}
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    impl<T, U> Enum<T, U> {
+        pub(crate) fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> EnumProj<'__pin, T, U> {
+            unsafe {
+                match self.get_unchecked_mut() {
+                    Self::Struct { pinned, unpinned } => EnumProj::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProj::Unit,
+                }
+            }
+        }
+        pub(crate) fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> EnumProjRef<'__pin, T, U> {
+            unsafe {
+                match self.get_ref() {
+                    Self::Struct { pinned, unpinned } => EnumProjRef::Struct {
+                        pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                        unpinned: unpinned,
+                    },
+                    Self::Unit => EnumProjRef::Unit,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    pub struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        Struct: (T, ::pin_project_lite::__private::AlwaysUnpin<U>),
+        Unit: (),
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Enum<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Enum<T, U> {}
+};
+fn main() {}
diff --git a/tests/expand/pub/enum.rs b/tests/expand/pub/enum.rs
new file mode 100644 (file)
index 0000000..d3968af
--- /dev/null
@@ -0,0 +1,16 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    #[project = EnumProj]
+    #[project_ref = EnumProjRef]
+    pub enum Enum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+}
+
+fn main() {}
diff --git a/tests/expand/pub/struct.expanded.rs b/tests/expand/pub/struct.expanded.rs
new file mode 100644 (file)
index 0000000..7b5826d
--- /dev/null
@@ -0,0 +1,84 @@
+use pin_project_lite::pin_project;
+pub struct Struct<T, U> {
+    pub pinned: T,
+    pub unpinned: U,
+}
+#[allow(explicit_outlives_requirements)]
+#[allow(single_use_lifetimes)]
+#[allow(clippy::unknown_clippy_lints)]
+#[allow(clippy::redundant_pub_crate)]
+#[allow(clippy::used_underscore_binding)]
+const _: () = {
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    pub(crate) struct Projection<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pub pinned: ::pin_project_lite::__private::Pin<&'__pin mut (T)>,
+        pub unpinned: &'__pin mut (U),
+    }
+    #[allow(dead_code)]
+    #[allow(single_use_lifetimes)]
+    #[allow(clippy::unknown_clippy_lints)]
+    #[allow(clippy::mut_mut)]
+    #[allow(clippy::redundant_pub_crate)]
+    #[allow(clippy::ref_option_ref)]
+    #[allow(clippy::type_repetition_in_bounds)]
+    pub(crate) struct ProjectionRef<'__pin, T, U>
+    where
+        Struct<T, U>: '__pin,
+    {
+        pub pinned: ::pin_project_lite::__private::Pin<&'__pin (T)>,
+        pub unpinned: &'__pin (U),
+    }
+    impl<T, U> Struct<T, U> {
+        pub(crate) fn project<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin mut Self>,
+        ) -> Projection<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_unchecked_mut();
+                Projection {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+        pub(crate) fn project_ref<'__pin>(
+            self: ::pin_project_lite::__private::Pin<&'__pin Self>,
+        ) -> ProjectionRef<'__pin, T, U> {
+            unsafe {
+                let Self { pinned, unpinned } = self.get_ref();
+                ProjectionRef {
+                    pinned: ::pin_project_lite::__private::Pin::new_unchecked(pinned),
+                    unpinned: unpinned,
+                }
+            }
+        }
+    }
+    #[allow(non_snake_case)]
+    pub struct __Origin<'__pin, T, U> {
+        __dummy_lifetime: ::pin_project_lite::__private::PhantomData<&'__pin ()>,
+        pinned: T,
+        unpinned: ::pin_project_lite::__private::AlwaysUnpin<U>,
+    }
+    impl<'__pin, T, U> ::pin_project_lite::__private::Unpin for Struct<T, U> where
+        __Origin<'__pin, T, U>: ::pin_project_lite::__private::Unpin
+    {
+    }
+    trait MustNotImplDrop {}
+    #[allow(clippy::drop_bounds, drop_bounds)]
+    impl<T: ::pin_project_lite::__private::Drop> MustNotImplDrop for T {}
+    impl<T, U> MustNotImplDrop for Struct<T, U> {}
+    #[forbid(unaligned_references, safe_packed_borrows)]
+    fn __assert_not_repr_packed<T, U>(this: &Struct<T, U>) {
+        let _ = &this.pinned;
+        let _ = &this.unpinned;
+    }
+};
+fn main() {}
diff --git a/tests/expand/pub/struct.rs b/tests/expand/pub/struct.rs
new file mode 100644 (file)
index 0000000..6659096
--- /dev/null
@@ -0,0 +1,11 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    pub struct Struct<T, U> {
+        #[pin]
+        pub pinned: T,
+        pub unpinned: U,
+    }
+}
+
+fn main() {}
diff --git a/tests/expandtest.rs b/tests/expandtest.rs
new file mode 100644 (file)
index 0000000..3f0d5c1
--- /dev/null
@@ -0,0 +1,43 @@
+#![cfg(not(miri))]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+use std::{
+    env,
+    process::{Command, ExitStatus, Stdio},
+};
+
+const PATH: &str = "tests/expand/**/*.rs";
+
+#[rustversion::attr(not(nightly), ignore)]
+#[test]
+fn expandtest() {
+    let is_ci = env::var_os("CI").is_some();
+    let cargo = &*env::var("CARGO").unwrap_or_else(|_| "cargo".into());
+    if !has_command(&[cargo, "expand"]) || !has_command(&[cargo, "fmt"]) {
+        if is_ci {
+            panic!("expandtest requires rustfmt and cargo-expand");
+        }
+        return;
+    }
+
+    let args = &["--all-features"];
+    if is_ci {
+        macrotest::expand_without_refresh_args(PATH, args);
+    } else {
+        env::set_var("MACROTEST", "overwrite");
+        macrotest::expand_args(PATH, args);
+    }
+}
+
+fn has_command(command: &[&str]) -> bool {
+    Command::new(command[0])
+        .args(&command[1..])
+        .arg("--version")
+        .stdin(Stdio::null())
+        .stdout(Stdio::null())
+        .stderr(Stdio::null())
+        .status()
+        .as_ref()
+        .map(ExitStatus::success)
+        .unwrap_or(false)
+}
diff --git a/tests/include/basic.rs b/tests/include/basic.rs
new file mode 100644 (file)
index 0000000..25121f2
--- /dev/null
@@ -0,0 +1,35 @@
+// default pin_project! is completely safe.
+
+::pin_project_lite::pin_project! {
+    #[derive(Debug)]
+    pub struct DefaultStruct<T, U> {
+        #[pin]
+        pub pinned: T,
+        pub unpinned: U,
+    }
+}
+
+::pin_project_lite::pin_project! {
+    #[project = DefaultStructProj]
+    #[project_ref = DefaultStructProjRef]
+    #[derive(Debug)]
+    pub struct DefaultStructNamed<T, U> {
+        #[pin]
+        pub pinned: T,
+        pub unpinned: U,
+    }
+}
+
+::pin_project_lite::pin_project! {
+    #[project = DefaultEnumProj]
+    #[project_ref = DefaultEnumProjRef]
+    #[derive(Debug)]
+    pub enum DefaultEnum<T, U> {
+        Struct {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        },
+        Unit,
+    }
+}
diff --git a/tests/lint.rs b/tests/lint.rs
new file mode 100644 (file)
index 0000000..852f940
--- /dev/null
@@ -0,0 +1,263 @@
+// Check interoperability with rustc and clippy lints.
+
+#![forbid(unsafe_code)]
+// for old compilers
+#![allow(unknown_lints)]
+#![warn(nonstandard_style, rust_2018_idioms, 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, rust_2021_compatibility)]
+// lints forbidden as a part of future_incompatible, rust_2018_compatibility, and rust_2021_compatibility are not included in the list below.
+// elided_lifetimes_in_paths, explicit_outlives_requirements, unused_extern_crates:  as a part of rust_2018_idioms
+// unsafe_op_in_unsafe_fn: requires Rust 1.52. and, we don't generate unsafe fn.
+// non_exhaustive_omitted_patterns: unstable
+// unstable_features: no way to generate #![feature(..)] by macros, expect for unstable inner attribute. and this lint is deprecated: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#unstable-features
+// unused_crate_dependencies, must_not_suspend: unrelated
+// unsafe_code: checked in forbid_unsafe module
+#![warn(
+    box_pointers,
+    deprecated_in_future,
+    fuzzy_provenance_casts,
+    lossy_provenance_casts,
+    macro_use_extern_crate,
+    meta_variable_misuse,
+    missing_abi,
+    missing_copy_implementations,
+    missing_debug_implementations,
+    missing_docs,
+    non_ascii_idents,
+    noop_method_call,
+    single_use_lifetimes,
+    trivial_casts,
+    trivial_numeric_casts,
+    unreachable_pub,
+    unused_import_braces,
+    unused_lifetimes,
+    unused_qualifications,
+    unused_results,
+    variant_size_differences
+)]
+#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::restriction)]
+#![allow(clippy::blanket_clippy_restriction_lints)] // this is a test, so enable all restriction lints intentionally.
+#![allow(clippy::exhaustive_structs, clippy::exhaustive_enums, clippy::single_char_lifetime_names)] // TODO
+
+pub mod basic {
+    include!("include/basic.rs");
+}
+
+pub mod box_pointers {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        #[derive(Debug)]
+        pub struct Struct {
+            #[pin]
+            pub p: Box<isize>,
+            pub u: Box<isize>,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[derive(Debug)]
+        pub enum Enum {
+            Struct {
+                #[pin]
+                p: Box<isize>,
+                u: Box<isize>,
+            },
+            Unit,
+        }
+    }
+}
+
+pub mod explicit_outlives_requirements {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        #[derive(Debug)]
+        pub struct Struct<'a, T, U>
+        where
+            T: ?Sized,
+            U: ?Sized,
+        {
+            #[pin]
+            pub pinned: &'a mut T,
+            pub unpinned: &'a mut U,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[derive(Debug)]
+        pub enum Enum<'a, T, U>
+        where
+            T: ?Sized,
+            U: ?Sized,
+        {
+            Struct {
+                #[pin]
+                pinned: &'a mut T,
+                unpinned: &'a mut U,
+            },
+            Unit,
+        }
+    }
+}
+
+pub mod variant_size_differences {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[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
+        pub enum Enum {
+            V1 { f: u8 },
+            V2 { f: [u8; 1024] },
+        }
+    }
+}
+
+pub mod clippy_mut_mut {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        #[derive(Debug)]
+        pub struct Struct<'a, T, U> {
+            #[pin]
+            pub pinned: &'a mut T,
+            pub unpinned: &'a mut U,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[derive(Debug)]
+        pub enum Enum<'a, T, U> {
+            Struct {
+                #[pin]
+                pinned: &'a mut T,
+                unpinned: &'a mut U,
+            },
+            Unit,
+        }
+    }
+}
+
+#[allow(unreachable_pub)]
+mod clippy_redundant_pub_crate {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        #[derive(Debug)]
+        pub struct Struct<T, U> {
+            #[pin]
+            pub pinned: T,
+            pub unpinned: U,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[derive(Debug)]
+        pub enum Enum<T, U> {
+            Struct {
+                #[pin]
+                pinned: T,
+                unpinned: U,
+            },
+            Unit,
+        }
+    }
+}
+
+#[allow(clippy::use_self)]
+pub mod clippy_type_repetition_in_bounds {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        #[derive(Debug)]
+        pub struct Struct<T, U>
+        where
+            Struct<T, U>: Sized,
+        {
+            #[pin]
+            pub pinned: T,
+            pub unpinned: U,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[derive(Debug)]
+        pub enum Enum<T, U>
+        where
+            Enum<T, U>: Sized,
+        {
+            Struct {
+                #[pin]
+                pinned: T,
+                unpinned: U,
+            },
+            Unit,
+        }
+    }
+}
+
+pub mod clippy_used_underscore_binding {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        #[derive(Debug)]
+        pub struct Struct<T, U> {
+            #[pin]
+            pub _pinned: T,
+            pub _unpinned: U,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[derive(Debug)]
+        pub enum Enum<T, U> {
+            Struct {
+                #[pin]
+                _pinned: T,
+                _unpinned: U,
+            },
+        }
+    }
+}
+
+pub mod clippy_ref_option_ref {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        pub struct Struct<'a> {
+            #[pin]
+            pub _pinned: Option<&'a ()>,
+            pub _unpinned: Option<&'a ()>,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        pub enum Enum<'a> {
+            Struct {
+                #[pin]
+                _pinned: Option<&'a ()>,
+                _unpinned: Option<&'a ()>,
+            },
+        }
+    }
+}
diff --git a/tests/proper_unpin.rs b/tests/proper_unpin.rs
new file mode 100644 (file)
index 0000000..668e975
--- /dev/null
@@ -0,0 +1,67 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+#[macro_use]
+mod auxiliary;
+
+pub mod default {
+    use std::marker::PhantomPinned;
+
+    use pin_project_lite::pin_project;
+
+    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>);
+}
diff --git a/tests/test.rs b/tests/test.rs
new file mode 100644 (file)
index 0000000..ed9b75c
--- /dev/null
@@ -0,0 +1,695 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+#[macro_use]
+mod auxiliary;
+
+use core::{
+    marker::{PhantomData, PhantomPinned},
+    pin::Pin,
+};
+
+use pin_project_lite::pin_project;
+
+#[test]
+fn projection() {
+    pin_project! {
+        #[project = StructProj]
+        #[project_ref = StructProjRef]
+        #[project_replace = StructProjReplace]
+        #[derive(Default)]
+        struct Struct<T, U> {
+            #[pin]
+            f1: T,
+            f2: U,
+        }
+    }
+
+    let mut s = Struct { f1: 1, f2: 2 };
+    let mut s_orig = Pin::new(&mut s);
+    let s = s_orig.as_mut().project();
+
+    let _: Pin<&mut i32> = s.f1;
+    assert_eq!(*s.f1, 1);
+    let _: &mut i32 = s.f2;
+    assert_eq!(*s.f2, 2);
+
+    assert_eq!(s_orig.as_ref().f1, 1);
+    assert_eq!(s_orig.as_ref().f2, 2);
+
+    let mut s = Struct { f1: 1, f2: 2 };
+    let mut s = Pin::new(&mut s);
+    {
+        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 StructProjReplace { f1: PhantomData, f2 } =
+            s.as_mut().project_replace(Struct::default());
+        assert_eq!(f2, 2);
+        let StructProj { f1, f2 } = s.project();
+        assert_eq!(*f1, 0);
+        assert_eq!(*f2, 0);
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[project_replace = EnumProjReplace]
+        #[derive(Eq, PartialEq, Debug)]
+        enum Enum<C, D> {
+            Struct {
+                #[pin]
+                f1: C,
+                f2: D,
+            },
+            Unit,
+        }
+    }
+
+    let mut e = Enum::Struct { f1: 1, f2: 2 };
+    let mut e = Pin::new(&mut e);
+
+    match e.as_mut().project() {
+        EnumProj::Struct { f1, f2 } => {
+            let _: Pin<&mut i32> = f1;
+            assert_eq!(*f1, 1);
+            let _: &mut i32 = f2;
+            assert_eq!(*f2, 2);
+        }
+        EnumProj::Unit => unreachable!(),
+    }
+
+    assert_eq!(&*e, &Enum::Struct { f1: 1, f2: 2 });
+
+    if let EnumProj::Struct { f1, f2 } = e.as_mut().project() {
+        let _: Pin<&mut i32> = f1;
+        assert_eq!(*f1, 1);
+        let _: &mut i32 = f2;
+        assert_eq!(*f2, 2);
+    }
+
+    if let EnumProjReplace::Struct { f1: PhantomData, f2 } = e.as_mut().project_replace(Enum::Unit)
+    {
+        assert_eq!(f2, 2);
+    }
+}
+
+#[test]
+fn enum_project_set() {
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        #[derive(Eq, PartialEq, Debug)]
+        enum Enum {
+            V1 { #[pin] f: u8 },
+            V2 { f: bool },
+        }
+    }
+
+    let mut e = Enum::V1 { f: 25 };
+    let mut e_orig = Pin::new(&mut e);
+    let e_proj = e_orig.as_mut().project();
+
+    match e_proj {
+        EnumProj::V1 { f } => {
+            let new_e = Enum::V2 { f: f.as_ref().get_ref() == &25 };
+            e_orig.set(new_e);
+        }
+        EnumProj::V2 { .. } => unreachable!(),
+    }
+
+    assert_eq!(e, Enum::V2 { f: true });
+}
+
+#[test]
+fn where_clause() {
+    pin_project! {
+        struct Struct<T>
+        where
+            T: Copy,
+        {
+            f: T,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        enum Enum<T>
+        where
+            T: Copy,
+        {
+            V { f: T },
+        }
+    }
+}
+
+#[test]
+fn where_clause_and_associated_type_field() {
+    pin_project! {
+        struct Struct1<I>
+        where
+            I: Iterator,
+        {
+            #[pin]
+            f1: I,
+            f2: I::Item,
+        }
+    }
+
+    pin_project! {
+        struct Struct2<I, J>
+        where
+            I: Iterator<Item = J>,
+        {
+            #[pin]
+            f1: I,
+            f2: J,
+        }
+    }
+
+    pin_project! {
+        pub struct Struct3<T>
+        where
+            T: 'static,
+        {
+            f: T,
+        }
+    }
+
+    trait Static: 'static {}
+
+    impl<T> Static for Struct3<T> {}
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        enum Enum<I>
+        where
+            I: Iterator,
+        {
+            V1 { #[pin] f: I },
+            V2 { f: I::Item },
+        }
+    }
+}
+
+#[test]
+fn derive_copy() {
+    pin_project! {
+        #[derive(Clone, Copy)]
+        struct Struct<T> {
+            f: T,
+        }
+    }
+
+    fn is_copy<T: Copy>() {}
+
+    is_copy::<Struct<u8>>();
+}
+
+#[test]
+fn move_out() {
+    struct NotCopy;
+
+    pin_project! {
+        struct Struct {
+            f: NotCopy,
+        }
+    }
+
+    let x = Struct { f: NotCopy };
+    let _val: NotCopy = x.f;
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        enum Enum {
+            V { f: NotCopy },
+        }
+    }
+
+    let x = Enum::V { f: NotCopy };
+    #[allow(clippy::infallible_destructuring_match)]
+    let _val: NotCopy = match x {
+        Enum::V { f } => f,
+    };
+}
+
+#[test]
+fn trait_bounds_on_type_generics() {
+    pin_project! {
+        pub struct Struct1<'a, T: ?Sized> {
+            f: &'a mut T,
+        }
+    }
+
+    pin_project! {
+        pub struct Struct2<'a, T: ::core::fmt::Debug> {
+            f: &'a mut T,
+        }
+    }
+
+    pin_project! {
+        pub struct Struct3<'a, T: core::fmt::Debug> {
+            f: &'a mut T,
+        }
+    }
+
+    // pin_project! {
+    //     pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {
+    //         f: &'a mut T,
+    //     }
+    // }
+
+    // pin_project! {
+    //     pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {
+    //         f: &'a mut T,
+    //     }
+    // }
+
+    pin_project! {
+        pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {
+            f: &'a mut T,
+        }
+    }
+
+    let _: Struct6<'_> = Struct6 { f: &mut [0_u8; 16] };
+
+    pin_project! {
+        pub struct Struct7<T: 'static> {
+            f: T,
+        }
+    }
+
+    trait Static: 'static {}
+
+    impl<T> Static for Struct7<T> {}
+
+    pin_project! {
+        pub struct Struct8<'a, 'b: 'a> {
+            f1: &'a u8,
+            f2: &'b u8,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        enum Enum<'a, T: ?Sized> {
+            V { f: &'a mut T },
+        }
+    }
+}
+
+#[test]
+fn private_type_in_public_type() {
+    pin_project! {
+        pub struct PublicStruct<T> {
+            #[pin]
+            inner: PrivateStruct<T>,
+        }
+    }
+
+    struct PrivateStruct<T>(T);
+}
+
+#[allow(clippy::needless_lifetimes)]
+#[test]
+fn lifetime_project() {
+    pin_project! {
+        struct Struct1<T, U> {
+            #[pin]
+            pinned: T,
+            unpinned: U,
+        }
+    }
+
+    pin_project! {
+        struct Struct2<'a, T, U> {
+            #[pin]
+            pinned: &'a T,
+            unpinned: U,
+        }
+    }
+
+    pin_project! {
+        #[project = EnumProj]
+        #[project_ref = EnumProjRef]
+        enum Enum<T, U> {
+            V {
+                #[pin]
+                pinned: T,
+                unpinned: U,
+            },
+        }
+    }
+
+    impl<T, U> Struct1<T, U> {
+        fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> {
+            self.project_ref().pinned
+        }
+        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 T> {
+            self.project_ref().pinned
+        }
+        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
+        }
+    }
+
+    impl<T, U> Enum<T, U> {
+        fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a T> {
+            match self.project_ref() {
+                EnumProjRef::V { pinned, .. } => pinned,
+            }
+        }
+        fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> {
+            match self.project() {
+                EnumProj::V { pinned, .. } => pinned,
+            }
+        }
+        fn get_pin_ref_elided(self: Pin<&Self>) -> Pin<&T> {
+            match self.project_ref() {
+                EnumProjRef::V { pinned, .. } => pinned,
+            }
+        }
+        fn get_pin_mut_elided(self: Pin<&mut Self>) -> Pin<&mut T> {
+            match self.project() {
+                EnumProj::V { pinned, .. } => pinned,
+            }
+        }
+    }
+}
+
+mod visibility {
+    use pin_project_lite::pin_project;
+
+    pin_project! {
+        pub(crate) struct S {
+            pub f: u8,
+        }
+    }
+}
+
+#[test]
+fn visibility() {
+    let mut x = visibility::S { f: 0 };
+    let x = Pin::new(&mut x);
+    let y = x.as_ref().project_ref();
+    let _: &u8 = y.f;
+    let y = x.project();
+    let _: &mut u8 = y.f;
+}
+
+#[test]
+fn trivial_bounds() {
+    pin_project! {
+        pub struct NoGenerics {
+            #[pin]
+            f: PhantomPinned,
+        }
+    }
+
+    assert_not_unpin!(NoGenerics);
+}
+
+#[test]
+fn dst() {
+    pin_project! {
+        pub struct Struct1<T: ?Sized> {
+            f: T,
+        }
+    }
+
+    let mut x = Struct1 { f: 0_u8 };
+    let x: Pin<&mut Struct1<dyn core::fmt::Debug>> = Pin::new(&mut x as _);
+    let _: &mut (dyn core::fmt::Debug) = x.project().f;
+
+    pin_project! {
+        pub struct Struct2<T: ?Sized> {
+            #[pin]
+            f: T,
+        }
+    }
+
+    let mut x = Struct2 { f: 0_u8 };
+    let x: Pin<&mut Struct2<dyn core::fmt::Debug + Unpin>> = Pin::new(&mut x as _);
+    let _: Pin<&mut (dyn core::fmt::Debug + Unpin)> = x.project().f;
+
+    pin_project! {
+        struct Struct3<T>
+        where
+            T: ?Sized,
+        {
+            f: T,
+        }
+    }
+
+    pin_project! {
+        struct Struct4<T>
+        where
+            T: ?Sized,
+        {
+            #[pin]
+            f: T,
+        }
+    }
+
+    pin_project! {
+        struct Struct11<'a, T: ?Sized, U: ?Sized> {
+            f1: &'a mut T,
+            f2: U,
+        }
+    }
+}
+
+#[test]
+fn dyn_type() {
+    pin_project! {
+        struct Struct1 {
+            f: dyn core::fmt::Debug,
+        }
+    }
+
+    pin_project! {
+        struct Struct2 {
+            #[pin]
+            f: dyn core::fmt::Debug,
+        }
+    }
+
+    pin_project! {
+        struct Struct3 {
+            f: dyn core::fmt::Debug + Send,
+        }
+    }
+
+    pin_project! {
+        struct Struct4 {
+            #[pin]
+            f: dyn core::fmt::Debug + Send,
+        }
+    }
+}
+
+#[test]
+fn no_infer_outlives() {
+    trait Trait<X> {
+        type Y;
+    }
+
+    struct Struct1<A>(A);
+
+    impl<X, T> Trait<X> for Struct1<T> {
+        type Y = Option<T>;
+    }
+
+    pin_project! {
+        struct Struct2<A, B> {
+            _f: <Struct1<A> as Trait<B>>::Y,
+        }
+    }
+}
+
+// https://github.com/taiki-e/pin-project-lite/issues/31
+#[test]
+fn trailing_comma() {
+    pub trait T {}
+
+    pin_project! {
+        pub struct S1<
+            A: T,
+            B: T,
+        > {
+            f: (A, B),
+        }
+    }
+
+    pin_project! {
+        pub struct S2<
+            A,
+            B,
+        >
+        where
+            A: T,
+            B: T,
+        {
+            f: (A, B),
+        }
+    }
+
+    pin_project! {
+        #[allow(explicit_outlives_requirements)]
+        pub struct S3<
+            'a,
+            A: 'a,
+            B: 'a,
+        > {
+            f: &'a (A, B),
+        }
+    }
+
+    // pin_project! {
+    //     pub struct S4<
+    //         'a,
+    //         'b: 'a, // <-----
+    //     > {
+    //         f: &'a &'b (),
+    //     }
+    // }
+}
+
+#[test]
+fn attrs() {
+    pin_project! {
+        /// dox1
+        #[derive(Clone)]
+        #[project = StructProj]
+        #[project_ref = StructProjRef]
+        /// dox2
+        #[derive(Debug)]
+        /// dox3
+        struct Struct {
+            // TODO
+            // /// dox4
+            f: ()
+        }
+    }
+
+    pin_project! {
+        #[project = Enum1Proj]
+        #[project_ref = Enum1ProjRef]
+        enum Enum1 {
+            #[cfg(not(any()))]
+            V {
+                f: ()
+            },
+        }
+    }
+
+    pin_project! {
+        /// dox1
+        #[derive(Clone)]
+        #[project = Enum2Proj]
+        #[project_ref = Enum2ProjRef]
+        /// dox2
+        #[derive(Debug)]
+        /// dox3
+        enum Enum2 {
+            /// dox4
+            V1 {
+                // TODO
+                // /// dox5
+                f: ()
+            },
+            /// dox6
+            V2,
+        }
+    }
+}
+
+#[test]
+fn pinned_drop() {
+    pin_project! {
+        pub struct Struct1<'a> {
+            was_dropped: &'a mut bool,
+            #[pin]
+            field: u8,
+        }
+        impl PinnedDrop for Struct1<'_> {
+            fn drop(this: Pin<&mut Self>) {
+                **this.project().was_dropped = true;
+            }
+        }
+    }
+
+    let mut was_dropped = false;
+    drop(Struct1 { was_dropped: &mut was_dropped, field: 42 });
+    assert!(was_dropped);
+
+    pin_project! {
+        pub struct Struct2<'a> {
+            was_dropped: &'a mut bool,
+            #[pin]
+            field: u8,
+        }
+        impl PinnedDrop for Struct2<'_> {
+            fn drop(mut this: Pin<&mut Self>) {
+                **this.as_mut().project().was_dropped = true;
+            }
+        }
+    }
+
+    trait Service<Request> {
+        type Error;
+    }
+
+    pin_project! {
+        struct Struct3<'a, T, Request>
+        where
+            T: Service<Request>,
+            T::Error: std::error::Error,
+        {
+            was_dropped: &'a mut bool,
+            #[pin]
+            field: T,
+            req: Request,
+        }
+
+        impl<T, Request> PinnedDrop for Struct3<'_, T, Request>
+        where
+            T: Service<Request>,
+            T::Error: std::error::Error,
+        {
+            fn drop(mut this: Pin<&mut Self>) {
+                **this.as_mut().project().was_dropped = true;
+            }
+        }
+    }
+}
diff --git a/tests/ui/pin_project/conflict-drop.rs b/tests/ui/pin_project/conflict-drop.rs
new file mode 100644 (file)
index 0000000..870059d
--- /dev/null
@@ -0,0 +1,15 @@
+use pin_project_lite::pin_project;
+
+pin_project! { //~ ERROR E0119
+    struct Foo<T, U> {
+        #[pin]
+        future: T,
+        field: U,
+    }
+}
+
+impl<T, U> Drop for Foo<T, U> {
+    fn drop(&mut self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/conflict-drop.stderr b/tests/ui/pin_project/conflict-drop.stderr
new file mode 100644 (file)
index 0000000..66872bd
--- /dev/null
@@ -0,0 +1,16 @@
+error[E0119]: conflicting implementations of trait `_::MustNotImplDrop` for type `Foo<_, _>`
+ --> tests/ui/pin_project/conflict-drop.rs:3:1
+  |
+3 | / pin_project! { //~ ERROR E0119
+4 | |     struct Foo<T, U> {
+5 | |         #[pin]
+6 | |         future: T,
+7 | |         field: U,
+8 | |     }
+9 | | }
+  | | ^
+  | | |
+  | |_first implementation here
+  |   conflicting implementation for `Foo<_, _>`
+  |
+  = note: this error originates in the macro `$crate::__pin_project_make_drop_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pin_project/conflict-unpin.rs b/tests/ui/pin_project/conflict-unpin.rs
new file mode 100644 (file)
index 0000000..f702f06
--- /dev/null
@@ -0,0 +1,40 @@
+use pin_project_lite::pin_project;
+
+// The same implementation.
+
+pin_project! { //~ ERROR E0119
+    struct Foo<T, U> {
+        #[pin]
+        future: T,
+        field: U,
+    }
+}
+
+// conflicting implementations
+impl<T, U> Unpin for Foo<T, U> where T: Unpin {} // Conditional Unpin impl
+
+// The implementation that under different conditions.
+
+pin_project! { //~ ERROR E0119
+    struct Bar<T, U> {
+        #[pin]
+        future: T,
+        field: U,
+    }
+}
+
+// conflicting implementations
+impl<T, U> Unpin for Bar<T, U> {} // Non-conditional Unpin impl
+
+pin_project! { //~ ERROR E0119
+    struct Baz<T, U> {
+        #[pin]
+        future: T,
+        field: U,
+    }
+}
+
+// conflicting implementations
+impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {} // Conditional Unpin impl
+
+fn main() {}
diff --git a/tests/ui/pin_project/conflict-unpin.stderr b/tests/ui/pin_project/conflict-unpin.stderr
new file mode 100644 (file)
index 0000000..bd30faf
--- /dev/null
@@ -0,0 +1,50 @@
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_, _>`
+  --> tests/ui/pin_project/conflict-unpin.rs:5:1
+   |
+5  | / pin_project! { //~ ERROR E0119
+6  | |     struct Foo<T, U> {
+7  | |         #[pin]
+8  | |         future: T,
+9  | |         field: U,
+10 | |     }
+11 | | }
+   | |_^ conflicting implementation for `Foo<_, _>`
+...
+14 |   impl<T, U> Unpin for Foo<T, U> where T: Unpin {} // Conditional Unpin impl
+   |   --------------------------------------------- first implementation here
+   |
+   = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Bar<_, _>`
+  --> tests/ui/pin_project/conflict-unpin.rs:18:1
+   |
+18 | / pin_project! { //~ ERROR E0119
+19 | |     struct Bar<T, U> {
+20 | |         #[pin]
+21 | |         future: T,
+22 | |         field: U,
+23 | |     }
+24 | | }
+   | |_^ conflicting implementation for `Bar<_, _>`
+...
+27 |   impl<T, U> Unpin for Bar<T, U> {} // Non-conditional Unpin impl
+   |   ------------------------------ first implementation here
+   |
+   = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Baz<_, _>`
+  --> tests/ui/pin_project/conflict-unpin.rs:29:1
+   |
+29 | / pin_project! { //~ ERROR E0119
+30 | |     struct Baz<T, U> {
+31 | |         #[pin]
+32 | |         future: T,
+33 | |         field: U,
+34 | |     }
+35 | | }
+   | |_^ conflicting implementation for `Baz<_, _>`
+...
+38 |   impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {} // Conditional Unpin impl
+   |   -------------------------------------------- first implementation here
+   |
+   = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pin_project/invalid-bounds.rs b/tests/ui/pin_project/invalid-bounds.rs
new file mode 100644 (file)
index 0000000..64b397a
--- /dev/null
@@ -0,0 +1,93 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct Generics1<T: 'static : Sized> { //~ ERROR no rules expected the token `:`
+        field: T,
+    }
+}
+
+pin_project! {
+    struct Generics2<T: 'static : ?Sized> { //~ ERROR no rules expected the token `:`
+        field: T,
+    }
+}
+
+pin_project! {
+    struct Generics3<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+        field: T,
+    }
+}
+
+pin_project! {
+    struct Generics4<T: ?Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+        field: T,
+    }
+}
+
+pin_project! {
+    struct Generics5<T: Sized : ?Sized> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+        field: T,
+    }
+}
+
+pin_project! {
+    struct Generics6<T: ?Sized : Sized> { //~ ERROR no rules expected the token `Sized`
+        field: T,
+    }
+}
+
+pin_project! {
+    struct WhereClause1<T>
+    where
+        T: 'static : Sized //~ ERROR no rules expected the token `:`
+    {
+        field: T,
+    }
+}
+
+pin_project! {
+    struct WhereClause2<T>
+    where
+        T: 'static : ?Sized //~ ERROR no rules expected the token `:`
+    {
+        field: T,
+    }
+}
+
+pin_project! {
+    struct WhereClause3<T>
+    where
+        T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+    {
+        field: T,
+    }
+}
+
+pin_project! {
+    struct WhereClause4<T>
+    where
+        T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+    {
+        field: T,
+    }
+}
+
+pin_project! {
+    struct WhereClause5<T>
+    where
+        T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:`
+    {
+        field: T,
+    }
+}
+
+pin_project! {
+    struct WhereClause6<T>
+    where
+        T: ?Sized : Sized //~ ERROR no rules expected the token `Sized`
+    {
+        field: T,
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/invalid-bounds.stderr b/tests/ui/pin_project/invalid-bounds.stderr
new file mode 100644 (file)
index 0000000..40e79bf
--- /dev/null
@@ -0,0 +1,428 @@
+error: no rules expected the token `:`
+ --> tests/ui/pin_project/invalid-bounds.rs:4:33
+  |
+4 |     struct Generics1<T: 'static : Sized> { //~ ERROR no rules expected the token `:`
+  |                                 ^ no rules expected this token in macro call
+
+error: no rules expected the token `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:10:33
+   |
+10 |     struct Generics2<T: 'static : ?Sized> { //~ ERROR no rules expected the token `:`
+   |                                 ^ no rules expected this token in macro call
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:15:1
+   |
+15 | / pin_project! {
+16 | |     struct Generics3<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+17 | |         field: T,
+18 | |     }
+19 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:15:1
+   |
+15 | / pin_project! {
+16 | |     struct Generics3<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+17 | |         field: T,
+18 | |     }
+19 | | }
+   | | ^
+   | | |
+   | |_expected one of `+`, `,`, `=`, or `>`
+   |   unexpected token
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:15:1
+   |
+15 | / pin_project! {
+16 | |     struct Generics3<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+17 | |         field: T,
+18 | |     }
+19 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:15:1
+   |
+15 | / pin_project! {
+16 | |     struct Generics3<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+17 | |         field: T,
+18 | |     }
+19 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:21:1
+   |
+21 | / pin_project! {
+22 | |     struct Generics4<T: ?Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+23 | |         field: T,
+24 | |     }
+25 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:21:1
+   |
+21 | / pin_project! {
+22 | |     struct Generics4<T: ?Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+23 | |         field: T,
+24 | |     }
+25 | | }
+   | | ^
+   | | |
+   | |_expected one of `+`, `,`, `=`, or `>`
+   |   unexpected token
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:21:1
+   |
+21 | / pin_project! {
+22 | |     struct Generics4<T: ?Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+23 | |         field: T,
+24 | |     }
+25 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:21:1
+   |
+21 | / pin_project! {
+22 | |     struct Generics4<T: ?Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+23 | |         field: T,
+24 | |     }
+25 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:27:1
+   |
+27 | / pin_project! {
+28 | |     struct Generics5<T: Sized : ?Sized> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+29 | |         field: T,
+30 | |     }
+31 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:27:1
+   |
+27 | / pin_project! {
+28 | |     struct Generics5<T: Sized : ?Sized> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+29 | |         field: T,
+30 | |     }
+31 | | }
+   | | ^
+   | | |
+   | |_expected one of `+`, `,`, `=`, or `>`
+   |   unexpected token
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:27:1
+   |
+27 | / pin_project! {
+28 | |     struct Generics5<T: Sized : ?Sized> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+29 | |         field: T,
+30 | |     }
+31 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:27:1
+   |
+27 | / pin_project! {
+28 | |     struct Generics5<T: Sized : ?Sized> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+29 | |         field: T,
+30 | |     }
+31 | | }
+   | | ^
+   | | |
+   | | expected one of `+`, `,`, `=`, or `>`
+   | |_unexpected token
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `Sized`
+  --> tests/ui/pin_project/invalid-bounds.rs:34:34
+   |
+34 |     struct Generics6<T: ?Sized : Sized> { //~ ERROR no rules expected the token `Sized`
+   |                                  ^^^^^ no rules expected this token in macro call
+
+error: no rules expected the token `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:42:20
+   |
+42 |         T: 'static : Sized //~ ERROR no rules expected the token `:`
+   |                    ^ no rules expected this token in macro call
+
+error: no rules expected the token `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:51:20
+   |
+51 |         T: 'static : ?Sized //~ ERROR no rules expected the token `:`
+   |                    ^ no rules expected this token in macro call
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:57:1
+   |
+57 | / pin_project! {
+58 | |     struct WhereClause3<T>
+59 | |     where
+60 | |         T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+63 | |     }
+64 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, or `{`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:57:1
+   |
+57 | / pin_project! {
+58 | |     struct WhereClause3<T>
+59 | |     where
+60 | |         T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+63 | |     }
+64 | | }
+   | | ^
+   | | |
+   | |_expected one of `+`, `,`, or `{`
+   |   unexpected token
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:57:1
+   |
+57 | / pin_project! {
+58 | |     struct WhereClause3<T>
+59 | |     where
+60 | |         T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+63 | |     }
+64 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:57:1
+   |
+57 | / pin_project! {
+58 | |     struct WhereClause3<T>
+59 | |     where
+60 | |         T: Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+63 | |     }
+64 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:66:1
+   |
+66 | / pin_project! {
+67 | |     struct WhereClause4<T>
+68 | |     where
+69 | |         T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+72 | |     }
+73 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, or `{`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:66:1
+   |
+66 | / pin_project! {
+67 | |     struct WhereClause4<T>
+68 | |     where
+69 | |         T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+72 | |     }
+73 | | }
+   | | ^
+   | | |
+   | |_expected one of `+`, `,`, or `{`
+   |   unexpected token
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:66:1
+   |
+66 | / pin_project! {
+67 | |     struct WhereClause4<T>
+68 | |     where
+69 | |         T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+72 | |     }
+73 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:66:1
+   |
+66 | / pin_project! {
+67 | |     struct WhereClause4<T>
+68 | |     where
+69 | |         T: ?Sized : 'static //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+72 | |     }
+73 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:75:1
+   |
+75 | / pin_project! {
+76 | |     struct WhereClause5<T>
+77 | |     where
+78 | |         T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+81 | |     }
+82 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected one of `+`, `,`, or `{`, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:75:1
+   |
+75 | / pin_project! {
+76 | |     struct WhereClause5<T>
+77 | |     where
+78 | |         T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+81 | |     }
+82 | | }
+   | | ^
+   | | |
+   | |_expected one of `+`, `,`, or `{`
+   |   unexpected token
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:75:1
+   |
+75 | / pin_project! {
+76 | |     struct WhereClause5<T>
+77 | |     where
+78 | |         T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+81 | |     }
+82 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: expected `{` after struct name, found `:`
+  --> tests/ui/pin_project/invalid-bounds.rs:75:1
+   |
+75 | / pin_project! {
+76 | |     struct WhereClause5<T>
+77 | |     where
+78 | |         T: Sized : ?Sized //~ ERROR expected `where`, or `{` after struct name, found `:`
+...  |
+81 | |     }
+82 | | }
+   | | ^
+   | | |
+   | |_expected `{` after struct name
+   |   in this macro invocation
+   |
+   = note: this error originates in the macro `$crate::__pin_project_parse_generics` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `Sized`
+  --> tests/ui/pin_project/invalid-bounds.rs:87:21
+   |
+87 |         T: ?Sized : Sized //~ ERROR no rules expected the token `Sized`
+   |                     ^^^^^ no rules expected this token in macro call
diff --git a/tests/ui/pin_project/invalid.rs b/tests/ui/pin_project/invalid.rs
new file mode 100644 (file)
index 0000000..e0ea61d
--- /dev/null
@@ -0,0 +1,25 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct A<T> {
+        #[pin()] //~ ERROR no rules expected the token `(`
+        pinned: T,
+    }
+}
+
+pin_project! {
+    #[pin] //~ ERROR cannot find attribute `pin` in this scope
+    struct B<T> {
+        pinned: T,
+    }
+}
+
+pin_project! {
+    struct C<T> {
+        #[pin]
+        #[pin] //~ ERROR no rules expected the token `#`
+        pinned: T,
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/invalid.stderr b/tests/ui/pin_project/invalid.stderr
new file mode 100644 (file)
index 0000000..623a886
--- /dev/null
@@ -0,0 +1,59 @@
+error: no rules expected the token `struct`
+ --> tests/ui/pin_project/invalid.rs:3:1
+  |
+3 | / pin_project! {
+4 | |     struct A<T> {
+5 | |         #[pin()] //~ ERROR no rules expected the token `(`
+6 | |         pinned: T,
+7 | |     }
+8 | | }
+  | |_^ no rules expected this token in macro call
+  |
+  = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `struct`
+ --> tests/ui/pin_project/invalid.rs:3:1
+  |
+3 | / pin_project! {
+4 | |     struct A<T> {
+5 | |         #[pin()] //~ ERROR no rules expected the token `(`
+6 | |         pinned: T,
+7 | |     }
+8 | | }
+  | |_^ no rules expected this token in macro call
+  |
+  = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `struct`
+  --> tests/ui/pin_project/invalid.rs:17:1
+   |
+17 | / pin_project! {
+18 | |     struct C<T> {
+19 | |         #[pin]
+20 | |         #[pin] //~ ERROR no rules expected the token `#`
+21 | |         pinned: T,
+22 | |     }
+23 | | }
+   | |_^ no rules expected this token in macro call
+   |
+   = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `struct`
+  --> tests/ui/pin_project/invalid.rs:17:1
+   |
+17 | / pin_project! {
+18 | |     struct C<T> {
+19 | |         #[pin]
+20 | |         #[pin] //~ ERROR no rules expected the token `#`
+21 | |         pinned: T,
+22 | |     }
+23 | | }
+   | |_^ no rules expected this token in macro call
+   |
+   = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: cannot find attribute `pin` in this scope
+  --> tests/ui/pin_project/invalid.rs:11:7
+   |
+11 |     #[pin] //~ ERROR cannot find attribute `pin` in this scope
+   |       ^^^
diff --git a/tests/ui/pin_project/overlapping_lifetime_names.rs b/tests/ui/pin_project/overlapping_lifetime_names.rs
new file mode 100644 (file)
index 0000000..117c18d
--- /dev/null
@@ -0,0 +1,10 @@
+use pin_project_lite::pin_project;
+
+pin_project! { //~ ERROR E0263,E0496
+    pub struct Foo<'__pin, T> {
+        #[pin]
+        field: &'__pin mut T,
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/overlapping_lifetime_names.stderr b/tests/ui/pin_project/overlapping_lifetime_names.stderr
new file mode 100644 (file)
index 0000000..35074d0
--- /dev/null
@@ -0,0 +1,75 @@
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20
+  |
+3 | / pin_project! { //~ ERROR E0263,E0496
+4 | |     pub struct Foo<'__pin, T> {
+  | |                    ^^^^^^ declared twice
+5 | |         #[pin]
+6 | |         field: &'__pin mut T,
+7 | |     }
+8 | | }
+  | |_- previous declaration here
+
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20
+  |
+3 | / pin_project! { //~ ERROR E0263,E0496
+4 | |     pub struct Foo<'__pin, T> {
+  | |                    ^^^^^^ declared twice
+5 | |         #[pin]
+6 | |         field: &'__pin mut T,
+7 | |     }
+8 | | }
+  | |_- previous declaration here
+
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20
+  |
+3 | / pin_project! { //~ ERROR E0263,E0496
+4 | |     pub struct Foo<'__pin, T> {
+  | |                    ^^^^^^ declared twice
+5 | |         #[pin]
+6 | |         field: &'__pin mut T,
+7 | |     }
+8 | | }
+  | |_- previous declaration here
+
+error[E0496]: lifetime name `'__pin` shadows a lifetime name that is already in scope
+ --> tests/ui/pin_project/overlapping_lifetime_names.rs:3:1
+  |
+3 | / pin_project! { //~ ERROR E0263,E0496
+4 | |     pub struct Foo<'__pin, T> {
+  | |                    ------ first declared here
+5 | |         #[pin]
+6 | |         field: &'__pin mut T,
+7 | |     }
+8 | | }
+  | |_^ lifetime `'__pin` already in scope
+  |
+  = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0496]: lifetime name `'__pin` shadows a lifetime name that is already in scope
+ --> tests/ui/pin_project/overlapping_lifetime_names.rs:3:1
+  |
+3 | / pin_project! { //~ ERROR E0263,E0496
+4 | |     pub struct Foo<'__pin, T> {
+  | |                    ------ first declared here
+5 | |         #[pin]
+6 | |         field: &'__pin mut T,
+7 | |     }
+8 | | }
+  | |_^ lifetime `'__pin` already in scope
+  |
+  = note: this error originates in the macro `$crate::__pin_project_struct_make_proj_method` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> tests/ui/pin_project/overlapping_lifetime_names.rs:4:20
+  |
+3 | / pin_project! { //~ ERROR E0263,E0496
+4 | |     pub struct Foo<'__pin, T> {
+  | |                    ^^^^^^ declared twice
+5 | |         #[pin]
+6 | |         field: &'__pin mut T,
+7 | |     }
+8 | | }
+  | |_- previous declaration here
diff --git a/tests/ui/pin_project/overlapping_unpin_struct.rs b/tests/ui/pin_project/overlapping_unpin_struct.rs
new file mode 100644 (file)
index 0000000..25131d1
--- /dev/null
@@ -0,0 +1,20 @@
+use std::marker::PhantomPinned;
+
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct Foo<T> {
+        #[pin]
+        inner: T,
+    }
+}
+
+struct __Origin {}
+
+impl Unpin for __Origin {}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+    is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
+}
diff --git a/tests/ui/pin_project/overlapping_unpin_struct.stderr b/tests/ui/pin_project/overlapping_unpin_struct.stderr
new file mode 100644 (file)
index 0000000..303e7cb
--- /dev/null
@@ -0,0 +1,33 @@
+error[E0277]: `PhantomPinned` cannot be unpinned
+  --> tests/ui/pin_project/overlapping_unpin_struct.rs:19:5
+   |
+19 |     is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Origin<'_, PhantomPinned>`, the trait `Unpin` is not implemented for `PhantomPinned`
+   |
+   = note: consider using `Box::pin`
+note: required because it appears within the type `_::__Origin<'_, PhantomPinned>`
+  --> tests/ui/pin_project/overlapping_unpin_struct.rs:5:1
+   |
+5  | / pin_project! {
+6  | |     struct Foo<T> {
+7  | |         #[pin]
+8  | |         inner: T,
+9  | |     }
+10 | | }
+   | |_^
+note: required because of the requirements on the impl of `Unpin` for `Foo<PhantomPinned>`
+  --> tests/ui/pin_project/overlapping_unpin_struct.rs:5:1
+   |
+5  | / pin_project! {
+6  | |     struct Foo<T> {
+7  | |         #[pin]
+8  | |         inner: T,
+9  | |     }
+10 | | }
+   | |_^
+note: required by a bound in `is_unpin`
+  --> tests/ui/pin_project/overlapping_unpin_struct.rs:16:16
+   |
+16 | fn is_unpin<T: Unpin>() {}
+   |                ^^^^^ required by this bound in `is_unpin`
+   = note: this error originates in the macro `$crate::__pin_project_make_unpin_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pin_project/packed.rs b/tests/ui/pin_project/packed.rs
new file mode 100644 (file)
index 0000000..50afb11
--- /dev/null
@@ -0,0 +1,21 @@
+#![allow(unaligned_references)]
+
+use pin_project_lite::pin_project;
+
+pin_project! { //~ ERROR reference to packed field is unaligned
+    #[repr(packed, C)]
+    struct Packed {
+        #[pin]
+        field: u16,
+    }
+}
+
+pin_project! { //~ ERROR reference to packed field is unaligned
+    #[repr(packed(2))]
+    struct PackedN {
+        #[pin]
+        field: u32,
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/packed.stderr b/tests/ui/pin_project/packed.stderr
new file mode 100644 (file)
index 0000000..81fb4f1
--- /dev/null
@@ -0,0 +1,57 @@
+error: reference to packed field is unaligned
+  --> tests/ui/pin_project/packed.rs:5:1
+   |
+5  | / pin_project! { //~ ERROR reference to packed field is unaligned
+6  | |     #[repr(packed, C)]
+7  | |     struct Packed {
+8  | |         #[pin]
+9  | |         field: u16,
+10 | |     }
+11 | | }
+   | |_^
+   |
+note: the lint level is defined here
+  --> tests/ui/pin_project/packed.rs:5:1
+   |
+5  | / pin_project! { //~ ERROR reference to packed field is unaligned
+6  | |     #[repr(packed, C)]
+7  | |     struct Packed {
+8  | |         #[pin]
+9  | |         field: u16,
+10 | |     }
+11 | | }
+   | |_^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: this error originates in the macro `$crate::__pin_project_constant` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: reference to packed field is unaligned
+  --> tests/ui/pin_project/packed.rs:13:1
+   |
+13 | / pin_project! { //~ ERROR reference to packed field is unaligned
+14 | |     #[repr(packed(2))]
+15 | |     struct PackedN {
+16 | |         #[pin]
+17 | |         field: u32,
+18 | |     }
+19 | | }
+   | |_^
+   |
+note: the lint level is defined here
+  --> tests/ui/pin_project/packed.rs:13:1
+   |
+13 | / pin_project! { //~ ERROR reference to packed field is unaligned
+14 | |     #[repr(packed(2))]
+15 | |     struct PackedN {
+16 | |         #[pin]
+17 | |         field: u32,
+18 | |     }
+19 | | }
+   | |_^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: this error originates in the macro `$crate::__pin_project_constant` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pin_project/unpin_sneaky.rs b/tests/ui/pin_project/unpin_sneaky.rs
new file mode 100644 (file)
index 0000000..984cc2a
--- /dev/null
@@ -0,0 +1,12 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct Foo {
+        #[pin]
+        inner: u8,
+    }
+}
+
+impl Unpin for __Origin {} //~ ERROR E0412,E0321
+
+fn main() {}
diff --git a/tests/ui/pin_project/unpin_sneaky.stderr b/tests/ui/pin_project/unpin_sneaky.stderr
new file mode 100644 (file)
index 0000000..4eb6eff
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0412]: cannot find type `__Origin` in this scope
+  --> tests/ui/pin_project/unpin_sneaky.rs:10:16
+   |
+10 | impl Unpin for __Origin {} //~ ERROR E0412,E0321
+   |                ^^^^^^^^ not found in this scope
+
+error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `[type error]`
+  --> tests/ui/pin_project/unpin_sneaky.rs:10:1
+   |
+10 | impl Unpin for __Origin {} //~ 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/unsupported.rs b/tests/ui/pin_project/unsupported.rs
new file mode 100644 (file)
index 0000000..2f80836
--- /dev/null
@@ -0,0 +1,27 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct Struct1 {} //~ ERROR no rules expected the token `}`
+}
+
+pin_project! {
+    struct Struct2(); //~ ERROR no rules expected the token `(`
+}
+
+pin_project! {
+    struct Struct3; //~ ERROR no rules expected the token `;`
+}
+
+pin_project! {
+    enum Enum { //~ ERROR no rules expected the token `enum`
+        A(u8)
+    }
+}
+
+pin_project! {
+    union Union { //~ ERROR no rules expected the token `union`
+        x: u8,
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/pin_project/unsupported.stderr b/tests/ui/pin_project/unsupported.stderr
new file mode 100644 (file)
index 0000000..a7d215a
--- /dev/null
@@ -0,0 +1,79 @@
+error: no rules expected the token `}`
+ --> tests/ui/pin_project/unsupported.rs:3:1
+  |
+3 | / pin_project! {
+4 | |     struct Struct1 {} //~ ERROR no rules expected the token `}`
+5 | | }
+  | |_^ no rules expected this token in macro call
+  |
+  = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `}`
+ --> tests/ui/pin_project/unsupported.rs:3:1
+  |
+3 | / pin_project! {
+4 | |     struct Struct1 {} //~ ERROR no rules expected the token `}`
+5 | | }
+  | |_^ no rules expected this token in macro call
+  |
+  = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `(`
+ --> tests/ui/pin_project/unsupported.rs:8:19
+  |
+8 |     struct Struct2(); //~ ERROR no rules expected the token `(`
+  |                   ^ no rules expected this token in macro call
+
+error: no rules expected the token `;`
+  --> tests/ui/pin_project/unsupported.rs:12:19
+   |
+12 |     struct Struct3; //~ ERROR no rules expected the token `;`
+   |                   ^ no rules expected this token in macro call
+
+error: no rules expected the token `enum`
+  --> tests/ui/pin_project/unsupported.rs:15:1
+   |
+15 | / pin_project! {
+16 | |     enum Enum { //~ ERROR no rules expected the token `enum`
+17 | |         A(u8)
+18 | |     }
+19 | | }
+   | |_^ no rules expected this token in macro call
+   |
+   = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `enum`
+  --> tests/ui/pin_project/unsupported.rs:15:1
+   |
+15 | / pin_project! {
+16 | |     enum Enum { //~ ERROR no rules expected the token `enum`
+17 | |         A(u8)
+18 | |     }
+19 | | }
+   | |_^ no rules expected this token in macro call
+   |
+   = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `union`
+  --> tests/ui/pin_project/unsupported.rs:21:1
+   |
+21 | / pin_project! {
+22 | |     union Union { //~ ERROR no rules expected the token `union`
+23 | |         x: u8,
+24 | |     }
+25 | | }
+   | |_^ no rules expected this token in macro call
+   |
+   = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: no rules expected the token `union`
+  --> tests/ui/pin_project/unsupported.rs:21:1
+   |
+21 | / pin_project! {
+22 | |     union Union { //~ ERROR no rules expected the token `union`
+23 | |         x: u8,
+24 | |     }
+25 | | }
+   | |_^ no rules expected this token in macro call
+   |
+   = note: this error originates in the macro `$crate::__pin_project_expand` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/pinned_drop/call-drop-inner.rs b/tests/ui/pinned_drop/call-drop-inner.rs
new file mode 100644 (file)
index 0000000..609b3be
--- /dev/null
@@ -0,0 +1,17 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+    pub struct S {
+        #[pin]
+        field: u8,
+    }
+    impl PinnedDrop for S {
+        fn drop(this: Pin<&mut Self>) {
+            __drop_inner(this);
+        }
+    }
+}
+
+fn main() {
+    let _x = S { field: 0 };
+}
diff --git a/tests/ui/pinned_drop/call-drop-inner.stderr b/tests/ui/pinned_drop/call-drop-inner.stderr
new file mode 100644 (file)
index 0000000..597f67c
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+  --> tests/ui/pinned_drop/call-drop-inner.rs:10:13
+   |
+10 |             __drop_inner(this);
+   |             ^^^^^^^^^^^^ ---- argument unexpected
+   |
+note: function defined here
+  --> tests/ui/pinned_drop/call-drop-inner.rs:3:1
+   |
+3  | / pin_project! {
+4  | |     pub struct S {
+5  | |         #[pin]
+6  | |         field: u8,
+...  |
+12 | |     }
+13 | | }
+   | |_^
+   = note: this error originates in the macro `$crate::__pin_project_make_drop_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: remove the extra argument
+   |
+10 |             __drop_inner();
+   |             ~~~~~~~~~~~~~~
diff --git a/tests/ui/pinned_drop/conditional-drop-impl.rs b/tests/ui/pinned_drop/conditional-drop-impl.rs
new file mode 100644 (file)
index 0000000..68b01b2
--- /dev/null
@@ -0,0 +1,26 @@
+use pin_project_lite::pin_project;
+
+// In `Drop` impl, the implementor must specify the same requirement as type definition.
+
+struct DropImpl<T> {
+    f: T,
+}
+
+impl<T: Unpin> Drop for DropImpl<T> {
+    //~^ ERROR E0367
+    fn drop(&mut self) {}
+}
+
+pin_project! {
+    //~^ ERROR E0367
+    struct PinnedDropImpl<T> {
+        #[pin]
+        f: T,
+    }
+
+    impl<T: Unpin> PinnedDrop for PinnedDropImpl<T> {
+        fn drop(_this: Pin<&mut Self>) {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/pinned_drop/conditional-drop-impl.stderr b/tests/ui/pinned_drop/conditional-drop-impl.stderr
new file mode 100644 (file)
index 0000000..d70009c
--- /dev/null
@@ -0,0 +1,38 @@
+error[E0367]: `Drop` impl requires `T: Unpin` but the struct it is implemented for does not
+ --> tests/ui/pinned_drop/conditional-drop-impl.rs:9:9
+  |
+9 | impl<T: Unpin> Drop for DropImpl<T> {
+  |         ^^^^^
+  |
+note: the implementor must specify the same requirement
+ --> tests/ui/pinned_drop/conditional-drop-impl.rs:5:1
+  |
+5 | / struct DropImpl<T> {
+6 | |     f: T,
+7 | | }
+  | |_^
+
+error[E0367]: `Drop` impl requires `T: Unpin` but the struct it is implemented for does not
+  --> tests/ui/pinned_drop/conditional-drop-impl.rs:14:1
+   |
+14 | / pin_project! {
+15 | |     //~^ ERROR E0367
+16 | |     struct PinnedDropImpl<T> {
+17 | |         #[pin]
+...  |
+23 | |     }
+24 | | }
+   | |_^
+   |
+note: the implementor must specify the same requirement
+  --> tests/ui/pinned_drop/conditional-drop-impl.rs:14:1
+   |
+14 | / pin_project! {
+15 | |     //~^ ERROR E0367
+16 | |     struct PinnedDropImpl<T> {
+17 | |         #[pin]
+...  |
+23 | |     }
+24 | | }
+   | |_^
+   = note: this error originates in the macro `$crate::__pin_project_make_drop_impl` (in Nightly builds, run with -Z macro-backtrace for more info)