summaryrefslogtreecommitdiffstats
path: root/third_party/rust/pin-project
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/pin-project
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--third_party/rust/pin-project-internal/.cargo-checksum.json1
-rw-r--r--third_party/rust/pin-project-internal/Cargo.toml36
-rw-r--r--third_party/rust/pin-project-internal/LICENSE-APACHE202
-rw-r--r--third_party/rust/pin-project-internal/LICENSE-MIT23
-rw-r--r--third_party/rust/pin-project-internal/src/lib.rs552
-rw-r--r--third_party/rust/pin-project-internal/src/pin_project/attribute.rs71
-rw-r--r--third_party/rust/pin-project-internal/src/pin_project/derive.rs834
-rw-r--r--third_party/rust/pin-project-internal/src/pin_project/mod.rs15
-rw-r--r--third_party/rust/pin-project-internal/src/pinned_drop.rs199
-rw-r--r--third_party/rust/pin-project-internal/src/project.rs286
-rw-r--r--third_party/rust/pin-project-internal/src/utils.rs339
-rw-r--r--third_party/rust/pin-project-lite/.cargo-checksum.json1
-rw-r--r--third_party/rust/pin-project-lite/CHANGELOG.md42
-rw-r--r--third_party/rust/pin-project-lite/Cargo.toml30
-rw-r--r--third_party/rust/pin-project-lite/LICENSE-APACHE202
-rw-r--r--third_party/rust/pin-project-lite/LICENSE-MIT23
-rw-r--r--third_party/rust/pin-project-lite/README.md105
-rw-r--r--third_party/rust/pin-project-lite/ci/install-component.sh29
-rw-r--r--third_party/rust/pin-project-lite/ci/install-rust.sh20
-rw-r--r--third_party/rust/pin-project-lite/src/lib.rs466
-rw-r--r--third_party/rust/pin-project-lite/tests/compiletest.rs9
-rw-r--r--third_party/rust/pin-project-lite/tests/test.rs348
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/conflict-drop.rs15
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/conflict-drop.stderr16
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/conflict-unpin.rs40
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/conflict-unpin.stderr50
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/invalid-bounds.rs15
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/invalid-bounds.stderr21
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/invalid.rs25
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/invalid.stderr17
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.rs10
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.stderr83
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.rs19
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.stderr13
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/packed.rs19
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/packed.stderr55
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/proper_unpin.rs41
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/proper_unpin.stderr43
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.rs12
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.stderr11
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/unsupported.rs27
-rw-r--r--third_party/rust/pin-project-lite/tests/ui/unsupported.stderr29
-rw-r--r--third_party/rust/pin-project/.cargo-checksum.json1
-rw-r--r--third_party/rust/pin-project/CHANGELOG.md363
-rw-r--r--third_party/rust/pin-project/Cargo.lock56
-rw-r--r--third_party/rust/pin-project/Cargo.toml28
-rw-r--r--third_party/rust/pin-project/LICENSE-APACHE202
-rw-r--r--third_party/rust/pin-project/LICENSE-MIT23
-rw-r--r--third_party/rust/pin-project/README.md77
-rw-r--r--third_party/rust/pin-project/ci.sh24
-rw-r--r--third_party/rust/pin-project/ci/install-component.sh29
-rw-r--r--third_party/rust/pin-project/ci/install-rust.sh20
-rw-r--r--third_party/rust/pin-project/compiletest.sh12
-rw-r--r--third_party/rust/pin-project/examples/README.md9
-rw-r--r--third_party/rust/pin-project/examples/enum-default-expanded.rs86
-rw-r--r--third_party/rust/pin-project/examples/enum-default.rs13
-rw-r--r--third_party/rust/pin-project/examples/pinned_drop-expanded.rs133
-rw-r--r--third_party/rust/pin-project/examples/pinned_drop.rs22
-rw-r--r--third_party/rust/pin-project/examples/struct-default-expanded.rs128
-rw-r--r--third_party/rust/pin-project/examples/struct-default.rs14
-rw-r--r--third_party/rust/pin-project/examples/unsafe_unpin-expanded.rs90
-rw-r--r--third_party/rust/pin-project/examples/unsafe_unpin.rs16
-rw-r--r--third_party/rust/pin-project/src/lib.rs205
-rw-r--r--third_party/rust/pin-project/tests/cfg.rs243
-rw-r--r--third_party/rust/pin-project/tests/compiletest.rs16
-rw-r--r--third_party/rust/pin-project/tests/no_infer_outlives.rs19
-rw-r--r--third_party/rust/pin-project/tests/pin_project.rs552
-rw-r--r--third_party/rust/pin-project/tests/pinned_drop.rs210
-rw-r--r--third_party/rust/pin-project/tests/project.rs217
-rw-r--r--third_party/rust/pin-project/tests/project_if_attr.rs.in29
-rw-r--r--third_party/rust/pin-project/tests/project_ref.rs151
-rw-r--r--third_party/rust/pin-project/tests/repr_packed.rs50
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.rs11
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.stderr5
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.rs24
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.stderr23
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.rs21
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.stderr22
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.rs18
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.stderr1
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.rs18
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.stderr1
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.rs12
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.stderr7
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/proper_unpin.rs28
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/proper_unpin.stderr11
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/unsupported.rs13
-rw-r--r--third_party/rust/pin-project/tests/ui/cfg/unsupported.stderr1
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.rs19
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.stderr15
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.rs23
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.stderr23
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.rs31
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.stderr21
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.rs37
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.stderr32
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.rs27
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.stderr23
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/invalid.rs56
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/invalid.stderr53
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.rs18
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.stderr11
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/packed.rs25
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/packed.stderr17
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.rs33
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.stderr23
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.rs12
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.stderr13
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.rs23
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.stderr17
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.rs38
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.stderr37
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.rs32
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.stderr21
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.rs30
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.stderr63
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.rs21
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.stderr24
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.rs11
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.stderr16
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/unsupported.rs32
-rw-r--r--third_party/rust/pin-project/tests/ui/pin_project/unsupported.stderr45
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.rs9
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr7
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/invalid.rs152
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/invalid.stderr85
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs15
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr8
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.rs14
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.stderr11
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/self.rs93
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/self.stderr95
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.rs17
-rw-r--r--third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.stderr7
-rw-r--r--third_party/rust/pin-project/tests/ui/project/ambiguous-let.rs24
-rw-r--r--third_party/rust/pin-project/tests/ui/project/ambiguous-let.stderr5
-rw-r--r--third_party/rust/pin-project/tests/ui/project/invalid.rs24
-rw-r--r--third_party/rust/pin-project/tests/ui/project/invalid.stderr11
-rw-r--r--third_party/rust/pin-project/tests/ui/project/type-mismatch.rs74
-rw-r--r--third_party/rust/pin-project/tests/ui/project/type-mismatch.stderr16
-rw-r--r--third_party/rust/pin-project/tests/ui/project/use-public.rs15
-rw-r--r--third_party/rust/pin-project/tests/ui/project/use-public.stderr7
-rw-r--r--third_party/rust/pin-project/tests/ui/project/use.rs17
-rw-r--r--third_party/rust/pin-project/tests/ui/project/use.stderr11
-rw-r--r--third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs14
-rw-r--r--third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr11
-rw-r--r--third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.rs43
-rw-r--r--third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.stderr63
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/README.md5
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs19
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.stderr10
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.rs25
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.stderr10
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs19
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.stderr10
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.rs29
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.stderr18
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs62
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs55
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr35
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.rs33
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.stderr5
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.rs52
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr45
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.rs34
-rw-r--r--third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.stderr17
-rw-r--r--third_party/rust/pin-project/tests/unsafe_unpin.rs76
167 files changed, 9977 insertions, 0 deletions
diff --git a/third_party/rust/pin-project-internal/.cargo-checksum.json b/third_party/rust/pin-project-internal/.cargo-checksum.json
new file mode 100644
index 0000000000..a115ec6566
--- /dev/null
+++ b/third_party/rust/pin-project-internal/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"3fe6c53bc8cb8dfee1091ff799a743024b78bbf7ded986396ccb8a139bc7f02b","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","src/lib.rs":"fe9fdaa1dcf2e9ade6ae1c34e20195223c8f63d19c0ba2d0189e07207d4f1a30","src/pin_project/attribute.rs":"5b441bab16d19215d660790b46eab18b402d36edb951ba7f8284772bf2a470bd","src/pin_project/derive.rs":"f244d4bed929350fdfcc96513fce17a4ab2146e1f7974ae1255d72a9b72ffd33","src/pin_project/mod.rs":"4c5f5215d1737a6e4797d7f5eb1f7f6008505b06cfc304a66758bd96e6252c0c","src/pinned_drop.rs":"4519a66e9804143578faf60ed8239811d92cc6b2af817736439a9bc772d48780","src/project.rs":"e6ce9acaaad85d9945c24ec4507e6373aa61dfab50717453666733fa8161c099","src/utils.rs":"340a79dd4b02b5ea97c747ef5c56d5a8cedfaeff4a259fe5140c83803b2ed115"},"package":"8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a"} \ No newline at end of file
diff --git a/third_party/rust/pin-project-internal/Cargo.toml b/third_party/rust/pin-project-internal/Cargo.toml
new file mode 100644
index 0000000000..f9d79ef0e9
--- /dev/null
+++ b/third_party/rust/pin-project-internal/Cargo.toml
@@ -0,0 +1,36 @@
+# 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 believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "pin-project-internal"
+version = "0.4.9"
+authors = ["Taiki Endo <te316e89@gmail.com>"]
+description = "An internal crate to support pin_project - do not use directly\n"
+homepage = "https://github.com/taiki-e/pin-project"
+documentation = "https://docs.rs/pin-project-internal"
+keywords = ["pin", "macros", "attribute"]
+categories = ["no-std", "rust-patterns"]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/taiki-e/pin-project"
+
+[lib]
+proc-macro = true
+[dependencies.proc-macro2]
+version = "1.0"
+
+[dependencies.quote]
+version = "1.0"
+
+[dependencies.syn]
+version = "1.0"
+features = ["full", "visit-mut"]
diff --git a/third_party/rust/pin-project-internal/LICENSE-APACHE b/third_party/rust/pin-project-internal/LICENSE-APACHE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/rust/pin-project-internal/LICENSE-APACHE
@@ -0,0 +1,202 @@
+
+ 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
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/third_party/rust/pin-project-internal/LICENSE-MIT b/third_party/rust/pin-project-internal/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/pin-project-internal/LICENSE-MIT
@@ -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/third_party/rust/pin-project-internal/src/lib.rs b/third_party/rust/pin-project-internal/src/lib.rs
new file mode 100644
index 0000000000..ba7abbb3d4
--- /dev/null
+++ b/third_party/rust/pin-project-internal/src/lib.rs
@@ -0,0 +1,552 @@
+//! An internal crate to support pin_project - **do not use directly**
+
+#![recursion_limit = "256"]
+#![doc(html_root_url = "https://docs.rs/pin-project-internal/0.4.9")]
+#![doc(test(
+ no_crate_inject,
+ attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code))
+))]
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(clippy::all)]
+// mem::take requires Rust 1.40
+#![allow(clippy::mem_replace_with_default)]
+#![allow(clippy::needless_doctest_main)]
+// While this crate supports stable Rust, it currently requires
+// nightly Rust in order for rustdoc to correctly document auto-generated
+// `Unpin` impls. This does not affect the runtime functionality of this crate,
+// nor does it affect the safety of the api provided by this crate.
+//
+// This is disabled by default and can be enabled using
+// `--cfg pin_project_show_unpin_struct` in RUSTFLAGS.
+//
+// Refs:
+// * https://github.com/taiki-e/pin-project/pull/53#issuecomment-525906867
+// * https://github.com/taiki-e/pin-project/pull/70
+// * https://github.com/rust-lang/rust/issues/63281
+#![cfg_attr(pin_project_show_unpin_struct, feature(proc_macro_def_site))]
+
+// older compilers require explicit `extern crate`.
+#[allow(unused_extern_crates)]
+extern crate proc_macro;
+
+#[macro_use]
+mod utils;
+
+mod pin_project;
+mod pinned_drop;
+mod project;
+
+use proc_macro::TokenStream;
+
+use utils::{Immutable, Mutable};
+
+/// An attribute that creates a projection struct covering all the fields.
+///
+/// This attribute creates a projection struct 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.
+///
+/// The following methods are implemented on the original `#[pin_project]` type:
+///
+/// ```
+/// # #[rustversion::since(1.36)]
+/// # fn dox() {
+/// # 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<'_>;
+/// # }
+/// # }
+/// ```
+///
+/// The visibility of the projected type and projection method is based on the
+/// original type. However, if the visibility of the original type is `pub`,
+/// the visibility of the projected type and the projection method is `pub(crate)`.
+///
+/// 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`.
+///
+/// ## Safety
+///
+/// This attribute is completely safe. In the absence of other `unsafe` code *that you write*,
+/// it is impossible to cause undefined behavior with this attribute.
+///
+/// This is accomplished by enforcing the four requirements for pin projection
+/// stated in [the Rust documentation](https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning):
+///
+/// 1. The struct must only be Unpin if all the structural fields are Unpin.
+///
+/// To enforce this, this attribute will automatically generate an `Unpin` implementation
+/// for you, which will require that all structurally pinned fields be `Unpin`
+/// If you wish to provide an manual `Unpin` impl, you can do so via the
+/// `UnsafeUnpin` argument.
+///
+/// 2. The destructor of the struct must not move structural fields out of its argument.
+///
+/// To enforce this, this attribute will generate code like this:
+///
+/// ```rust
+/// struct MyStruct {}
+/// trait MyStructMustNotImplDrop {}
+/// impl<T: Drop> MyStructMustNotImplDrop for T {}
+/// impl MyStructMustNotImplDrop for MyStruct {}
+/// ```
+///
+/// If you attempt to provide an Drop impl, the blanket impl will
+/// then apply to your type, causing a compile-time error due to
+/// the conflict with the second impl.
+///
+/// If you wish to provide a custom `Drop` impl, you can annotate a function
+/// with `#[pinned_drop]`. This function takes a pinned version of your struct -
+/// that is, `Pin<&mut MyStruct>` where `MyStruct` is the type of your struct.
+///
+/// You can call `project()` on this type as usual, along with any other
+/// methods you have defined. Because your code is never provided with
+/// a `&mut MyStruct`, it is impossible to move out of pin-projectable
+/// fields in safe code in your destructor.
+///
+/// 3. You must make sure that you uphold the Drop guarantee: once your struct is pinned,
+/// the memory that contains the content is not overwritten or deallocated without calling the content's destructors.
+///
+/// Safe code doesn't need to worry about this - the only wait to violate this requirement
+/// is to manually deallocate memory (which is `unsafe`), or to overwrite a field with something else.
+/// Because your custom destructor takes `Pin<&mut MyStruct`, it's impossible to obtain
+/// a mutable reference to a pin-projected field in safe code.
+///
+/// 4. You must not offer any other operations that could lead to data being moved out of the structural fields when your type is pinned.
+///
+/// As with requirement 3, it is impossible for safe code to violate this. This crate ensures that safe code can never
+/// obtain a mutable reference to `#[pin]` fields, which prevents you from ever moving out of them in safe code.
+///
+/// Pin projections are also incompatible with `#[repr(packed)]` structs. Attempting to use this attribute
+/// on a `#[repr(packed)]` struct results in a compile-time error.
+///
+///
+/// ## Examples
+///
+/// Using `#[pin_project]` will automatically create the appropriate
+/// conditional [`Unpin`] implementation:
+///
+/// ```rust
+/// use pin_project::pin_project;
+/// use std::pin::Pin;
+///
+/// #[pin_project]
+/// struct Foo<T, U> {
+/// #[pin]
+/// future: T,
+/// field: U,
+/// }
+///
+/// impl<T, U> Foo<T, U> {
+/// fn baz(self: Pin<&mut Self>) {
+/// let this = self.project();
+/// let _: Pin<&mut T> = this.future; // Pinned reference to the field
+/// let _: &mut U = this.field; // Normal reference to the field
+/// }
+/// }
+/// ```
+///
+/// Note that borrowing the field where `#[pin]` attribute is used multiple
+/// times requires using [`.as_mut()`][`Pin::as_mut`] to avoid
+/// consuming the `Pin`.
+///
+/// If you want to implement [`Unpin`] manually, you must use the `UnsafeUnpin`
+/// argument to `#[pin_project]`.
+///
+/// ```rust
+/// use pin_project::{pin_project, UnsafeUnpin};
+/// use std::pin::Pin;
+///
+/// #[pin_project(UnsafeUnpin)]
+/// struct Foo<T, U> {
+/// #[pin]
+/// future: T,
+/// field: U,
+/// }
+///
+/// impl<T, U> Foo<T, U> {
+/// fn baz(self: Pin<&mut Self>) {
+/// let this = self.project();
+/// let _: Pin<&mut T> = this.future; // Pinned reference to the field
+/// let _: &mut U = this.field; // Normal reference to the field
+/// }
+/// }
+///
+/// unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {} // Conditional Unpin impl
+/// ```
+///
+/// Note the usage of the unsafe [`UnsafeUnpin`] trait, instead of the usual
+/// [`Unpin`] trait. [`UnsafeUnpin`] behaves exactly like [`Unpin`], except that is
+/// unsafe to implement. This unsafety comes from the fact that pin projections
+/// are being used. If you implement [`UnsafeUnpin`], you must ensure that it is
+/// only implemented when all pin-projected fields implement [`Unpin`].
+///
+/// See [`UnsafeUnpin`] trait for more details.
+///
+/// ### `#[pinned_drop]`
+///
+/// In order to correctly implement pin projections, a type's `Drop` impl must
+/// not move out of any structurally pinned fields. Unfortunately, [`Drop::drop`]
+/// takes `&mut Self`, not `Pin<&mut Self>`.
+///
+/// To ensure that this requirement is upheld, the `#[pin_project]` attribute will
+/// provide a [`Drop`] impl for you. This `Drop` impl will delegate to an impl
+/// block annotated with `#[pinned_drop]` if you use the `PinnedDrop` argument
+/// to `#[pin_project]`. This impl block acts just like a normal [`Drop`] impl,
+/// except for the following two:
+///
+/// * `drop` method takes `Pin<&mut Self>`
+/// * Name of the trait is `PinnedDrop`.
+///
+/// `#[pin_project]` implements the actual [`Drop`] trait via `PinnedDrop` you
+/// implemented. To drop a type that implements `PinnedDrop`, use the [`drop`]
+/// function just like dropping a type that directly implements [`Drop`].
+///
+/// In particular, it will never be called more than once, just like [`Drop::drop`].
+///
+/// For example:
+///
+/// ```rust
+/// use pin_project::{pin_project, pinned_drop};
+/// use std::{fmt::Debug, pin::Pin};
+///
+/// #[pin_project(PinnedDrop)]
+/// pub struct Foo<T: Debug, U: Debug> {
+/// #[pin]
+/// pinned_field: T,
+/// unpin_field: U,
+/// }
+///
+/// #[pinned_drop]
+/// impl<T: Debug, U: Debug> PinnedDrop for Foo<T, U> {
+/// fn drop(self: Pin<&mut Self>) {
+/// println!("Dropping pinned field: {:?}", self.pinned_field);
+/// println!("Dropping unpin field: {:?}", self.unpin_field);
+/// }
+/// }
+///
+/// fn main() {
+/// let _x = Foo { pinned_field: true, unpin_field: 40 };
+/// }
+/// ```
+///
+/// See also [`pinned_drop`] attribute.
+///
+/// ## Supported Items
+///
+/// The current pin-project supports the following types of items.
+///
+/// ### Structs (structs with named fields):
+///
+/// ```rust
+/// use pin_project::pin_project;
+/// use std::pin::Pin;
+///
+/// #[pin_project]
+/// struct Foo<T, U> {
+/// #[pin]
+/// future: T,
+/// field: U,
+/// }
+///
+/// impl<T, U> Foo<T, U> {
+/// fn baz(self: Pin<&mut Self>) {
+/// let this = self.project();
+/// let _: Pin<&mut T> = this.future;
+/// let _: &mut U = this.field;
+/// }
+/// }
+/// ```
+///
+/// ### Tuple structs (structs with unnamed fields):
+///
+/// ```rust
+/// use pin_project::pin_project;
+/// use std::pin::Pin;
+///
+/// #[pin_project]
+/// struct Foo<T, U>(#[pin] T, U);
+///
+/// impl<T, U> Foo<T, U> {
+/// fn baz(self: Pin<&mut Self>) {
+/// let this = self.project();
+/// let _: Pin<&mut T> = this.0;
+/// let _: &mut U = this.1;
+/// }
+/// }
+/// ```
+///
+/// Structs without fields (unit-like struct and zero fields struct) are not
+/// supported.
+///
+/// ### Enums
+///
+/// `pin_project` also supports enums, but to use it, you need to use with the
+/// [`project`] attribute.
+///
+/// The attribute at the expression position is not stable, so you need to use
+/// a dummy `#[project]` attribute for the function.
+///
+/// ```rust
+/// use pin_project::{pin_project, project};
+/// use std::pin::Pin;
+///
+/// #[pin_project]
+/// enum Foo<A, B, C> {
+/// Tuple(#[pin] A, B),
+/// Struct { field: C },
+/// Unit,
+/// }
+///
+/// impl<A, B, C> Foo<A, B, C> {
+/// #[project] // Nightly does not need a dummy attribute to the function.
+/// fn baz(self: Pin<&mut Self>) {
+/// #[project]
+/// match self.project() {
+/// Foo::Tuple(x, y) => {
+/// let _: Pin<&mut A> = x;
+/// let _: &mut B = y;
+/// }
+/// Foo::Struct { field } => {
+/// let _: &mut C = field;
+/// }
+/// Foo::Unit => {}
+/// }
+/// }
+/// }
+/// ```
+///
+/// Enums without variants (zero-variant enums) are not supported.
+///
+/// See also [`project`] and [`project_ref`] attributes.
+///
+/// [`Pin::as_mut`]: core::pin::Pin::as_mut
+/// [`Pin::set`]: core::pin::Pin::set
+/// [`drop`]: Drop::drop
+/// [`UnsafeUnpin`]: https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html
+/// [`project`]: ./attr.project.html
+/// [`project_ref`]: ./attr.project_ref.html
+/// [`pinned_drop`]: ./attr.pinned_drop.html
+#[proc_macro_attribute]
+pub fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream {
+ pin_project::attribute(&args.into(), input.into()).into()
+}
+
+/// An attribute for annotating an impl block that implements [`Drop`].
+///
+/// This attribute is only needed when you wish to provide a [`Drop`]
+/// impl for your type. The impl block annotated with `#[pinned_drop]` acts just
+/// like a normal [`Drop`] impl, except for the fact that `drop` method takes
+/// `Pin<&mut Self>`. In particular, it will never be called more than once,
+/// just like [`Drop::drop`].
+///
+/// ## Example
+///
+/// ```rust
+/// use pin_project::{pin_project, pinned_drop};
+/// use std::pin::Pin;
+///
+/// #[pin_project(PinnedDrop)]
+/// struct Foo {
+/// #[pin]
+/// field: u8,
+/// }
+///
+/// #[pinned_drop]
+/// impl PinnedDrop for Foo {
+/// fn drop(self: Pin<&mut Self>) {
+/// println!("Dropping: {}", self.field);
+/// }
+/// }
+///
+/// fn main() {
+/// let _x = Foo { field: 50 };
+/// }
+/// ```
+///
+/// See ["pinned-drop" section of `pin_project` attribute][pinned-drop] for more details.
+///
+/// [pinned-drop]: ./attr.pin_project.html#pinned_drop
+#[proc_macro_attribute]
+pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
+ let input = syn::parse_macro_input!(input);
+ pinned_drop::attribute(&args.into(), input).into()
+}
+
+/// An attribute to provide way to refer to the projected type returned by
+/// `project` method.
+///
+/// The following syntaxes are supported.
+///
+/// ## `impl` blocks
+///
+/// All methods (and associated functions) in `#[project] impl` block become
+/// methods of the projected type. If you want to implement methods on the
+/// original type, you need to create another (non-`#[project]`) `impl` block.
+///
+/// To call a method implemented in `#[project] impl` block, you need to first
+/// get the projected-type with `let this = self.project();`.
+///
+/// ### Examples
+///
+/// ```rust
+/// use pin_project::{pin_project, project};
+/// use std::pin::Pin;
+///
+/// #[pin_project]
+/// struct Foo<T, U> {
+/// #[pin]
+/// future: T,
+/// field: U,
+/// }
+///
+/// // impl for the original type
+/// impl<T, U> Foo<T, U> {
+/// fn bar(self: Pin<&mut Self>) {
+/// self.project().baz()
+/// }
+/// }
+///
+/// // impl for the projected type
+/// #[project]
+/// impl<T, U> Foo<T, U> {
+/// fn baz(self) {
+/// let Self { future, field } = self;
+///
+/// let _: Pin<&mut T> = future;
+/// let _: &mut U = field;
+/// }
+/// }
+/// ```
+///
+/// ## `let` bindings
+///
+/// *The attribute at the expression position is not stable, so you need to use
+/// a dummy `#[project]` attribute for the function.*
+///
+/// ### Examples
+///
+/// ```rust
+/// use pin_project::{pin_project, project};
+/// use std::pin::Pin;
+///
+/// #[pin_project]
+/// struct Foo<T, U> {
+/// #[pin]
+/// future: T,
+/// field: U,
+/// }
+///
+/// impl<T, U> Foo<T, U> {
+/// #[project] // Nightly does not need a dummy attribute to the function.
+/// fn baz(self: Pin<&mut Self>) {
+/// #[project]
+/// let Foo { future, field } = self.project();
+///
+/// let _: Pin<&mut T> = future;
+/// let _: &mut U = field;
+/// }
+/// }
+/// ```
+///
+/// ## `match` expressions
+///
+/// *The attribute at the expression position is not stable, so you need to use
+/// a dummy `#[project]` attribute for the function.*
+///
+/// ### Examples
+///
+/// ```rust
+/// use pin_project::{pin_project, project};
+/// use std::pin::Pin;
+///
+/// #[pin_project]
+/// enum Foo<A, B, C> {
+/// Tuple(#[pin] A, B),
+/// Struct { field: C },
+/// Unit,
+/// }
+///
+/// impl<A, B, C> Foo<A, B, C> {
+/// #[project] // Nightly does not need a dummy attribute to the function.
+/// fn baz(self: Pin<&mut Self>) {
+/// #[project]
+/// match self.project() {
+/// Foo::Tuple(x, y) => {
+/// let _: Pin<&mut A> = x;
+/// let _: &mut B = y;
+/// }
+/// Foo::Struct { field } => {
+/// let _: &mut C = field;
+/// }
+/// Foo::Unit => {}
+/// }
+/// }
+/// }
+/// ```
+///
+/// ## `use` statements
+///
+/// ### Examples
+///
+/// ```rust
+/// # mod dox {
+/// use pin_project::pin_project;
+///
+/// #[pin_project]
+/// struct Foo<A> {
+/// #[pin]
+/// field: A,
+/// }
+///
+/// mod bar {
+/// use super::Foo;
+/// use pin_project::project;
+/// use std::pin::Pin;
+///
+/// #[project]
+/// use super::Foo;
+///
+/// #[project]
+/// fn baz<A>(foo: Pin<&mut Foo<A>>) {
+/// #[project]
+/// let Foo { field } = foo.project();
+/// let _: Pin<&mut A> = field;
+/// }
+/// }
+/// # }
+/// ```
+#[proc_macro_attribute]
+pub fn project(args: TokenStream, input: TokenStream) -> TokenStream {
+ let input = syn::parse_macro_input!(input);
+ project::attribute(&args.into(), input, Mutable).into()
+}
+
+/// An attribute to provide way to refer to the projected type returned by
+/// `project_ref` method.
+///
+/// This is the same as [`project`] attribute except it refers to the projected
+/// type returned by `project_ref` method.
+///
+/// See [`project`] attribute for more details.
+///
+/// [`project`]: ./attr.project.html
+#[proc_macro_attribute]
+pub fn project_ref(args: TokenStream, input: TokenStream) -> TokenStream {
+ let input = syn::parse_macro_input!(input);
+ project::attribute(&args.into(), input, Immutable).into()
+}
+
+/// An internal helper macro.
+#[doc(hidden)]
+#[proc_macro_derive(__PinProjectInternalDerive, attributes(pin))]
+pub fn __pin_project_internal_derive(input: TokenStream) -> TokenStream {
+ pin_project::derive(input.into()).into()
+}
diff --git a/third_party/rust/pin-project-internal/src/pin_project/attribute.rs b/third_party/rust/pin-project-internal/src/pin_project/attribute.rs
new file mode 100644
index 0000000000..7a0996e720
--- /dev/null
+++ b/third_party/rust/pin-project-internal/src/pin_project/attribute.rs
@@ -0,0 +1,71 @@
+use proc_macro2::{Span, TokenStream};
+use quote::quote;
+use syn::{
+ parse::{Parse, ParseStream},
+ *,
+};
+
+use crate::utils::{SliceExt, CURRENT_PRIVATE_MODULE};
+
+use super::PIN;
+
+// To generate the correct `Unpin` implementation and the projection methods,
+// we need to collect the types of the pinned fields.
+// However, since proc-macro-attribute is applied before `#[cfg]` and `#[cfg_attr]` on fields,
+// we cannot be collecting field types properly at this timing.
+// So instead of generating the `Unpin` implementation and the projection methods here,
+// delegate their processing to proc-macro-derive.
+//
+// At this stage, only attributes are parsed and the following attributes are
+// added to the attributes of the item.
+// * `#[derive(InternalDerive)]` - An internal helper macro that does the above processing.
+// * `#[pin(#private(#args))]` - Pass the argument of `#[pin_project]` to proc-macro-derive (`InternalDerive`).
+
+pub(super) fn parse_attribute(args: &TokenStream, input: TokenStream) -> Result<TokenStream> {
+ let Input { mut attrs, body } = syn::parse2(input)?;
+
+ let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
+ attrs.push(syn::parse_quote! {
+ #[derive(::pin_project::#private::__PinProjectInternalDerive)]
+ });
+ // Use `#private` to prevent users from trying to control `InternalDerive` manually.
+ // `#private` does not guarantee compatibility between patch versions,
+ // so it should be sufficient for this purpose in most cases.
+ attrs.push(syn::parse_quote! {
+ #[pin(#private(#args))]
+ });
+
+ Ok(quote! {
+ #(#attrs)*
+ #body
+ })
+}
+
+#[allow(dead_code)] // https://github.com/rust-lang/rust/issues/56750
+struct Input {
+ attrs: Vec<Attribute>,
+ body: TokenStream,
+}
+
+impl Parse for Input {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+
+ let ahead = input.fork();
+ let _vis: Visibility = ahead.parse()?;
+ if !ahead.peek(Token![struct]) && !ahead.peek(Token![enum]) {
+ // If we check this only on proc-macro-derive, it may generate unhelpful error messages.
+ // So it is preferable to be able to detect it here.
+ Err(error!(
+ input.parse::<TokenStream>()?,
+ "#[pin_project] attribute may only be used on structs or enums"
+ ))
+ } else if let Some(attr) = attrs.find(PIN) {
+ Err(error!(attr, "#[pin] attribute may only be used on fields of structs or variants"))
+ } else if let Some(attr) = attrs.find("pin_project") {
+ Err(error!(attr, "only one #[pin_project] attribute is allowed"))
+ } else {
+ Ok(Self { attrs, body: input.parse()? })
+ }
+ }
+}
diff --git a/third_party/rust/pin-project-internal/src/pin_project/derive.rs b/third_party/rust/pin-project-internal/src/pin_project/derive.rs
new file mode 100644
index 0000000000..30318f0483
--- /dev/null
+++ b/third_party/rust/pin-project-internal/src/pin_project/derive.rs
@@ -0,0 +1,834 @@
+use proc_macro2::{Span, TokenStream};
+use quote::{format_ident, quote, quote_spanned};
+use syn::{
+ parse::{Parse, ParseBuffer, ParseStream},
+ visit_mut::VisitMut,
+ *,
+};
+
+use crate::utils::*;
+
+use super::PIN;
+
+pub(super) fn parse_derive(input: TokenStream) -> Result<TokenStream> {
+ match syn::parse2(input)? {
+ Item::Struct(ItemStruct { attrs, vis, ident, generics, fields, .. }) => {
+ validate_struct(&ident, &fields)?;
+ let mut cx = Context::new(attrs, vis, ident, generics)?;
+
+ let packed_check = cx.ensure_not_packed(&fields)?;
+ let mut proj_items = cx.parse_struct(&fields)?;
+ proj_items.extend(packed_check);
+ proj_items.extend(cx.make_unpin_impl());
+ proj_items.extend(cx.make_drop_impl());
+ Ok(proj_items)
+ }
+ Item::Enum(ItemEnum { attrs, vis, ident, generics, brace_token, variants, .. }) => {
+ validate_enum(brace_token, &variants)?;
+ let mut cx = Context::new(attrs, vis, ident, generics)?;
+
+ // We don't need to check for '#[repr(packed)]',
+ // since it does not apply to enums.
+ let mut proj_items = cx.parse_enum(&variants)?;
+ proj_items.extend(cx.make_unpin_impl());
+ proj_items.extend(cx.make_drop_impl());
+ Ok(proj_items)
+ }
+ item => Err(error!(item, "#[pin_project] attribute may only be used on structs or enums")),
+ }
+}
+
+fn validate_struct(ident: &Ident, fields: &Fields) -> Result<()> {
+ match fields {
+ Fields::Named(FieldsNamed { named: f, .. })
+ | Fields::Unnamed(FieldsUnnamed { unnamed: f, .. })
+ if f.is_empty() =>
+ {
+ Err(error!(
+ fields,
+ "#[pin_project] attribute may not be used on structs with zero fields"
+ ))
+ }
+ Fields::Unit => {
+ Err(error!(ident, "#[pin_project] attribute may not be used on structs with units"))
+ }
+ _ => Ok(()),
+ }
+}
+
+fn validate_enum(brace_token: token::Brace, variants: &Variants) -> Result<()> {
+ if variants.is_empty() {
+ return Err(syn::Error::new(
+ brace_token.span,
+ "#[pin_project] attribute may not be used on enums without variants",
+ ));
+ }
+ let has_field = variants.iter().try_fold(false, |has_field, v| {
+ if let Some((_, e)) = &v.discriminant {
+ Err(error!(e, "#[pin_project] attribute may not be used on enums with discriminants"))
+ } else if let Some(attr) = v.attrs.find(PIN) {
+ Err(error!(attr, "#[pin] attribute may only be used on fields of structs or variants"))
+ } else if let Fields::Unit = v.fields {
+ Ok(has_field)
+ } else {
+ Ok(true)
+ }
+ })?;
+ if has_field {
+ Ok(())
+ } else {
+ Err(error!(
+ variants,
+ "#[pin_project] attribute may not be used on enums that have no field"
+ ))
+ }
+}
+
+#[derive(Default)]
+struct Args {
+ pinned_drop: Option<Span>,
+ unsafe_unpin: Option<Span>,
+}
+
+const DUPLICATE_PIN: &str = "duplicate #[pin] attribute";
+
+impl Args {
+ fn get(attrs: &[Attribute]) -> Result<Self> {
+ let mut prev: Option<(&Attribute, Result<Args>)> = None;
+
+ for attr in attrs {
+ if attr.path.is_ident(PIN) {
+ if let Some((prev_attr, prev_res)) = &prev {
+ // As the `#[pin]` attribute generated by `#[pin_project]`
+ // has the same span as `#[pin_project]`, it is possible
+ // that a useless error message will be generated.
+ let res = syn::parse2::<Self>(attr.tokens.clone());
+ let span = match (&prev_res, res) {
+ (Ok(_), Ok(_)) => unreachable!(),
+ (_, Ok(_)) => prev_attr,
+ (Ok(_), _) => attr,
+ (Err(prev_err), Err(_)) => {
+ if prev_err.to_string() == DUPLICATE_PIN {
+ attr
+ } else {
+ prev_attr
+ }
+ }
+ };
+ return Err(error!(span, DUPLICATE_PIN));
+ }
+ prev = Some((attr, syn::parse2::<Self>(attr.tokens.clone())));
+ }
+ }
+
+ // This `unwrap` only fails if another macro removes `#[pin]`.
+ prev.unwrap().1
+ }
+}
+
+impl Parse for Args {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ fn parse_input(input: ParseStream<'_>) -> Result<ParseBuffer<'_>> {
+ // Extracts `#args` from `(#private(#args))`.
+ if let Ok(content) = input.parenthesized() {
+ if let Ok(private) = content.parse::<Ident>() {
+ if private == CURRENT_PRIVATE_MODULE {
+ if let Ok(args) = content.parenthesized() {
+ return Ok(args);
+ }
+ }
+ }
+ }
+
+ // If this fails, it means that there is a `#[pin]` attribute
+ // inserted by something other than #[pin_project] attribute.
+ Err(error!(TokenStream::new(), DUPLICATE_PIN))
+ }
+
+ let input = parse_input(input)?;
+ let mut args = Self::default();
+ while !input.is_empty() {
+ let ident = input.parse::<Ident>()?;
+ match &*ident.to_string() {
+ "PinnedDrop" => {
+ if args.pinned_drop.is_some() {
+ return Err(error!(ident, "duplicate `PinnedDrop` argument"));
+ }
+ args.pinned_drop = Some(ident.span());
+ }
+ "UnsafeUnpin" => {
+ if args.unsafe_unpin.is_some() {
+ return Err(error!(ident, "duplicate `UnsafeUnpin` argument"));
+ }
+ args.unsafe_unpin = Some(ident.span());
+ }
+ _ => return Err(error!(ident, "unexpected argument: {}", ident)),
+ }
+
+ if !input.is_empty() {
+ let _: token::Comma = input.parse()?;
+ }
+ }
+
+ Ok(args)
+ }
+}
+
+struct OriginalType {
+ /// Attributes of the original type.
+ attrs: Vec<Attribute>,
+ /// Visibility of the original type.
+ vis: Visibility,
+ /// Name of the original type.
+ ident: Ident,
+ /// Generics of the original type.
+ generics: Generics,
+}
+
+struct ProjectedType {
+ /// Visibility of the projected type.
+ vis: Visibility,
+ /// Name of the projected type returned by `project` method.
+ mut_ident: Ident,
+ /// Name of the projected type returned by `project_ref` method.
+ ref_ident: Ident,
+ /// Lifetime on the generated projected type.
+ lifetime: Lifetime,
+ /// Generics of the projected type.
+ generics: Generics,
+ /// `where` clause of the projected type. This has an additional
+ /// bound generated by `insert_lifetime_and_bound`
+ where_clause: WhereClause,
+}
+
+struct Context {
+ orig: OriginalType,
+ proj: ProjectedType,
+ /// Types of the pinned fields.
+ pinned_fields: Vec<Type>,
+ /// `PinnedDrop` attribute.
+ pinned_drop: Option<Span>,
+ /// `UnsafeUnpin` attribute.
+ unsafe_unpin: Option<Span>,
+}
+
+impl Context {
+ fn new(
+ attrs: Vec<Attribute>,
+ vis: Visibility,
+ ident: Ident,
+ mut generics: Generics,
+ ) -> Result<Self> {
+ let Args { pinned_drop, unsafe_unpin } = Args::get(&attrs)?;
+
+ {
+ let ty_generics = generics.split_for_impl().1;
+ let self_ty = syn::parse_quote!(#ident #ty_generics);
+ let mut visitor = ReplaceReceiver::new(&self_ty);
+ visitor.visit_where_clause_mut(generics.make_where_clause());
+ }
+
+ let mut lifetime_name = String::from(DEFAULT_LIFETIME_NAME);
+ determine_lifetime_name(&mut lifetime_name, &generics.params);
+ let lifetime = Lifetime::new(&lifetime_name, Span::call_site());
+
+ let mut proj_generics = generics.clone();
+ let ty_generics = generics.split_for_impl().1;
+ let ty_generics_as_generics = syn::parse_quote!(#ty_generics);
+ let pred = insert_lifetime_and_bound(
+ &mut proj_generics,
+ lifetime.clone(),
+ &ty_generics_as_generics,
+ ident.clone(),
+ );
+ let mut where_clause = generics.clone().make_where_clause().clone();
+ where_clause.predicates.push(pred);
+
+ Ok(Self {
+ proj: ProjectedType {
+ vis: determine_visibility(&vis),
+ mut_ident: proj_ident(&ident, Mutable),
+ ref_ident: proj_ident(&ident, Immutable),
+ lifetime,
+ generics: proj_generics,
+ where_clause,
+ },
+ orig: OriginalType { attrs, vis, ident, generics },
+ pinned_drop,
+ unsafe_unpin,
+ pinned_fields: Vec::new(),
+ })
+ }
+
+ fn parse_struct(&mut self, fields: &Fields) -> Result<TokenStream> {
+ let (proj_pat, proj_init, proj_fields, proj_ref_fields) = match fields {
+ Fields::Named(fields) => self.visit_named(fields)?,
+ Fields::Unnamed(fields) => self.visit_unnamed(fields)?,
+ Fields::Unit => unreachable!(),
+ };
+
+ let orig_ident = &self.orig.ident;
+ let proj_ident = &self.proj.mut_ident;
+ let proj_ref_ident = &self.proj.ref_ident;
+ let vis = &self.proj.vis;
+ let proj_generics = &self.proj.generics;
+ let where_clause = &self.proj.where_clause;
+
+ // For tuple structs, we need to generate `(T1, T2) where Foo: Bar`
+ // For non-tuple structs, we need to generate `where Foo: Bar { field1: T }`
+ let (where_clause_fields, where_clause_ref_fields) = match fields {
+ Fields::Named(_) => {
+ (quote!(#where_clause #proj_fields), quote!(#where_clause #proj_ref_fields))
+ }
+ Fields::Unnamed(_) => {
+ (quote!(#proj_fields #where_clause;), quote!(#proj_ref_fields #where_clause;))
+ }
+ Fields::Unit => unreachable!(),
+ };
+
+ let mut proj_items = quote! {
+ #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #vis struct #proj_ident #proj_generics #where_clause_fields
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #vis struct #proj_ref_ident #proj_generics #where_clause_ref_fields
+ };
+
+ let proj_body = quote! {
+ let #orig_ident #proj_pat = self.get_unchecked_mut();
+ #proj_ident #proj_init
+ };
+ let proj_ref_body = quote! {
+ let #orig_ident #proj_pat = self.get_ref();
+ #proj_ref_ident #proj_init
+ };
+
+ proj_items.extend(self.make_proj_impl(&proj_body, &proj_ref_body));
+
+ Ok(proj_items)
+ }
+
+ fn parse_enum(&mut self, variants: &Variants) -> Result<TokenStream> {
+ let (proj_variants, proj_ref_variants, proj_arms, proj_ref_arms) =
+ self.visit_variants(variants)?;
+
+ let proj_ident = &self.proj.mut_ident;
+ let proj_ref_ident = &self.proj.ref_ident;
+ let vis = &self.proj.vis;
+ let proj_generics = &self.proj.generics;
+ let where_clause = &self.proj.where_clause;
+
+ let mut proj_items = quote! {
+ #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #vis enum #proj_ident #proj_generics #where_clause {
+ #proj_variants
+ }
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ #vis enum #proj_ref_ident #proj_generics #where_clause {
+ #proj_ref_variants
+ }
+ };
+
+ let proj_body = quote! {
+ match self.get_unchecked_mut() {
+ #proj_arms
+ }
+ };
+ let proj_ref_body = quote! {
+ match self.get_ref() {
+ #proj_ref_arms
+ }
+ };
+
+ proj_items.extend(self.make_proj_impl(&proj_body, &proj_ref_body));
+
+ Ok(proj_items)
+ }
+
+ fn visit_variants(
+ &mut self,
+ variants: &Variants,
+ ) -> Result<(TokenStream, TokenStream, TokenStream, TokenStream)> {
+ let mut proj_variants = TokenStream::new();
+ let mut proj_ref_variants = TokenStream::new();
+ let mut proj_arms = TokenStream::new();
+ let mut proj_ref_arms = TokenStream::new();
+ for Variant { ident, fields, .. } in variants {
+ let (proj_pat, proj_body, proj_fields, proj_ref_fields) = match fields {
+ Fields::Named(fields) => self.visit_named(fields)?,
+ Fields::Unnamed(fields) => self.visit_unnamed(fields)?,
+ Fields::Unit => {
+ (TokenStream::new(), TokenStream::new(), TokenStream::new(), TokenStream::new())
+ }
+ };
+
+ let orig_ident = &self.orig.ident;
+ let proj_ident = &self.proj.mut_ident;
+ let proj_ref_ident = &self.proj.ref_ident;
+ proj_variants.extend(quote! {
+ #ident #proj_fields,
+ });
+ proj_ref_variants.extend(quote! {
+ #ident #proj_ref_fields,
+ });
+ proj_arms.extend(quote! {
+ #orig_ident::#ident #proj_pat => {
+ #proj_ident::#ident #proj_body
+ }
+ });
+ proj_ref_arms.extend(quote! {
+ #orig_ident::#ident #proj_pat => {
+ #proj_ref_ident::#ident #proj_body
+ }
+ });
+ }
+
+ Ok((proj_variants, proj_ref_variants, proj_arms, proj_ref_arms))
+ }
+
+ fn visit_named(
+ &mut self,
+ FieldsNamed { named: fields, .. }: &FieldsNamed,
+ ) -> Result<(TokenStream, TokenStream, TokenStream, TokenStream)> {
+ let mut proj_pat = Vec::with_capacity(fields.len());
+ let mut proj_body = Vec::with_capacity(fields.len());
+ let mut proj_fields = Vec::with_capacity(fields.len());
+ let mut proj_ref_fields = Vec::with_capacity(fields.len());
+ for Field { attrs, vis, ident, ty, .. } in fields {
+ if attrs.find_exact(PIN)?.is_some() {
+ self.pinned_fields.push(ty.clone());
+
+ let lifetime = &self.proj.lifetime;
+ proj_fields.push(quote! {
+ #vis #ident: ::core::pin::Pin<&#lifetime mut (#ty)>
+ });
+ proj_ref_fields.push(quote! {
+ #vis #ident: ::core::pin::Pin<&#lifetime (#ty)>
+ });
+ proj_body.push(quote! {
+ #ident: ::core::pin::Pin::new_unchecked(#ident)
+ });
+ } else {
+ let lifetime = &self.proj.lifetime;
+ proj_fields.push(quote! {
+ #vis #ident: &#lifetime mut (#ty)
+ });
+ proj_ref_fields.push(quote! {
+ #vis #ident: &#lifetime (#ty)
+ });
+ proj_body.push(quote! {
+ #ident
+ });
+ }
+ proj_pat.push(ident);
+ }
+
+ let proj_pat = quote!({ #(#proj_pat),* });
+ let proj_body = quote!({ #(#proj_body),* });
+ let proj_fields = quote!({ #(#proj_fields),* });
+ let proj_ref_fields = quote!({ #(#proj_ref_fields),* });
+
+ Ok((proj_pat, proj_body, proj_fields, proj_ref_fields))
+ }
+
+ fn visit_unnamed(
+ &mut self,
+ FieldsUnnamed { unnamed: fields, .. }: &FieldsUnnamed,
+ ) -> Result<(TokenStream, TokenStream, TokenStream, TokenStream)> {
+ let mut proj_pat = Vec::with_capacity(fields.len());
+ let mut proj_body = Vec::with_capacity(fields.len());
+ let mut proj_fields = Vec::with_capacity(fields.len());
+ let mut proj_ref_fields = Vec::with_capacity(fields.len());
+ for (i, Field { attrs, vis, ty, .. }) in fields.iter().enumerate() {
+ let id = format_ident!("_{}", i);
+ if attrs.find_exact(PIN)?.is_some() {
+ self.pinned_fields.push(ty.clone());
+
+ let lifetime = &self.proj.lifetime;
+ proj_fields.push(quote! {
+ #vis ::core::pin::Pin<&#lifetime mut (#ty)>
+ });
+ proj_ref_fields.push(quote! {
+ #vis ::core::pin::Pin<&#lifetime (#ty)>
+ });
+ proj_body.push(quote! {
+ ::core::pin::Pin::new_unchecked(#id)
+ });
+ } else {
+ let lifetime = &self.proj.lifetime;
+ proj_fields.push(quote! {
+ #vis &#lifetime mut (#ty)
+ });
+ proj_ref_fields.push(quote! {
+ #vis &#lifetime (#ty)
+ });
+ proj_body.push(quote! {
+ #id
+ });
+ }
+ proj_pat.push(id);
+ }
+
+ let proj_pat = quote!((#(#proj_pat),*));
+ let proj_body = quote!((#(#proj_body),*));
+ let (proj_fields, proj_ref_fields) =
+ (quote!((#(#proj_fields),*)), quote!((#(#proj_ref_fields),*)));
+
+ Ok((proj_pat, proj_body, proj_fields, proj_ref_fields))
+ }
+
+ /// Creates conditional `Unpin` implementation for original type.
+ fn make_unpin_impl(&mut self) -> TokenStream {
+ if let Some(unsafe_unpin) = self.unsafe_unpin {
+ let mut proj_generics = self.proj.generics.clone();
+ let orig_ident = &self.orig.ident;
+ let lifetime = &self.proj.lifetime;
+
+ let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
+ proj_generics.make_where_clause().predicates.push(
+ // Make the error message highlight `UnsafeUnpin` argument.
+ syn::parse2(quote_spanned! { unsafe_unpin =>
+ ::pin_project::#private::Wrapper<#lifetime, Self>: ::pin_project::UnsafeUnpin
+ })
+ .unwrap(),
+ );
+
+ let (impl_generics, _, where_clause) = proj_generics.split_for_impl();
+ let ty_generics = self.orig.generics.split_for_impl().1;
+
+ quote! {
+ #[allow(single_use_lifetimes)]
+ impl #impl_generics ::core::marker::Unpin for #orig_ident #ty_generics #where_clause {}
+ }
+ } else {
+ let mut full_where_clause = self.orig.generics.where_clause.as_ref().cloned().unwrap();
+ let orig_ident = &self.orig.ident;
+
+ let make_span = || {
+ #[cfg(pin_project_show_unpin_struct)]
+ {
+ proc_macro::Span::def_site().into()
+ }
+ #[cfg(not(pin_project_show_unpin_struct))]
+ {
+ Span::call_site()
+ }
+ };
+
+ let struct_ident = format_ident!("__{}", orig_ident, span = make_span());
+
+ // Generate a field in our new struct for every
+ // pinned field in the original type.
+ let fields: Vec<_> = self
+ .pinned_fields
+ .iter()
+ .enumerate()
+ .map(|(i, ty)| {
+ let field_ident = format_ident!("__field{}", i);
+ quote! {
+ #field_ident: #ty
+ }
+ })
+ .collect();
+
+ // We could try to determine the subset of type parameters
+ // and lifetimes that are actually used by the pinned fields
+ // (as opposed to those only used by unpinned fields).
+ // However, this would be tricky and error-prone, since
+ // it's possible for users to create types that would alias
+ // with generic parameters (e.g. 'struct T').
+ //
+ // Instead, we generate a use of every single type parameter
+ // and lifetime used in the original struct. For type parameters,
+ // we generate code like this:
+ //
+ // ```rust
+ // struct AlwaysUnpin<T: ?Sized>(PhantomData<T>) {}
+ // impl<T: ?Sized> Unpin for AlwaysUnpin<T> {}
+ //
+ // ...
+ // _field: AlwaysUnpin<(A, B, C)>
+ // ```
+ //
+ // This ensures that any unused type parameters
+ // don't end up with Unpin bounds.
+ let lifetime_fields: Vec<_> = self
+ .orig
+ .generics
+ .lifetimes()
+ .enumerate()
+ .map(|(i, LifetimeDef { lifetime, .. })| {
+ let field_ident = format_ident!("__lifetime{}", i);
+ quote! {
+ #field_ident: &#lifetime ()
+ }
+ })
+ .collect();
+
+ let scope_ident = format_ident!("__unpin_scope_{}", orig_ident);
+
+ let vis = &self.orig.vis;
+ let lifetime = &self.proj.lifetime;
+ let type_params: Vec<_> = self.orig.generics.type_params().map(|t| &t.ident).collect();
+ let proj_generics = &self.proj.generics;
+ let (impl_generics, proj_ty_generics, _) = proj_generics.split_for_impl();
+ let (_, ty_generics, where_clause) = self.orig.generics.split_for_impl();
+
+ full_where_clause.predicates.push(syn::parse_quote! {
+ #struct_ident #proj_ty_generics: ::core::marker::Unpin
+ });
+
+ let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
+ let inner_data = quote! {
+ // This needs to have the same visibility as the original type,
+ // due to the limitations of the 'public in private' error.
+ //
+ // Out goal is to implement the public trait Unpin for
+ // a potentially public user type. Because of this, rust
+ // requires that any types mentioned in the where clause of
+ // our Unpin impl also be public. This means that our generated
+ // 'UnpinStruct' type must also be public. However, we take
+ // steps to ensure that the user can never actually reference
+ // this 'public' type. These steps are described below.
+ //
+ // See also https://github.com/taiki-e/pin-project/pull/53.
+ #vis struct #struct_ident #proj_generics #where_clause {
+ __pin_project_use_generics: ::pin_project::#private::AlwaysUnpin<#lifetime, (#(#type_params),*)>,
+
+ #(#fields,)*
+ #(#lifetime_fields,)*
+ }
+
+ impl #impl_generics ::core::marker::Unpin for #orig_ident #ty_generics #full_where_clause {}
+ };
+
+ if cfg!(pin_project_show_unpin_struct) {
+ // On nightly, we use def-site hygiene to make it impossible
+ // for user code to refer to any of the types we define.
+ // This allows us to omit wrapping the generated types
+ // in an fn() scope, allowing rustdoc to properly document
+ // them.
+ inner_data
+ } else {
+ // When we're not on nightly, we need to create an enclosing fn() scope
+ // for all of our generated items. This makes it impossible for
+ // user code to refer to any of our generated types, but has
+ // the advantage of preventing Rustdoc from displaying
+ // docs for any of our types. In particular, users cannot see
+ // the automatically generated Unpin impl for the 'UnpinStruct$Name' types.
+ quote! {
+ #[allow(non_snake_case)]
+ fn #scope_ident() {
+ #inner_data
+ }
+ }
+ }
+ }
+ }
+
+ /// Creates `Drop` implementation for original type.
+ fn make_drop_impl(&self) -> TokenStream {
+ let ident = &self.orig.ident;
+ let (impl_generics, ty_generics, where_clause) = self.orig.generics.split_for_impl();
+
+ let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
+ if let Some(pinned_drop) = self.pinned_drop {
+ // Make the error message highlight `PinnedDrop` argument.
+ // See https://github.com/taiki-e/pin-project/issues/16#issuecomment-513586812
+ // for why this is only for the span of function calls, not the entire `impl` block.
+ let call_drop = quote_spanned! { pinned_drop =>
+ ::pin_project::#private::PinnedDrop::drop(pinned_self)
+ };
+
+ quote! {
+ #[allow(single_use_lifetimes)]
+ impl #impl_generics ::core::ops::Drop for #ident #ty_generics #where_clause {
+ fn drop(&mut self) {
+ // Safety - we're in 'drop', so we know that 'self' will
+ // never move again.
+ let pinned_self = unsafe { ::core::pin::Pin::new_unchecked(self) };
+ // We call `pinned_drop` only once. Since `PinnedDrop::drop`
+ // is an unsafe function and a private API, it is never called again in safe
+ // code *unless the user uses a maliciously crafted macro*.
+ unsafe {
+ #call_drop;
+ }
+ }
+ }
+ }
+ } else {
+ // If the user does not provide a pinned_drop impl,
+ // we need to ensure that they don't provide a `Drop` impl of their
+ // own.
+ // Based on https://github.com/upsuper/assert-impl/blob/f503255b292ab0ba8d085b657f4065403cfa46eb/src/lib.rs#L80-L87
+ //
+ // We create a new identifier for each struct, so that the traits
+ // for different types do not conflict with each other.
+ //
+ // Another approach would be to provide an empty Drop impl,
+ // which would conflict with a user-provided Drop impl.
+ // However, this would trigger the compiler's special handling
+ // of Drop types (e.g. fields cannot be moved out of a Drop type).
+ // This approach prevents the creation of needless Drop impls,
+ // giving users more flexibility.
+ let trait_ident = format_ident!("{}MustNotImplDrop", ident);
+
+ quote! {
+ // 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 #trait_ident {}
+ #[allow(clippy::drop_bounds)]
+ impl<T: ::core::ops::Drop> #trait_ident for T {}
+ #[allow(single_use_lifetimes)]
+ impl #impl_generics #trait_ident for #ident #ty_generics #where_clause {}
+
+ // A dummy impl of `PinnedDrop`, to ensure that the user cannot implement it.
+ // Since the user did not pass `PinnedDrop` to `#[pin_project]`, any `PinnedDrop`
+ // impl will not actually be called. Unfortunately, we can't detect this situation
+ // directly from either the `#[pin_project]` or `#[pinned_drop]` attributes, since
+ // we don't know what other attirbutes/impl may exist.
+ //
+ // To ensure that users don't accidentally write a non-functional `PinnedDrop`
+ // impls, we emit one ourselves. If the user ends up writing a `PinnedDrop` impl,
+ // they'll get a "conflicting implementations of trait" error when coherence
+ // checks are run
+ #[allow(single_use_lifetimes)]
+ impl #impl_generics ::pin_project::#private::PinnedDrop for #ident #ty_generics #where_clause {
+ unsafe fn drop(self: ::core::pin::Pin<&mut Self>) {}
+ }
+ }
+ }
+ }
+
+ /// Creates an implementation of the projection method.
+ fn make_proj_impl(&self, proj_body: &TokenStream, proj_ref_body: &TokenStream) -> TokenStream {
+ let vis = &self.proj.vis;
+ let lifetime = &self.proj.lifetime;
+ let orig_ident = &self.orig.ident;
+ let proj_ident = &self.proj.mut_ident;
+ let proj_ref_ident = &self.proj.ref_ident;
+
+ let proj_ty_generics = self.proj.generics.split_for_impl().1;
+ let (impl_generics, ty_generics, where_clause) = self.orig.generics.split_for_impl();
+
+ quote! {
+ impl #impl_generics #orig_ident #ty_generics #where_clause {
+ #vis fn project<#lifetime>(
+ self: ::core::pin::Pin<&#lifetime mut Self>,
+ ) -> #proj_ident #proj_ty_generics {
+ unsafe {
+ #proj_body
+ }
+ }
+ #vis fn project_ref<#lifetime>(
+ self: ::core::pin::Pin<&#lifetime Self>,
+ ) -> #proj_ref_ident #proj_ty_generics {
+ unsafe {
+ #proj_ref_body
+ }
+ }
+ }
+ }
+ }
+
+ fn ensure_not_packed(&self, fields: &Fields) -> Result<TokenStream> {
+ for meta in self.orig.attrs.iter().filter_map(|attr| attr.parse_meta().ok()) {
+ if let Meta::List(l) = meta {
+ if l.path.is_ident("repr") {
+ for repr in l.nested.iter() {
+ match repr {
+ NestedMeta::Meta(Meta::Path(path))
+ | NestedMeta::Meta(Meta::List(MetaList { path, .. }))
+ if path.is_ident("packed") =>
+ {
+ return Err(error!(
+ repr,
+ "#[pin_project] attribute may not be used on #[repr(packed)] types"
+ ));
+ }
+ _ => {}
+ }
+ }
+ }
+ }
+ }
+
+ // As proc-macro-derive can't rewrite the structure definition,
+ // it's probably no longer necessary, but it keeps it for now.
+
+ // Workaround for https://github.com/taiki-e/pin-project/issues/32
+ // Through the tricky use of proc macros, it's possible to bypass
+ // the above check for the 'repr' attribute.
+ // To ensure that it's impossible to use pin projections on a #[repr(packed)]
+ // struct, we generate code like this:
+ //
+ // #[deny(safe_packed_borrows)]
+ // fn enforce_not_packed_for_MyStruct(val: &MyStruct) {
+ // let _field1 = &val.field1;
+ // let _field2 = &val.field2;
+ // ...
+ // let _fieldn = &val.fieldn;
+ // }
+ //
+ // Taking a reference to a packed field is unsafe, and applying
+ // #[deny(safe_packed_borrows)] makes sure that doing this without
+ // an 'unsafe' block (which we deliberately do not generate)
+ // is a hard error.
+ //
+ // If the struct ends up having #[repr(packed)] applied somehow,
+ // this will generate an (unfriendly) error message. Under all reasonable
+ // circumstances, we'll detect the #[repr(packed)] attribute, and generate
+ // a much nicer error above.
+ //
+ // There is one exception: If the type of a struct field has an alignment of 1
+ // (e.g. u8), it is always safe to take a reference to it, even if the struct
+ // is #[repr(packed)]. If the struct is composed entirely of types of alignment 1,
+ // our generated method will not trigger an error if the struct is #[repr(packed)]
+ //
+ // Fortunately, this should have no observable consequence - #[repr(packed)]
+ // is essentially a no-op on such a type. Nevertheless, we include a test
+ // to ensure that the compiler doesn't ever try to copy the fields on
+ // such a struct when trying to drop it - which is reason we prevent
+ // #[repr(packed)] in the first place.
+ //
+ // See also https://github.com/taiki-e/pin-project/pull/34.
+ let mut field_refs = vec![];
+ match fields {
+ Fields::Named(FieldsNamed { named, .. }) => {
+ for Field { ident, .. } in named {
+ field_refs.push(quote! {
+ &val.#ident;
+ });
+ }
+ }
+ Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => {
+ for (index, _) in unnamed.iter().enumerate() {
+ let index = Index::from(index);
+ field_refs.push(quote! {
+ &val.#index;
+ });
+ }
+ }
+ Fields::Unit => {}
+ }
+
+ let (impl_generics, ty_generics, where_clause) = self.orig.generics.split_for_impl();
+
+ let struct_name = &self.orig.ident;
+ let method_name = format_ident!("__pin_project_assert_not_repr_packed_{}", self.orig.ident);
+ Ok(quote! {
+ #[allow(single_use_lifetimes)]
+ #[allow(non_snake_case)]
+ #[deny(safe_packed_borrows)]
+ fn #method_name #impl_generics (val: &#struct_name #ty_generics) #where_clause {
+ #(#field_refs)*
+ }
+ })
+ }
+}
diff --git a/third_party/rust/pin-project-internal/src/pin_project/mod.rs b/third_party/rust/pin-project-internal/src/pin_project/mod.rs
new file mode 100644
index 0000000000..e8d83aacf7
--- /dev/null
+++ b/third_party/rust/pin-project-internal/src/pin_project/mod.rs
@@ -0,0 +1,15 @@
+use proc_macro2::TokenStream;
+
+mod attribute;
+mod derive;
+
+/// The annotation for pinned type.
+const PIN: &str = "pin";
+
+pub(crate) fn attribute(args: &TokenStream, input: TokenStream) -> TokenStream {
+ attribute::parse_attribute(args, input).unwrap_or_else(|e| e.to_compile_error())
+}
+
+pub(crate) fn derive(input: TokenStream) -> TokenStream {
+ derive::parse_derive(input).unwrap_or_else(|e| e.to_compile_error())
+}
diff --git a/third_party/rust/pin-project-internal/src/pinned_drop.rs b/third_party/rust/pin-project-internal/src/pinned_drop.rs
new file mode 100644
index 0000000000..11cc37dc50
--- /dev/null
+++ b/third_party/rust/pin-project-internal/src/pinned_drop.rs
@@ -0,0 +1,199 @@
+use proc_macro2::{Span, TokenStream};
+use quote::{quote, quote_spanned, ToTokens};
+use syn::{spanned::Spanned, visit_mut::VisitMut, *};
+
+use crate::utils::{
+ parse_as_empty, prepend_underscore_to_self, ReplaceReceiver, CURRENT_PRIVATE_MODULE,
+};
+
+pub(crate) fn attribute(args: &TokenStream, mut input: ItemImpl) -> TokenStream {
+ if let Err(e) = parse_as_empty(args).and_then(|()| parse(&mut input)) {
+ let self_ty = &input.self_ty;
+ let (impl_generics, _, where_clause) = input.generics.split_for_impl();
+
+ let mut tokens = e.to_compile_error();
+ let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
+ // Generate a dummy `PinnedDrop` implementation.
+ // In many cases, `#[pinned_drop] impl` is declared after `#[pin_project]`.
+ // Therefore, if `pinned_drop` compile fails, you will also get an error
+ // about `PinnedDrop` not being implemented.
+ // This can be prevented to some extent by generating a dummy
+ // `PinnedDrop` implementation.
+ // We already know that we will get a compile error, so this won't
+ // accidentally compile successfully.
+ tokens.extend(quote! {
+ impl #impl_generics ::pin_project::#private::PinnedDrop for #self_ty #where_clause {
+ unsafe fn drop(self: ::core::pin::Pin<&mut Self>) {}
+ }
+ });
+ tokens
+ } else {
+ input.into_token_stream()
+ }
+}
+
+fn parse_method(method: &ImplItemMethod) -> Result<()> {
+ fn get_ty_path(ty: &Type) -> Option<&Path> {
+ if let Type::Path(TypePath { qself: None, path }) = ty { Some(path) } else { None }
+ }
+
+ const INVALID_ARGUMENT: &str = "method `drop` must take an argument `self: Pin<&mut Self>`";
+
+ if method.sig.ident != "drop" {
+ return Err(error!(
+ method.sig.ident,
+ "method `{}` is not a member of trait `PinnedDrop", method.sig.ident,
+ ));
+ }
+
+ if let ReturnType::Type(_, ty) = &method.sig.output {
+ match &**ty {
+ Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => {}
+ _ => return Err(error!(ty, "method `drop` must return the unit type")),
+ }
+ }
+
+ if method.sig.inputs.len() != 1 {
+ if method.sig.inputs.is_empty() {
+ return Err(syn::Error::new(method.sig.paren_token.span, INVALID_ARGUMENT));
+ } else {
+ return Err(error!(&method.sig.inputs, INVALID_ARGUMENT));
+ }
+ }
+
+ if let FnArg::Typed(PatType { pat, ty, .. }) = &method.sig.inputs[0] {
+ // !by_ref (mutability) ident !subpat: path
+ if let (Pat::Ident(PatIdent { by_ref: None, ident, subpat: None, .. }), Some(path)) =
+ (&**pat, get_ty_path(ty))
+ {
+ let ty = &path.segments.last().unwrap();
+ if let PathArguments::AngleBracketed(args) = &ty.arguments {
+ // (mut) self: (path::)Pin<args>
+ if ident == "self" && args.args.len() == 1 && ty.ident == "Pin" {
+ // &mut <elem>
+ if let GenericArgument::Type(Type::Reference(TypeReference {
+ mutability: Some(_),
+ elem,
+ ..
+ })) = &args.args[0]
+ {
+ if get_ty_path(elem).map_or(false, |path| path.is_ident("Self")) {
+ if method.sig.unsafety.is_some() {
+ return Err(error!(
+ method.sig.unsafety,
+ "implementing the method `drop` is not unsafe"
+ ));
+ }
+ return Ok(());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Err(error!(method.sig.inputs[0], INVALID_ARGUMENT))
+}
+
+fn parse(item: &mut ItemImpl) -> Result<()> {
+ if let Some((_, path, _)) = &mut item.trait_ {
+ if path.is_ident("PinnedDrop") {
+ let private = Ident::new(CURRENT_PRIVATE_MODULE, Span::call_site());
+ *path = syn::parse2(quote_spanned! { path.span() =>
+ ::pin_project::#private::PinnedDrop
+ })
+ .unwrap();
+ } else {
+ return Err(error!(
+ path,
+ "#[pinned_drop] may only be used on implementation for the `PinnedDrop` trait"
+ ));
+ }
+ } else {
+ return Err(error!(
+ item.self_ty,
+ "#[pinned_drop] may only be used on implementation for the `PinnedDrop` trait"
+ ));
+ }
+
+ if item.unsafety.is_some() {
+ return Err(error!(item.unsafety, "implementing the trait `PinnedDrop` is not unsafe"));
+ }
+ if item.items.is_empty() {
+ return Err(error!(item, "not all trait items implemented, missing: `drop`"));
+ }
+
+ for (i, item) in item.items.iter().enumerate() {
+ match item {
+ ImplItem::Const(item) => {
+ return Err(error!(
+ item,
+ "const `{}` is not a member of trait `PinnedDrop`", item.ident
+ ));
+ }
+ ImplItem::Type(item) => {
+ return Err(error!(
+ item,
+ "type `{}` is not a member of trait `PinnedDrop`", item.ident
+ ));
+ }
+ ImplItem::Method(method) => {
+ parse_method(method)?;
+ if i != 0 {
+ return Err(error!(method, "duplicate definitions with name `drop`"));
+ }
+ }
+ _ => parse_as_empty(&item.to_token_stream())?,
+ }
+ }
+
+ expand_item(item);
+
+ Ok(())
+}
+
+// from:
+//
+// fn drop(self: Pin<&mut Self>) {
+// // something
+// }
+//
+// into:
+//
+// unsafe fn drop(self: Pin<&mut Self>) {
+// fn __drop_inner<T>(__self: Pin<&mut Foo<'_, T>>) {
+// // something
+// }
+// __drop_inner(self);
+// }
+//
+fn expand_item(item: &mut ItemImpl) {
+ let method =
+ if let ImplItem::Method(method) = &mut item.items[0] { method } else { unreachable!() };
+ let mut drop_inner = method.clone();
+
+ // `fn drop(mut self: Pin<&mut Self>)` -> `fn __drop_inner<T>(mut __self: Pin<&mut Receiver>)`
+ drop_inner.sig.ident = Ident::new("__drop_inner", drop_inner.sig.ident.span());
+ drop_inner.sig.generics = item.generics.clone();
+ if let FnArg::Typed(arg) = &mut drop_inner.sig.inputs[0] {
+ if let Pat::Ident(ident) = &mut *arg.pat {
+ prepend_underscore_to_self(&mut ident.ident);
+ }
+ }
+ let mut visitor = ReplaceReceiver::new(&item.self_ty);
+ visitor.visit_signature_mut(&mut drop_inner.sig);
+ visitor.visit_block_mut(&mut drop_inner.block);
+
+ // `fn drop(mut self: Pin<&mut Self>)` -> `unsafe fn drop(self: Pin<&mut Self>)`
+ method.sig.unsafety = Some(token::Unsafe::default());
+ if let FnArg::Typed(arg) = &mut method.sig.inputs[0] {
+ if let Pat::Ident(ident) = &mut *arg.pat {
+ ident.mutability = None;
+ }
+ }
+
+ method.block = syn::parse_quote! {{
+ #drop_inner
+ __drop_inner(self);
+ }};
+}
diff --git a/third_party/rust/pin-project-internal/src/project.rs b/third_party/rust/pin-project-internal/src/project.rs
new file mode 100644
index 0000000000..92627d435b
--- /dev/null
+++ b/third_party/rust/pin-project-internal/src/project.rs
@@ -0,0 +1,286 @@
+use proc_macro2::{Span, TokenStream};
+use quote::ToTokens;
+use syn::{
+ visit_mut::{self, VisitMut},
+ *,
+};
+
+use crate::utils::*;
+
+pub(crate) fn attribute(args: &TokenStream, input: Stmt, mutability: Mutability) -> TokenStream {
+ parse_as_empty(args)
+ .and_then(|()| parse(input, mutability))
+ .unwrap_or_else(|e| e.to_compile_error())
+}
+
+fn replace_stmt(stmt: &mut Stmt, mutability: Mutability) -> Result<()> {
+ match stmt {
+ Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
+ Context::new(mutability).replace_expr_match(expr);
+ }
+ Stmt::Expr(Expr::If(expr_if)) => {
+ let mut expr_if = expr_if;
+ while let Expr::Let(ref mut expr) = &mut *expr_if.cond {
+ Context::new(mutability).replace_expr_let(expr);
+ if let Some((_, ref mut expr)) = expr_if.else_branch {
+ if let Expr::If(new_expr_if) = &mut **expr {
+ expr_if = new_expr_if;
+ continue;
+ }
+ }
+ break;
+ }
+ }
+ Stmt::Local(local) => Context::new(mutability).replace_local(local)?,
+ _ => {}
+ }
+ Ok(())
+}
+
+fn parse(mut stmt: Stmt, mutability: Mutability) -> Result<TokenStream> {
+ replace_stmt(&mut stmt, mutability)?;
+ match &mut stmt {
+ Stmt::Item(Item::Fn(item)) => replace_item_fn(item, mutability)?,
+ Stmt::Item(Item::Impl(item)) => replace_item_impl(item, mutability),
+ Stmt::Item(Item::Use(item)) => replace_item_use(item, mutability)?,
+ _ => {}
+ }
+
+ Ok(stmt.into_token_stream())
+}
+
+struct Context {
+ register: Option<(Ident, usize)>,
+ replaced: bool,
+ mutability: Mutability,
+}
+
+impl Context {
+ fn new(mutability: Mutability) -> Self {
+ Self { register: None, replaced: false, mutability }
+ }
+
+ fn update(&mut self, ident: &Ident, len: usize) {
+ if self.register.is_none() {
+ self.register = Some((ident.clone(), len));
+ }
+ }
+
+ fn compare_paths(&self, ident: &Ident, len: usize) -> bool {
+ match &self.register {
+ Some((i, l)) => *l == len && ident == i,
+ None => false,
+ }
+ }
+
+ fn replace_local(&mut self, local: &mut Local) -> Result<()> {
+ if let Some(Expr::Match(expr)) = local.init.as_mut().map(|(_, expr)| &mut **expr) {
+ self.replace_expr_match(expr);
+ }
+
+ if self.replaced {
+ if is_replaceable(&local.pat, false) {
+ return Err(error!(
+ local.pat,
+ "Both initializer expression and pattern are replaceable, \
+ you need to split the initializer expression into separate let bindings \
+ to avoid ambiguity"
+ ));
+ }
+ } else {
+ self.replace_pat(&mut local.pat, false);
+ }
+
+ Ok(())
+ }
+
+ fn replace_expr_let(&mut self, expr: &mut ExprLet) {
+ self.replace_pat(&mut expr.pat, true)
+ }
+
+ fn replace_expr_match(&mut self, expr: &mut ExprMatch) {
+ expr.arms.iter_mut().for_each(|Arm { pat, .. }| self.replace_pat(pat, true))
+ }
+
+ fn replace_pat(&mut self, pat: &mut Pat, allow_pat_path: bool) {
+ match pat {
+ Pat::Ident(PatIdent { subpat: Some((_, pat)), .. })
+ | Pat::Reference(PatReference { pat, .. })
+ | Pat::Box(PatBox { pat, .. })
+ | Pat::Type(PatType { pat, .. }) => self.replace_pat(pat, allow_pat_path),
+
+ Pat::Or(PatOr { cases, .. }) => {
+ cases.iter_mut().for_each(|pat| self.replace_pat(pat, allow_pat_path))
+ }
+
+ Pat::Struct(PatStruct { path, .. }) | Pat::TupleStruct(PatTupleStruct { path, .. }) => {
+ self.replace_path(path)
+ }
+ Pat::Path(PatPath { qself: None, path, .. }) if allow_pat_path => {
+ self.replace_path(path)
+ }
+ _ => {}
+ }
+ }
+
+ fn replace_path(&mut self, path: &mut Path) {
+ let len = match path.segments.len() {
+ // 1: struct
+ // 2: enum
+ len @ 1 | len @ 2 => len,
+ // other path
+ _ => return,
+ };
+
+ if self.register.is_none() || self.compare_paths(&path.segments[0].ident, len) {
+ self.update(&path.segments[0].ident, len);
+ self.replaced = true;
+ replace_ident(&mut path.segments[0].ident, self.mutability);
+ }
+ }
+}
+
+fn is_replaceable(pat: &Pat, allow_pat_path: bool) -> bool {
+ match pat {
+ Pat::Ident(PatIdent { subpat: Some((_, pat)), .. })
+ | Pat::Reference(PatReference { pat, .. })
+ | Pat::Box(PatBox { pat, .. })
+ | Pat::Type(PatType { pat, .. }) => is_replaceable(pat, allow_pat_path),
+
+ Pat::Or(PatOr { cases, .. }) => cases.iter().any(|pat| is_replaceable(pat, allow_pat_path)),
+
+ Pat::Struct(_) | Pat::TupleStruct(_) => true,
+ Pat::Path(PatPath { qself: None, .. }) => allow_pat_path,
+ _ => false,
+ }
+}
+
+fn replace_item_impl(item: &mut ItemImpl, mutability: Mutability) {
+ let PathSegment { ident, arguments } = match &mut *item.self_ty {
+ Type::Path(TypePath { qself: None, path }) => path.segments.last_mut().unwrap(),
+ _ => return,
+ };
+
+ replace_ident(ident, mutability);
+
+ let mut lifetime_name = String::from(DEFAULT_LIFETIME_NAME);
+ determine_lifetime_name(&mut lifetime_name, &item.generics.params);
+ item.items
+ .iter_mut()
+ .filter_map(|i| if let ImplItem::Method(i) = i { Some(i) } else { None })
+ .for_each(|item| determine_lifetime_name(&mut lifetime_name, &item.sig.generics.params));
+ let lifetime = Lifetime::new(&lifetime_name, Span::call_site());
+
+ insert_lifetime(&mut item.generics, lifetime.clone());
+
+ match arguments {
+ PathArguments::None => {
+ *arguments = PathArguments::AngleBracketed(syn::parse_quote!(<#lifetime>));
+ }
+ PathArguments::AngleBracketed(args) => {
+ args.args.insert(0, syn::parse_quote!(#lifetime));
+ }
+ PathArguments::Parenthesized(_) => unreachable!(),
+ }
+}
+
+fn replace_item_fn(item: &mut ItemFn, mutability: Mutability) -> Result<()> {
+ let mut visitor = FnVisitor { res: Ok(()), mutability };
+ visitor.visit_block_mut(&mut item.block);
+ visitor.res
+}
+
+fn replace_item_use(item: &mut ItemUse, mutability: Mutability) -> Result<()> {
+ let mut visitor = UseTreeVisitor { res: Ok(()), mutability };
+ visitor.visit_item_use_mut(item);
+ visitor.res
+}
+
+fn replace_ident(ident: &mut Ident, mutability: Mutability) {
+ *ident = proj_ident(ident, mutability);
+}
+
+// =================================================================================================
+// visitors
+
+struct FnVisitor {
+ res: Result<()>,
+ mutability: Mutability,
+}
+
+impl FnVisitor {
+ /// Returns the attribute name.
+ fn name(&self) -> &str {
+ if self.mutability == Mutable { "project" } else { "project_ref" }
+ }
+
+ fn visit_stmt(&mut self, node: &mut Stmt) -> Result<()> {
+ let attr = match node {
+ Stmt::Expr(Expr::Match(expr)) | Stmt::Semi(Expr::Match(expr), _) => {
+ expr.attrs.find_remove(self.name())?
+ }
+ Stmt::Local(local) => local.attrs.find_remove(self.name())?,
+ Stmt::Expr(Expr::If(expr_if)) => {
+ if let Expr::Let(_) = &*expr_if.cond {
+ expr_if.attrs.find_remove(self.name())?
+ } else {
+ None
+ }
+ }
+ _ => return Ok(()),
+ };
+ if let Some(attr) = attr {
+ parse_as_empty(&attr.tokens)?;
+ replace_stmt(node, self.mutability)?;
+ }
+ Ok(())
+ }
+}
+
+impl VisitMut for FnVisitor {
+ fn visit_stmt_mut(&mut self, node: &mut Stmt) {
+ if self.res.is_err() {
+ return;
+ }
+
+ visit_mut::visit_stmt_mut(self, node);
+
+ if let Err(e) = self.visit_stmt(node) {
+ self.res = Err(e)
+ }
+ }
+
+ fn visit_item_mut(&mut self, _: &mut Item) {
+ // Do not recurse into nested items.
+ }
+}
+
+struct UseTreeVisitor {
+ res: Result<()>,
+ mutability: Mutability,
+}
+
+impl VisitMut for UseTreeVisitor {
+ fn visit_use_tree_mut(&mut self, node: &mut UseTree) {
+ if self.res.is_err() {
+ return;
+ }
+
+ match node {
+ // Desugar `use tree::<name>` into `tree::__<name>Projection`.
+ UseTree::Name(name) => replace_ident(&mut name.ident, self.mutability),
+ UseTree::Glob(glob) => {
+ self.res =
+ Err(error!(glob, "#[project] attribute may not be used on glob imports"));
+ }
+ UseTree::Rename(rename) => {
+ // TODO: Consider allowing the projected type to be renamed by `#[project] use Foo as Bar`.
+ self.res =
+ Err(error!(rename, "#[project] attribute may not be used on renamed imports"));
+ }
+ node @ UseTree::Path(_) | node @ UseTree::Group(_) => {
+ visit_mut::visit_use_tree_mut(self, node)
+ }
+ }
+ }
+}
diff --git a/third_party/rust/pin-project-internal/src/utils.rs b/third_party/rust/pin-project-internal/src/utils.rs
new file mode 100644
index 0000000000..1890afcf36
--- /dev/null
+++ b/third_party/rust/pin-project-internal/src/utils.rs
@@ -0,0 +1,339 @@
+use std::mem;
+
+use proc_macro2::{Group, TokenStream, TokenTree};
+use quote::{format_ident, quote_spanned};
+use syn::{
+ parse::{ParseBuffer, ParseStream},
+ punctuated::Punctuated,
+ token::{self, Comma},
+ visit_mut::{self, VisitMut},
+ *,
+};
+
+pub(crate) const DEFAULT_LIFETIME_NAME: &str = "'pin";
+pub(crate) const CURRENT_PRIVATE_MODULE: &str = "__private";
+
+pub(crate) type Variants = Punctuated<Variant, token::Comma>;
+
+pub(crate) use Mutability::{Immutable, Mutable};
+
+macro_rules! error {
+ ($span:expr, $msg:expr) => {
+ syn::Error::new_spanned(&$span, $msg)
+ };
+ ($span:expr, $($tt:tt)*) => {
+ error!($span, format!($($tt)*))
+ };
+}
+
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub(crate) enum Mutability {
+ Mutable,
+ Immutable,
+}
+
+/// Creates the ident of projected type from the ident of the original type.
+pub(crate) fn proj_ident(ident: &Ident, mutability: Mutability) -> Ident {
+ if mutability == Mutable {
+ format_ident!("__{}Projection", ident)
+ } else {
+ format_ident!("__{}ProjectionRef", ident)
+ }
+}
+
+/// Determines the lifetime names. Ensure it doesn't overlap with any existing lifetime names.
+pub(crate) fn determine_lifetime_name(
+ lifetime_name: &mut String,
+ generics: &Punctuated<GenericParam, Comma>,
+) {
+ let existing_lifetimes: Vec<String> = generics
+ .iter()
+ .filter_map(|param| {
+ if let GenericParam::Lifetime(LifetimeDef { lifetime, .. }) = param {
+ Some(lifetime.to_string())
+ } else {
+ None
+ }
+ })
+ .collect();
+ while existing_lifetimes.iter().any(|name| name.starts_with(&**lifetime_name)) {
+ lifetime_name.push('_');
+ }
+}
+
+/// Like `insert_lifetime`, but also generates a bound of the form
+/// `OriginalType<A, B>: 'lifetime`. Used when generating the definition
+/// of a projection type
+pub(crate) fn insert_lifetime_and_bound(
+ generics: &mut Generics,
+ lifetime: Lifetime,
+ orig_generics: &Generics,
+ orig_ident: Ident,
+) -> WherePredicate {
+ insert_lifetime(generics, lifetime.clone());
+
+ let orig_type: syn::Type = syn::parse_quote!(#orig_ident #orig_generics);
+ let mut punct = Punctuated::new();
+ punct.push(TypeParamBound::Lifetime(lifetime));
+
+ WherePredicate::Type(PredicateType {
+ lifetimes: None,
+ bounded_ty: orig_type,
+ colon_token: syn::token::Colon::default(),
+ bounds: punct,
+ })
+}
+
+/// Inserts a `lifetime` at position `0` of `generics.params`.
+pub(crate) fn insert_lifetime(generics: &mut Generics, lifetime: Lifetime) {
+ if generics.lt_token.is_none() {
+ generics.lt_token = Some(token::Lt::default())
+ }
+ if generics.gt_token.is_none() {
+ generics.gt_token = Some(token::Gt::default())
+ }
+
+ generics.params.insert(
+ 0,
+ GenericParam::Lifetime(LifetimeDef {
+ attrs: Vec::new(),
+ lifetime,
+ colon_token: None,
+ bounds: Punctuated::new(),
+ }),
+ );
+}
+
+/// Determines the visibility of the projected type and projection method.
+pub(crate) fn determine_visibility(vis: &Visibility) -> Visibility {
+ if let Visibility::Public(token) = vis {
+ syn::parse2(quote_spanned! { token.pub_token.span =>
+ pub(crate)
+ })
+ .unwrap()
+ } else {
+ vis.clone()
+ }
+}
+
+/// Check if `tokens` is an empty `TokenStream`.
+/// This is almost equivalent to `syn::parse2::<Nothing>()`,
+/// but produces a better error message and does not require ownership of `tokens`.
+pub(crate) fn parse_as_empty(tokens: &TokenStream) -> Result<()> {
+ if tokens.is_empty() { Ok(()) } else { Err(error!(tokens, "unexpected token: {}", tokens)) }
+}
+
+// =================================================================================================
+// extension traits
+
+pub(crate) trait SliceExt {
+ fn position_exact(&self, ident: &str) -> Result<Option<usize>>;
+ fn find(&self, ident: &str) -> Option<&Attribute>;
+ fn find_exact(&self, ident: &str) -> Result<Option<&Attribute>>;
+}
+
+pub(crate) trait VecExt {
+ fn find_remove(&mut self, ident: &str) -> Result<Option<Attribute>>;
+}
+
+impl SliceExt for [Attribute] {
+ fn position_exact(&self, ident: &str) -> Result<Option<usize>> {
+ self.iter()
+ .try_fold((0, None), |(i, mut prev), attr| {
+ if attr.path.is_ident(ident) {
+ if prev.is_some() {
+ return Err(error!(attr, "duplicate #[{}] attribute", ident));
+ }
+ parse_as_empty(&attr.tokens)?;
+ prev = Some(i);
+ }
+ Ok((i + 1, prev))
+ })
+ .map(|(_, pos)| pos)
+ }
+
+ fn find(&self, ident: &str) -> Option<&Attribute> {
+ self.iter().position(|attr| attr.path.is_ident(ident)).and_then(|i| self.get(i))
+ }
+
+ fn find_exact(&self, ident: &str) -> Result<Option<&Attribute>> {
+ self.position_exact(ident).map(|pos| pos.and_then(|i| self.get(i)))
+ }
+}
+
+impl VecExt for Vec<Attribute> {
+ fn find_remove(&mut self, ident: &str) -> Result<Option<Attribute>> {
+ self.position_exact(ident).map(|pos| pos.map(|i| self.remove(i)))
+ }
+}
+
+pub(crate) trait ParseBufferExt<'a> {
+ fn parenthesized(self) -> Result<ParseBuffer<'a>>;
+}
+
+impl<'a> ParseBufferExt<'a> for ParseStream<'a> {
+ fn parenthesized(self) -> Result<ParseBuffer<'a>> {
+ let content;
+ let _: token::Paren = syn::parenthesized!(content in self);
+ Ok(content)
+ }
+}
+
+impl<'a> ParseBufferExt<'a> for ParseBuffer<'a> {
+ fn parenthesized(self) -> Result<ParseBuffer<'a>> {
+ let content;
+ let _: token::Paren = syn::parenthesized!(content in self);
+ Ok(content)
+ }
+}
+
+// =================================================================================================
+// visitors
+
+// Replace `self`/`Self` with `__self`/`self_ty`.
+// Based on https://github.com/dtolnay/async-trait/blob/0.1.22/src/receiver.rs
+
+pub(crate) struct ReplaceReceiver<'a> {
+ self_ty: &'a Type,
+}
+
+impl<'a> ReplaceReceiver<'a> {
+ pub(crate) fn new(self_ty: &'a Type) -> Self {
+ Self { self_ty }
+ }
+
+ fn self_to_qself(&mut self, qself: &mut Option<QSelf>, path: &mut Path) {
+ if path.leading_colon.is_some() {
+ return;
+ }
+
+ let first = &path.segments[0];
+ if first.ident != "Self" || !first.arguments.is_empty() {
+ return;
+ }
+
+ if path.segments.len() == 1 {
+ self.self_to_expr_path(path);
+ return;
+ }
+
+ *qself = Some(QSelf {
+ lt_token: token::Lt::default(),
+ ty: Box::new(self.self_ty.clone()),
+ position: 0,
+ as_token: None,
+ gt_token: token::Gt::default(),
+ });
+
+ match path.segments.pairs().next().unwrap().punct() {
+ Some(&&colon) => path.leading_colon = Some(colon),
+ None => return,
+ }
+
+ let segments = mem::replace(&mut path.segments, Punctuated::new());
+ path.segments = segments.into_pairs().skip(1).collect();
+ }
+
+ fn self_to_expr_path(&self, path: &mut Path) {
+ if let Type::Path(self_ty) = &self.self_ty {
+ *path = self_ty.path.clone();
+ for segment in &mut path.segments {
+ if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
+ if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
+ bracketed.colon2_token = Some(token::Colon2::default());
+ }
+ }
+ }
+ } else {
+ let span = path.segments[0].ident.span();
+ let msg = "Self type of this impl is unsupported in expression position";
+ let error = Error::new(span, msg).to_compile_error();
+ *path = parse_quote!(::core::marker::PhantomData::<#error>);
+ }
+ }
+}
+
+impl VisitMut for ReplaceReceiver<'_> {
+ // `Self` -> `Receiver`
+ fn visit_type_mut(&mut self, ty: &mut Type) {
+ if let Type::Path(node) = ty {
+ if node.qself.is_none() && node.path.is_ident("Self") {
+ *ty = self.self_ty.clone();
+ } else {
+ self.visit_type_path_mut(node);
+ }
+ } else {
+ visit_mut::visit_type_mut(self, ty);
+ }
+ }
+
+ // `Self::Assoc` -> `<Receiver>::Assoc`
+ fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
+ if ty.qself.is_none() {
+ self.self_to_qself(&mut ty.qself, &mut ty.path);
+ }
+ visit_mut::visit_type_path_mut(self, ty);
+ }
+
+ // `Self::method` -> `<Receiver>::method`
+ fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
+ if expr.qself.is_none() {
+ prepend_underscore_to_self(&mut expr.path.segments[0].ident);
+ self.self_to_qself(&mut expr.qself, &mut expr.path);
+ }
+ visit_mut::visit_expr_path_mut(self, expr);
+ }
+
+ fn visit_expr_struct_mut(&mut self, expr: &mut ExprStruct) {
+ if expr.path.is_ident("Self") {
+ self.self_to_expr_path(&mut expr.path);
+ }
+ visit_mut::visit_expr_struct_mut(self, expr);
+ }
+
+ fn visit_macro_mut(&mut self, node: &mut Macro) {
+ // We can't tell in general whether `self` inside a macro invocation
+ // refers to the self in the argument list or a different self
+ // introduced within the macro. Heuristic: if the macro input contains
+ // `fn`, then `self` is more likely to refer to something other than the
+ // outer function's self argument.
+ if !contains_fn(node.tokens.clone()) {
+ node.tokens = fold_token_stream(node.tokens.clone());
+ }
+ }
+
+ fn visit_item_mut(&mut self, _: &mut Item) {
+ // Do not recurse into nested items.
+ }
+}
+
+fn contains_fn(tokens: TokenStream) -> bool {
+ tokens.into_iter().any(|tt| match tt {
+ TokenTree::Ident(ident) => ident == "fn",
+ TokenTree::Group(group) => contains_fn(group.stream()),
+ _ => false,
+ })
+}
+
+fn fold_token_stream(tokens: TokenStream) -> TokenStream {
+ tokens
+ .into_iter()
+ .map(|tt| match tt {
+ TokenTree::Ident(mut ident) => {
+ prepend_underscore_to_self(&mut ident);
+ TokenTree::Ident(ident)
+ }
+ TokenTree::Group(group) => {
+ let content = fold_token_stream(group.stream());
+ TokenTree::Group(Group::new(group.delimiter(), content))
+ }
+ other => other,
+ })
+ .collect()
+}
+
+pub(crate) fn prepend_underscore_to_self(ident: &mut Ident) {
+ if ident == "self" {
+ *ident = Ident::new("__self", ident.span());
+ }
+}
diff --git a/third_party/rust/pin-project-lite/.cargo-checksum.json b/third_party/rust/pin-project-lite/.cargo-checksum.json
new file mode 100644
index 0000000000..1a7077d987
--- /dev/null
+++ b/third_party/rust/pin-project-lite/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"f3f611059446979ec88ad60bbc10c88b03344a78fe7352d1c96d8c90677ba81c","Cargo.toml":"8d385982debe367eb5fccfe3aca22147742db78b66b7dd67c43c33dc943c921d","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"c9dca7888b355c14d2506e7a2f5646f000e56c23312354767b3adb1efb10c7f3","ci/install-component.sh":"2d7d6276f1b2c90601bdad6c98213a26f65e332fd2433fd6649051d8145b01ef","ci/install-rust.sh":"1169f71b716fc1980ca2fcc0b3735b601519ac6d6808481bdd704714e13db9aa","src/lib.rs":"88d2496e42b17ee985f96b17ffee501e4ac3974031719d2836b48906563208b0","tests/compiletest.rs":"cd1e9f4bcecec60e95b2d5853162dbf60d20cea1e58c774142ce5731912ef47b","tests/test.rs":"880aea52c8c3ea1ebf9cb87a737cbc389d54cf99ba44a98262bc89644c8d7d90","tests/ui/conflict-drop.rs":"55e6809b5f59dd81e32c2c89b742c0c76db6b099a1d2621e5b882c0d20f92837","tests/ui/conflict-drop.stderr":"c6d2d419ec2eb06e1a2eb9b4541278415517acb55ad054cb4ced38a049eadcaf","tests/ui/conflict-unpin.rs":"51b3b6720fa581b63167d6ac941a1ea1bf739b09954931b2bc2f7abe2d934f26","tests/ui/conflict-unpin.stderr":"3966c1b4cefddf2892b967be69cddd4c56064c22ee80f275d51217ae0fee24e3","tests/ui/invalid-bounds.rs":"cfaa9530a84033a680ac21dbcccb7887e49c665fe9fa9a2d403d9f76a838bc58","tests/ui/invalid-bounds.stderr":"a6c2087dd408f0ff5790536dd162b9c849dc3b25b80438341e7974e2ff9760e6","tests/ui/invalid.rs":"7304bd4a5bac1419382742432cfa8af83535d7be8cfad52c661410e0e9e8207a","tests/ui/invalid.stderr":"cb935ec370a87ba511aeef64613e7351b2eac9e574b5a256c7cb3c30f4bd74a6","tests/ui/overlapping_lifetime_names.rs":"a64c42cc56fa4751d73a1db80a7deb568427dc96f30c1a29665067d8c0ecb2c9","tests/ui/overlapping_lifetime_names.stderr":"d0e4f80c1b9c262fd1937c092c6f046bad84b704000fe1bc2cb3790229e5df00","tests/ui/overlapping_unpin_struct.rs":"5fde23ef628d2dbd27377ffa472fc19b1c6873122f38c3fb1f84fda8602f55f3","tests/ui/overlapping_unpin_struct.stderr":"2a7590446a6efa299d4cf9b5e02699118c252658537d458bf1bfcc0837065611","tests/ui/packed.rs":"12b14e183c809b267f0feff0b6c8bf8d664315e6959d236bd7a0887fc226b9bf","tests/ui/packed.stderr":"b9cf7c2e9874ca27d3de03a87624cabebc0fe3772e1b5af0d795f018cf489f46","tests/ui/proper_unpin.rs":"274e59d488d2a1640b7aed707b80623800df19ed7277f28e8f2c463185a3b7a2","tests/ui/proper_unpin.stderr":"6ee5760ff8f19cc47f721ec9f63236f41dc84ae95f34d84b7fe0c13302a91431","tests/ui/unpin_sneaky.rs":"12e97a387ce1af6ee6a567687674aab70e96962a48f2433c39976d0b3e2c3341","tests/ui/unpin_sneaky.stderr":"9cec3997d07771c9cc1b4f6cb5da2e932945a7dda7146d7f44624d110d44fcf6","tests/ui/unsupported.rs":"14defa90e736f314bbbc219973929b77bdd22e5f7e4c4c88403db764f4d167d6","tests/ui/unsupported.stderr":"310a8a7ed4e8120fa570957800e6cc86ff5561580a241ab808092e99a1f3b8b2"},"package":"237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"} \ No newline at end of file
diff --git a/third_party/rust/pin-project-lite/CHANGELOG.md b/third_party/rust/pin-project-lite/CHANGELOG.md
new file mode 100644
index 0000000000..769ef91b21
--- /dev/null
+++ b/third_party/rust/pin-project-lite/CHANGELOG.md
@@ -0,0 +1,42 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+This project adheres to [Semantic Versioning](https://semver.org).
+
+## [Unreleased]
+
+## [0.1.4] - 2020-01-20
+
+* [Support ?Sized bounds in generic parameters.][9]
+
+[9]: https://github.com/taiki-e/pin-project-lite/pull/9
+
+## [0.1.3] - 2020-01-20
+
+* [Support lifetime bounds in generic parameters.][7]
+
+[7]: https://github.com/taiki-e/pin-project-lite/pull/7
+
+## [0.1.2] - 2020-01-05
+
+* [Support recognizing default generic parameters.][6]
+
+[6]: https://github.com/taiki-e/pin-project-lite/pull/6
+
+## [0.1.1] - 2019-11-15
+
+* [`pin_project!` macro now determines the visibility of the projection type/method is based on the original type.][5]
+
+[5]: https://github.com/taiki-e/pin-project-lite/pull/5
+
+## [0.1.0] - 2019-10-22
+
+Initial release
+
+[Unreleased]: https://github.com/taiki-e/pin-project-lite/compare/v0.1.4...HEAD
+[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/third_party/rust/pin-project-lite/Cargo.toml b/third_party/rust/pin-project-lite/Cargo.toml
new file mode 100644
index 0000000000..f646dc301b
--- /dev/null
+++ b/third_party/rust/pin-project-lite/Cargo.toml
@@ -0,0 +1,30 @@
+# 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 believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "pin-project-lite"
+version = "0.1.4"
+authors = ["Taiki Endo <te316e89@gmail.com>"]
+description = "A lightweight version of pin-project written with declarative macros.\n"
+homepage = "https://github.com/taiki-e/pin-project-lite"
+documentation = "https://docs.rs/pin-project-lite"
+readme = "README.md"
+keywords = ["pin", "macros"]
+categories = ["no-std", "rust-patterns"]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/taiki-e/pin-project-lite"
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.trybuild]
+version = "1.0"
diff --git a/third_party/rust/pin-project-lite/LICENSE-APACHE b/third_party/rust/pin-project-lite/LICENSE-APACHE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/rust/pin-project-lite/LICENSE-APACHE
@@ -0,0 +1,202 @@
+
+ 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
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/third_party/rust/pin-project-lite/LICENSE-MIT b/third_party/rust/pin-project-lite/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/pin-project-lite/LICENSE-MIT
@@ -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/third_party/rust/pin-project-lite/README.md b/third_party/rust/pin-project-lite/README.md
new file mode 100644
index 0000000000..0bc7bffb78
--- /dev/null
+++ b/third_party/rust/pin-project-lite/README.md
@@ -0,0 +1,105 @@
+# pin-project-lite
+
+[![crates-badge]][crates-url]
+[![docs-badge]][docs-url]
+[![license-badge]][license]
+[![rustc-badge]][rustc-url]
+
+[crates-badge]: https://img.shields.io/crates/v/pin-project-lite.svg
+[crates-url]: https://crates.io/crates/pin-project-lite
+[docs-badge]: https://docs.rs/pin-project-lite/badge.svg
+[docs-url]: https://docs.rs/pin-project-lite
+[license-badge]: https://img.shields.io/crates/l/pin-project-lite.svg
+[license]: #license
+[rustc-badge]: https://img.shields.io/badge/rustc-1.37+-lightgray.svg
+[rustc-url]: https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html
+
+A lightweight version of [pin-project] written with declarative macros.
+
+## Usage
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+pin-project-lite = "0.1"
+```
+
+The current pin-project-lite requires Rust 1.37 or later.
+
+## Examples
+
+```rust
+use pin_project_lite::pin_project;
+use std::pin::Pin;
+
+pin_project! {
+ struct Struct<T, U> {
+ #[pin]
+ pinned: T,
+ unpinned: U,
+ }
+}
+
+impl<T, U> Struct<T, U> {
+ fn foo(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
+ }
+}
+```
+
+## [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: Structs only
+
+pin-project-lite will refuse anything other than a braced struct with named fields. Enums and tuple structs are not supported.
+
+### Different: No support for custom Drop implementation
+
+[pin-project supports this.][pinned-drop]
+
+### Different: No support for custom Unpin implementation
+
+[pin-project supports this.][unsafe-unpin]
+
+### Different: No support for pattern matching and destructing
+
+[pin-project supports this.][projection-helper]
+
+[pin-project]: https://github.com/taiki-e/pin-project
+[pinned-drop]: https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#pinned_drop
+[unsafe-unpin]: https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html
+[projection-helper]: https://docs.rs/pin-project/0.4/pin_project/attr.project.html#let-bindings
+
+## License
+
+Licensed under either of
+
+* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
+* MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
diff --git a/third_party/rust/pin-project-lite/ci/install-component.sh b/third_party/rust/pin-project-lite/ci/install-component.sh
new file mode 100644
index 0000000000..943755c5b2
--- /dev/null
+++ b/third_party/rust/pin-project-lite/ci/install-component.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set -euo pipefail
+
+component="${1}"
+
+if ! rustup component add "${component}" 2>/dev/null; then
+ # If the component is unavailable on the latest nightly,
+ # use the latest toolchain with the component available.
+ # Refs: https://github.com/rust-lang/rustup-components-history#the-web-part
+ target=$(curl -sSf "https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/${component}")
+ echo "'${component}' is unavailable on the default toolchain, use the toolchain 'nightly-${target}' instead"
+
+ rustup update "nightly-${target}" --no-self-update
+ rustup default "nightly-${target}"
+
+ echo "Query rust and cargo versions:"
+ rustup -V
+ rustc -V
+ cargo -V
+
+ rustup component add "${component}"
+fi
+
+echo "Query component versions:"
+case "${component}" in
+ clippy | miri) cargo "${component}" -V ;;
+ rustfmt) "${component}" -V ;;
+esac
diff --git a/third_party/rust/pin-project-lite/ci/install-rust.sh b/third_party/rust/pin-project-lite/ci/install-rust.sh
new file mode 100644
index 0000000000..3e0b27ae84
--- /dev/null
+++ b/third_party/rust/pin-project-lite/ci/install-rust.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -euo pipefail
+
+toolchain="${1:-nightly}"
+
+if rustup -V 2>/dev/null; then
+ rustup set profile minimal
+ rustup update "${toolchain}" --no-self-update
+ rustup default "${toolchain}"
+else
+ curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "${toolchain}"
+ export PATH=${PATH}:${HOME}/.cargo/bin
+ echo "##[add-path]${HOME}/.cargo/bin"
+fi
+
+echo "Query rust and cargo versions:"
+rustup -V
+rustc -V
+cargo -V
diff --git a/third_party/rust/pin-project-lite/src/lib.rs b/third_party/rust/pin-project-lite/src/lib.rs
new file mode 100644
index 0000000000..2980ebaeba
--- /dev/null
+++ b/third_party/rust/pin-project-lite/src/lib.rs
@@ -0,0 +1,466 @@
+//! A lightweight version of [pin-project] written with declarative macros.
+//!
+//! ## Examples
+//!
+//! ```rust
+//! use pin_project_lite::pin_project;
+//! use std::pin::Pin;
+//!
+//! pin_project! {
+//! struct Struct<T, U> {
+//! #[pin]
+//! pinned: T,
+//! unpinned: U,
+//! }
+//! }
+//!
+//! impl<T, U> Struct<T, U> {
+//! fn foo(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
+//! }
+//! }
+//! ```
+//!
+//! ## [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: Structs only
+//!
+//! pin-project-lite will refuse anything other than a braced struct with named fields. Enums and tuple structs are not supported.
+//!
+//! ### Different: No support for custom Drop implementation
+//!
+//! [pin-project supports this.][pinned-drop]
+//!
+//! ### Different: No support for custom Unpin implementation
+//!
+//! [pin-project supports this.][unsafe-unpin]
+//!
+//! ### Different: No support for pattern matching and destructing
+//!
+//! [pin-project supports this.][projection-helper]
+//!
+//! [pin-project]: https://github.com/taiki-e/pin-project
+//! [pinned-drop]: https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html#pinned_drop
+//! [unsafe-unpin]: https://docs.rs/pin-project/0.4/pin_project/trait.UnsafeUnpin.html
+//! [projection-helper]: https://docs.rs/pin-project/0.4/pin_project/attr.project.html#let-bindings
+
+#![no_std]
+#![recursion_limit = "256"]
+#![doc(html_root_url = "https://docs.rs/pin-project-lite/0.1.4")]
+#![doc(test(
+ no_crate_inject,
+ attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code))
+))]
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(clippy::all)]
+// mem::take requires Rust 1.40
+#![allow(clippy::mem_replace_with_default)]
+
+/// A macro that creates a projection struct covering all the fields.
+///
+/// This macro creates a projection struct 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.
+///
+/// The following methods are implemented on the original type:
+///
+/// ```
+/// # 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<'_>;
+/// # }
+/// ```
+///
+/// The visibility of the projected type and projection method is based on the
+/// original type. However, if the visibility of the original type is `pub`,
+/// the visibility of the projected type and the projection method is `pub(crate)`.
+///
+/// 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`.
+///
+/// ## 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 pin_project_lite::pin_project;
+/// use std::pin::Pin;
+///
+/// pin_project! {
+/// struct Struct<T, U> {
+/// #[pin]
+/// pinned: T,
+/// unpinned: U,
+/// }
+/// }
+///
+/// impl<T, U> Struct<T, U> {
+/// fn foo(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
+/// }
+/// }
+/// ```
+///
+/// Note that borrowing the field where `#[pin]` attribute is used multiple
+/// times requires using [`.as_mut()`][`Pin::as_mut`] to avoid
+/// consuming the `Pin`.
+///
+/// [pin-project]: https://github.com/taiki-e/pin-project
+/// [`Pin::as_mut`]: core::pin::Pin::as_mut
+#[macro_export]
+macro_rules! pin_project {
+ // determine_visibility
+ (
+ $(#[$attrs:meta])*
+ pub struct $ident:ident
+ $(<
+ $( $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),* $(,)?
+ )?
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+ $(,)?
+ }
+ ) => {
+ $crate::pin_project! {@internal (pub(crate))
+ $(#[$attrs])*
+ pub struct $ident
+ $(<
+ $( $lifetime $(: $lifetime_bound)? ),*
+ $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ),*
+ >)?
+ $(where
+ $($where_clause_ty : $where_clause_bound),*
+ )?
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ };
+ (
+ $(#[$attrs:meta])*
+ $vis:vis struct $ident:ident
+ $(<
+ $( $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),* $(,)?
+ )?
+ {
+ $(
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+ $(,)?
+ }
+ ) => {
+ $crate::pin_project! {@internal ($vis)
+ $(#[$attrs])*
+ $vis struct $ident
+ $(<
+ $( $lifetime $(: $lifetime_bound)? ),*
+ $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ),*
+ >)?
+ $(where
+ $($where_clause_ty : $where_clause_bound),*
+ )?
+ {
+ $(
+ $(#[$pin])?
+ $field_vis $field: $field_ty
+ ),+
+ }
+ }
+ };
+
+ (@internal ($proj_vis:vis)
+ // limitation: does not support tuple structs and enums (wontfix)
+ // limitation: no projection helper (wontfix)
+ $(#[$attrs:meta])*
+ $vis:vis struct $ident:ident
+ $(<
+ $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),*
+ // limitation: does not support multiple trait/lifetime bounds and ? trait bounds.
+ $( $generics:ident $(: $generics_bound:path)? $(: ?$generics_unsized_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),*
+ >)?
+ $(where
+ // limitation: does not support multiple trait/lifetime bounds and ? trait bounds.
+ $($where_clause_ty:ty : $where_clause_bound:path),*
+ )?
+ {
+ $(
+ // limitation: cannot interoperate with other attributes.
+ $(#[$pin:ident])?
+ $field_vis:vis $field:ident: $field_ty:ty
+ ),+
+ }
+ ) => {
+ $(#[$attrs])*
+ $vis struct $ident
+ $(< $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? $(= $generics_default)? ,)* >)?
+ $(where
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {
+ $(
+ $field_vis $field: $field_ty
+ ),+
+ }
+
+ // limitation: underscore_const_names requires rust 1.37+ (wontfix)
+ const _: () = {
+ #[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ $proj_vis struct Projection
+ <'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?>
+ $(where
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {
+ $(
+ $field_vis $field: $crate::pin_project!(@make_proj_field $(#[$pin])? $field_ty; mut)
+ ),+
+ }
+ #[allow(dead_code)] // This lint warns unused fields/variants.
+ $proj_vis struct ProjectionRef
+ <'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?>
+ $(where
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {
+ $(
+ $field_vis $field: $crate::pin_project!(@make_proj_field $(#[$pin])? $field_ty;)
+ ),+
+ }
+
+ impl $(< $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* >)?
+ $ident $(< $($lifetime,)* $($generics),* >)?
+ $(where
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {
+ $proj_vis fn project<'__pin>(
+ self: ::core::pin::Pin<&'__pin mut Self>,
+ ) -> Projection<'__pin $(, $($lifetime,)* $($generics),* )?> {
+ unsafe {
+ let this = self.get_unchecked_mut();
+ Projection {
+ $(
+ $field: $crate::pin_project!(@make_unsafe_field_proj this; $(#[$pin])? $field; mut)
+ ),+
+ }
+ }
+ }
+ $proj_vis fn project_ref<'__pin>(
+ self: ::core::pin::Pin<&'__pin Self>,
+ ) -> ProjectionRef<'__pin $(, $($lifetime,)* $($generics),* )?> {
+ unsafe {
+ let this = self.get_ref();
+ ProjectionRef {
+ $(
+ $field: $crate::pin_project!(@make_unsafe_field_proj this; $(#[$pin])? $field;)
+ ),+
+ }
+ }
+ }
+ }
+
+ // 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 delcared within
+ // a function, which makes it impossible to be named by user code.
+ // This guarnatees 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', satisfiying 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.
+ $vis struct __Origin
+ <'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?>
+ $(where
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {
+ __dummy_lifetime: ::core::marker::PhantomData<&'__pin ()>,
+ $(
+ $field: $crate::pin_project!(@make_unpin_bound $(#[$pin])? $field_ty)
+ ),+
+ }
+ impl <'__pin $(, $( $lifetime $(: $lifetime_bound)? ,)* $($generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* )?> ::core::marker::Unpin
+ for $ident $(< $($lifetime,)* $($generics),* >)?
+ where
+ __Origin <'__pin $(, $($lifetime,)* $($generics),* )?>: ::core::marker::Unpin
+ $(,
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {
+ }
+
+ // 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 comflict 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)]
+ impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
+ #[allow(single_use_lifetimes)]
+ impl $(< $( $lifetime $(: $lifetime_bound)? ,)* $($generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),*>)? MustNotImplDrop
+ for $ident $(< $($lifetime,)* $($generics),* >)?
+ $(where
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {}
+
+ // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+ //
+ // Taking a reference to a packed field is unsafe, amd appplying
+ // #[deny(safe_packed_borrows)] makes sure that doing this without
+ // an 'unsafe' block (which we deliberately do not generate)
+ // is a hard error.
+ //
+ // If the struct ends up having #[repr(packed)] applied somehow,
+ // this will generate an (unfriendly) error message. Under all reasonable
+ // circumstances, we'll detect the #[repr(packed)] attribute, and generate
+ // a much nicer error above.
+ //
+ // See https://github.com/taiki-e/pin-project/pull/34 for more details.
+ #[allow(single_use_lifetimes)]
+ #[allow(non_snake_case)]
+ #[deny(safe_packed_borrows)]
+ fn __assert_not_repr_packed
+ $(< $($lifetime $(: $lifetime_bound)? ,)* $( $generics $(: $generics_bound)? $(: ?$generics_unsized_bound)? $(: $generics_lifetime_bound)? ),* >)?
+ (
+ this: &$ident $(< $($lifetime,)* $($generics),* >)?
+ )
+ $(where
+ $($where_clause_ty: $where_clause_bound),*
+ )*
+ {
+ $(
+ &this.$field;
+ )+
+ }
+ };
+ };
+
+ // make_unpin_bound
+ (@make_unpin_bound
+ #[pin]
+ $field_ty:ty
+ ) => {
+ $field_ty
+ };
+ (@make_unpin_bound
+ $field_ty:ty
+ ) => {
+ $crate::__private::AlwaysUnpin<$field_ty>
+ };
+
+ // make_unsafe_field_proj
+ (@make_unsafe_field_proj
+ $this:ident;
+ #[pin]
+ $field:ident;
+ $($mut:ident)?
+ ) => {
+ ::core::pin::Pin::new_unchecked(&$($mut)? $this.$field)
+ };
+ (@make_unsafe_field_proj
+ $this:ident;
+ $field:ident;
+ $($mut:ident)?
+ ) => {
+ &$($mut)? $this.$field
+ };
+
+ // make_proj_field
+ (@make_proj_field
+ #[pin]
+ $field_ty:ty;
+ $($mut:ident)?
+ ) => {
+ ::core::pin::Pin<&'__pin $($mut)? ($field_ty)>
+ };
+ (@make_proj_field
+ $field_ty:ty;
+ $($mut:ident)?
+ ) => {
+ &'__pin $($mut)? ($field_ty)
+ };
+
+ // limitation: no useful error messages (wontfix)
+}
+
+// Not public API.
+#[doc(hidden)]
+pub mod __private {
+ use core::marker::PhantomData;
+
+ // 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> {}
+}
diff --git a/third_party/rust/pin-project-lite/tests/compiletest.rs b/third_party/rust/pin-project-lite/tests/compiletest.rs
new file mode 100644
index 0000000000..ae3df319f0
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/compiletest.rs
@@ -0,0 +1,9 @@
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+#[rustversion::attr(not(nightly), ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/third_party/rust/pin-project-lite/tests/test.rs b/third_party/rust/pin-project-lite/tests/test.rs
new file mode 100644
index 0000000000..9077149b6f
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/test.rs
@@ -0,0 +1,348 @@
+#![no_std]
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+use core::{marker::PhantomPinned, pin::Pin};
+use pin_project_lite::pin_project;
+
+#[test]
+fn test_pin_project() {
+ pin_project! {
+ struct Foo<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+ }
+
+ let mut foo = Foo { field1: 1, field2: 2 };
+
+ let mut foo_orig = Pin::new(&mut foo);
+ let foo = foo_orig.as_mut().project();
+
+ let x: Pin<&mut i32> = foo.field1;
+ assert_eq!(*x, 1);
+
+ let y: &mut i32 = foo.field2;
+ assert_eq!(*y, 2);
+
+ assert_eq!(foo_orig.as_ref().field1, 1);
+ assert_eq!(foo_orig.as_ref().field2, 2);
+
+ let mut foo = Foo { field1: 1, field2: 2 };
+
+ let foo = Pin::new(&mut foo).project();
+
+ let field1 = foo.field1;
+ let field2 = foo.field2;
+ let _: Pin<&mut i32> = field1;
+ let _: &mut i32 = field2;
+}
+
+#[test]
+fn where_clause_and_associated_type_fields() {
+ pin_project! {
+ struct Struct1<I>
+ where
+ I: Iterator,
+ {
+ #[pin]
+ field1: I,
+ field2: I::Item,
+ }
+ }
+
+ pin_project! {
+ struct Struct2<I, J>
+ where
+ I: Iterator<Item = J>,
+ {
+ #[pin]
+ field1: I,
+ field2: J,
+ }
+ }
+
+ // TODO(#7): where clause does not support yet.
+
+ // pin_project! {
+ // pub struct Struct3<T>
+ // where
+ // T: 'static,
+ // {
+ // field: T,
+ // }
+ // }
+
+ // trait Static: 'static {}
+
+ // impl<T> Static for Struct3<T> {}
+}
+
+// #[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+// #[test]
+// fn unsized_in_where_clause() {
+// pin_project! {
+// struct Struct<I>
+// where
+// I: ?Sized,
+// {
+// #[pin]
+// field: I,
+// }
+// }
+// }
+
+#[test]
+fn derive_copy() {
+ pin_project! {
+ #[derive(Clone, Copy)]
+ struct Struct<T> {
+ val: T,
+ }
+ }
+
+ fn is_copy<T: Copy>() {}
+
+ is_copy::<Struct<u8>>();
+}
+
+#[test]
+fn move_out() {
+ struct NotCopy;
+
+ pin_project! {
+ struct Struct {
+ val: NotCopy,
+ }
+ }
+
+ let foo = Struct { val: NotCopy };
+ let _val: NotCopy = foo.val;
+}
+
+#[test]
+fn trait_bounds_on_type_generics() {
+ pin_project! {
+ pub struct Struct1<'a, T: ?Sized> {
+ field: &'a mut T,
+ }
+ }
+
+ pin_project! {
+ pub struct Struct2<'a, T: ::core::fmt::Debug> {
+ field: &'a mut T,
+ }
+ }
+
+ pin_project! {
+ pub struct Struct3<'a, T: core::fmt::Debug> {
+ field: &'a mut T,
+ }
+ }
+
+ // pin_project! {
+ // pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {
+ // field: &'a mut T,
+ // }
+ // }
+
+ // pin_project! {
+ // pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {
+ // field: &'a mut T,
+ // }
+ // }
+
+ pin_project! {
+ pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {
+ field: &'a mut T,
+ }
+ }
+
+ let _: Struct6<'_> = Struct6 { field: &mut [0u8; 16] };
+
+ pin_project! {
+ pub struct Struct7<T: 'static> {
+ field: T,
+ }
+ }
+
+ trait Static: 'static {}
+
+ impl<T> Static for Struct7<T> {}
+
+ pin_project! {
+ pub struct Struct8<'a, 'b: 'a> {
+ field1: &'a u8,
+ field2: &'b u8,
+ }
+ }
+}
+
+#[test]
+fn private_type_in_public_type() {
+ pin_project! {
+ pub struct PublicStruct<T> {
+ #[pin]
+ inner: PrivateStruct<T>,
+ }
+ }
+
+ struct PrivateStruct<T>(T);
+}
+
+#[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 mut 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
+ }
+ }
+
+ impl<'b, T, U> Struct2<'b, T, U> {
+ fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b mut T> {
+ self.project_ref().pinned
+ }
+ fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b mut T> {
+ self.project().pinned
+ }
+ }
+}
+
+#[test]
+fn lifetime_project_elided() {
+ pin_project! {
+ struct Struct1<T, U> {
+ #[pin]
+ pinned: T,
+ unpinned: U,
+ }
+ }
+
+ pin_project! {
+ struct Struct2<'a, T, U> {
+ #[pin]
+ pinned: &'a mut T,
+ unpinned: U,
+ }
+ }
+
+ impl<T, U> Struct1<T, U> {
+ fn get_pin_ref(self: Pin<&Self>) -> Pin<&T> {
+ self.project_ref().pinned
+ }
+ fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
+ self.project().pinned
+ }
+ }
+
+ impl<'b, T, U> Struct2<'b, T, U> {
+ fn get_pin_ref(self: Pin<&Self>) -> Pin<&&'b mut T> {
+ self.project_ref().pinned
+ }
+ fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut &'b mut T> {
+ self.project().pinned
+ }
+ }
+}
+
+mod visibility {
+ use pin_project_lite::pin_project;
+
+ pin_project! {
+ pub(crate) struct A {
+ pub b: u8,
+ }
+ }
+}
+
+#[test]
+fn visibility() {
+ let mut x = visibility::A { b: 0 };
+ let x = Pin::new(&mut x);
+ let y = x.as_ref().project_ref();
+ let _: &u8 = y.b;
+ let y = x.project();
+ let _: &mut u8 = y.b;
+}
+
+#[test]
+fn trivial_bounds() {
+ pin_project! {
+ pub struct NoGenerics {
+ #[pin]
+ field: PhantomPinned,
+ }
+ }
+}
+
+#[test]
+fn dst() {
+ pin_project! {
+ pub struct A<T: ?Sized> {
+ x: T,
+ }
+ }
+
+ let _: &mut A<dyn core::fmt::Debug> = &mut A { x: 0u8 } as _;
+
+ pin_project! {
+ pub struct B<T: ?Sized> {
+ #[pin]
+ x: T,
+ }
+ }
+}
+
+#[test]
+fn dyn_type() {
+ pin_project! {
+ struct Struct1 {
+ a: i32,
+ f: dyn core::fmt::Debug,
+ }
+ }
+
+ pin_project! {
+ struct Struct2 {
+ a: i32,
+ #[pin]
+ f: dyn core::fmt::Debug,
+ }
+ }
+
+ pin_project! {
+ struct Struct3 {
+ a: i32,
+ f: dyn core::fmt::Debug + Send,
+ }
+ }
+
+ pin_project! {
+ struct Struct4 {
+ a: i32,
+ #[pin]
+ f: dyn core::fmt::Debug + Send,
+ }
+ }
+}
diff --git a/third_party/rust/pin-project-lite/tests/ui/conflict-drop.rs b/third_party/rust/pin-project-lite/tests/ui/conflict-drop.rs
new file mode 100644
index 0000000000..870059d62f
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/conflict-drop.rs
@@ -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/third_party/rust/pin-project-lite/tests/ui/conflict-drop.stderr b/third_party/rust/pin-project-lite/tests/ui/conflict-drop.stderr
new file mode 100644
index 0000000000..6679d3d244
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/conflict-drop.stderr
@@ -0,0 +1,16 @@
+error[E0119]: conflicting implementations of trait `_::MustNotImplDrop` for type `Foo<_, _>`:
+ --> $DIR/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 a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/third_party/rust/pin-project-lite/tests/ui/conflict-unpin.rs b/third_party/rust/pin-project-lite/tests/ui/conflict-unpin.rs
new file mode 100644
index 0000000000..f702f064de
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/conflict-unpin.rs
@@ -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/third_party/rust/pin-project-lite/tests/ui/conflict-unpin.stderr b/third_party/rust/pin-project-lite/tests/ui/conflict-unpin.stderr
new file mode 100644
index 0000000000..8065fde58b
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/conflict-unpin.stderr
@@ -0,0 +1,50 @@
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_, _>`:
+ --> $DIR/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 a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Bar<_, _>`:
+ --> $DIR/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 a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Baz<_, _>`:
+ --> $DIR/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 a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/third_party/rust/pin-project-lite/tests/ui/invalid-bounds.rs b/third_party/rust/pin-project-lite/tests/ui/invalid-bounds.rs
new file mode 100644
index 0000000000..980bb952ea
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/invalid-bounds.rs
@@ -0,0 +1,15 @@
+use pin_project_lite::pin_project;
+
+pin_project! {
+ struct A<T: 'static : ?Sized> { //~ ERROR no rules expected the token `:`
+ field: T,
+ }
+}
+
+pin_project! {
+ struct B<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+ field: T,
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project-lite/tests/ui/invalid-bounds.stderr b/third_party/rust/pin-project-lite/tests/ui/invalid-bounds.stderr
new file mode 100644
index 0000000000..ebd1da8179
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/invalid-bounds.stderr
@@ -0,0 +1,21 @@
+error: no rules expected the token `:`
+ --> $DIR/invalid-bounds.rs:4:25
+ |
+4 | struct A<T: 'static : ?Sized> { //~ ERROR no rules expected the token `:`
+ | ^ no rules expected this token in macro call
+
+error: expected one of `+`, `,`, `=`, or `>`, found `:`
+ --> $DIR/invalid-bounds.rs:9:1
+ |
+9 | / pin_project! {
+10 | | struct B<T: Sized : 'static> { //~ ERROR expected one of `+`, `,`, `=`, or `>`, found `:`
+11 | | field: T,
+12 | | }
+13 | | }
+ | | ^
+ | | |
+ | | expected one of `+`, `,`, `=`, or `>`
+ | |_unexpected token
+ | in this macro invocation
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/third_party/rust/pin-project-lite/tests/ui/invalid.rs b/third_party/rust/pin-project-lite/tests/ui/invalid.rs
new file mode 100644
index 0000000000..e0ea61d4f7
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/invalid.rs
@@ -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/third_party/rust/pin-project-lite/tests/ui/invalid.stderr b/third_party/rust/pin-project-lite/tests/ui/invalid.stderr
new file mode 100644
index 0000000000..f780e2e69a
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/invalid.stderr
@@ -0,0 +1,17 @@
+error: no rules expected the token `(`
+ --> $DIR/invalid.rs:5:14
+ |
+5 | #[pin()] //~ ERROR no rules expected the token `(`
+ | ^ no rules expected this token in macro call
+
+error: no rules expected the token `#`
+ --> $DIR/invalid.rs:20:9
+ |
+20 | #[pin] //~ ERROR no rules expected the token `#`
+ | ^ no rules expected this token in macro call
+
+error: cannot find attribute `pin` in this scope
+ --> $DIR/invalid.rs:11:7
+ |
+11 | #[pin] //~ ERROR cannot find attribute `pin` in this scope
+ | ^^^
diff --git a/third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.rs b/third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.rs
new file mode 100644
index 0000000000..87a737e2fa
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.rs
@@ -0,0 +1,10 @@
+use pin_project_lite::pin_project;
+
+pin_project! { //~ ERROR E0496
+ pub struct Foo<'__pin, T> { //~ ERROR E0263
+ #[pin]
+ field: &'__pin mut T,
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.stderr b/third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.stderr
new file mode 100644
index 0000000000..db4f5a8bb0
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/overlapping_lifetime_names.stderr
@@ -0,0 +1,83 @@
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> $DIR/overlapping_lifetime_names.rs:4:20
+ |
+3 | / pin_project! { //~ ERROR E0496
+4 | | pub struct Foo<'__pin, T> { //~ ERROR E0263
+ | | ^^^^^^ declared twice
+5 | | #[pin]
+6 | | field: &'__pin mut T,
+7 | | }
+8 | | }
+ | |_- previous declaration here
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> $DIR/overlapping_lifetime_names.rs:4:20
+ |
+3 | / pin_project! { //~ ERROR E0496
+4 | | pub struct Foo<'__pin, T> { //~ ERROR E0263
+ | | ^^^^^^ declared twice
+5 | | #[pin]
+6 | | field: &'__pin mut T,
+7 | | }
+8 | | }
+ | |_- previous declaration here
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0496]: lifetime name `'__pin` shadows a lifetime name that is already in scope
+ --> $DIR/overlapping_lifetime_names.rs:3:1
+ |
+3 | / pin_project! { //~ ERROR E0496
+4 | | pub struct Foo<'__pin, T> { //~ ERROR E0263
+ | | ------ first declared here
+5 | | #[pin]
+6 | | field: &'__pin mut T,
+7 | | }
+8 | | }
+ | |_^ lifetime '__pin already in scope
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0496]: lifetime name `'__pin` shadows a lifetime name that is already in scope
+ --> $DIR/overlapping_lifetime_names.rs:3:1
+ |
+3 | / pin_project! { //~ ERROR E0496
+4 | | pub struct Foo<'__pin, T> { //~ ERROR E0263
+ | | ------ first declared here
+5 | | #[pin]
+6 | | field: &'__pin mut T,
+7 | | }
+8 | | }
+ | |_^ lifetime '__pin already in scope
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> $DIR/overlapping_lifetime_names.rs:4:20
+ |
+3 | / pin_project! { //~ ERROR E0496
+4 | | pub struct Foo<'__pin, T> { //~ ERROR E0263
+ | | ^^^^^^ declared twice
+5 | | #[pin]
+6 | | field: &'__pin mut T,
+7 | | }
+8 | | }
+ | |_- previous declaration here
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0263]: lifetime name `'__pin` declared twice in the same scope
+ --> $DIR/overlapping_lifetime_names.rs:4:20
+ |
+3 | / pin_project! { //~ ERROR E0496
+4 | | pub struct Foo<'__pin, T> { //~ ERROR E0263
+ | | ^^^^^^ declared twice
+5 | | #[pin]
+6 | | field: &'__pin mut T,
+7 | | }
+8 | | }
+ | |_- previous declaration here
+ |
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.rs b/third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.rs
new file mode 100644
index 0000000000..1338524307
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.rs
@@ -0,0 +1,19 @@
+use pin_project_lite::pin_project;
+use std::marker::PhantomPinned;
+
+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/third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.stderr b/third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.stderr
new file mode 100644
index 0000000000..73db6f932b
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/overlapping_unpin_struct.stderr
@@ -0,0 +1,13 @@
+error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `_::__Origin<'_, std::marker::PhantomPinned>`
+ --> $DIR/overlapping_unpin_struct.rs:18:5
+ |
+15 | fn is_unpin<T: Unpin>() {}
+ | -------- ----- required by this bound in `is_unpin`
+...
+18 | is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Origin<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = help: the following implementations were found:
+ <std::marker::PhantomPinned as std::marker::Unpin>
+ = note: required because it appears within the type `_::__Origin<'_, std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned>`
diff --git a/third_party/rust/pin-project-lite/tests/ui/packed.rs b/third_party/rust/pin-project-lite/tests/ui/packed.rs
new file mode 100644
index 0000000000..0bccc1f216
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/packed.rs
@@ -0,0 +1,19 @@
+use pin_project_lite::pin_project;
+
+pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+ #[repr(packed, C)]
+ struct A {
+ #[pin]
+ field: u16,
+ }
+}
+
+pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+ #[repr(packed(2))]
+ struct C {
+ #[pin]
+ field: u32,
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project-lite/tests/ui/packed.stderr b/third_party/rust/pin-project-lite/tests/ui/packed.stderr
new file mode 100644
index 0000000000..1853377dec
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/packed.stderr
@@ -0,0 +1,55 @@
+error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
+ --> $DIR/packed.rs:3:1
+ |
+3 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+4 | | #[repr(packed, C)]
+5 | | struct A {
+6 | | #[pin]
+7 | | field: u16,
+8 | | }
+9 | | }
+ | |_^
+ |
+note: lint level defined here
+ --> $DIR/packed.rs:3:1
+ |
+3 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+4 | | #[repr(packed, C)]
+5 | | struct A {
+6 | | #[pin]
+7 | | field: u16,
+8 | | }
+9 | | }
+ | |_^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
+ = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
+ --> $DIR/packed.rs:11:1
+ |
+11 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+12 | | #[repr(packed(2))]
+13 | | struct C {
+14 | | #[pin]
+15 | | field: u32,
+16 | | }
+17 | | }
+ | |_^
+ |
+note: lint level defined here
+ --> $DIR/packed.rs:11:1
+ |
+11 | / pin_project! { //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+12 | | #[repr(packed(2))]
+13 | | struct C {
+14 | | #[pin]
+15 | | field: u32,
+16 | | }
+17 | | }
+ | |_^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
+ = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
+ = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
diff --git a/third_party/rust/pin-project-lite/tests/ui/proper_unpin.rs b/third_party/rust/pin-project-lite/tests/ui/proper_unpin.rs
new file mode 100644
index 0000000000..3c85f2d77f
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/proper_unpin.rs
@@ -0,0 +1,41 @@
+use pin_project_lite::pin_project;
+use std::marker::PhantomPinned;
+
+struct Inner<T> {
+ val: T,
+}
+
+pin_project! {
+ struct Foo<T, U> {
+ #[pin]
+ inner: Inner<T>,
+ other: U,
+ }
+}
+
+pin_project! {
+ pub struct TrivialBounds {
+ #[pin]
+ field1: PhantomPinned,
+ }
+}
+
+pin_project! {
+ struct Bar<'a, T, U> {
+ #[pin]
+ inner: &'a mut Inner<T>,
+ other: U,
+ }
+}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
+ is_unpin::<Foo<(), PhantomPinned>>(); // Ok
+ is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
+
+ is_unpin::<TrivialBounds>(); //~ ERROR E0277
+
+ is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ Ok
+}
diff --git a/third_party/rust/pin-project-lite/tests/ui/proper_unpin.stderr b/third_party/rust/pin-project-lite/tests/ui/proper_unpin.stderr
new file mode 100644
index 0000000000..52eb80223e
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/proper_unpin.stderr
@@ -0,0 +1,43 @@
+error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `_::__Origin<'_, std::marker::PhantomPinned, ()>`
+ --> $DIR/proper_unpin.rs:34:5
+ |
+31 | fn is_unpin<T: Unpin>() {}
+ | -------- ----- required by this bound in `is_unpin`
+...
+34 | is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Origin<'_, std::marker::PhantomPinned, ()>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = help: the following implementations were found:
+ <std::marker::PhantomPinned as std::marker::Unpin>
+ = note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
+ = note: required because it appears within the type `_::__Origin<'_, std::marker::PhantomPinned, ()>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, ()>`
+
+error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `_::__Origin<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
+ --> $DIR/proper_unpin.rs:36:5
+ |
+31 | fn is_unpin<T: Unpin>() {}
+ | -------- ----- required by this bound in `is_unpin`
+...
+36 | is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Origin<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = help: the following implementations were found:
+ <std::marker::PhantomPinned as std::marker::Unpin>
+ = note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
+ = note: required because it appears within the type `_::__Origin<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, std::marker::PhantomPinned>`
+
+error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `_::__Origin<'_>`
+ --> $DIR/proper_unpin.rs:38:5
+ |
+31 | fn is_unpin<T: Unpin>() {}
+ | -------- ----- required by this bound in `is_unpin`
+...
+38 | is_unpin::<TrivialBounds>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `_::__Origin<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = help: the following implementations were found:
+ <std::marker::PhantomPinned as std::marker::Unpin>
+ = note: required because it appears within the type `_::__Origin<'_>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
diff --git a/third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.rs b/third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.rs
new file mode 100644
index 0000000000..984cc2a219
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.rs
@@ -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/third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.stderr b/third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.stderr
new file mode 100644
index 0000000000..77ad2dc315
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/unpin_sneaky.stderr
@@ -0,0 +1,11 @@
+error[E0412]: cannot find type `__Origin` in this scope
+ --> $DIR/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 `std::marker::Unpin`, can only be implemented for a struct/enum type, not `[type error]`
+ --> $DIR/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/third_party/rust/pin-project-lite/tests/ui/unsupported.rs b/third_party/rust/pin-project-lite/tests/ui/unsupported.rs
new file mode 100644
index 0000000000..2f80836275
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/unsupported.rs
@@ -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/third_party/rust/pin-project-lite/tests/ui/unsupported.stderr b/third_party/rust/pin-project-lite/tests/ui/unsupported.stderr
new file mode 100644
index 0000000000..4f7b1aed09
--- /dev/null
+++ b/third_party/rust/pin-project-lite/tests/ui/unsupported.stderr
@@ -0,0 +1,29 @@
+error: no rules expected the token `}`
+ --> $DIR/unsupported.rs:4:21
+ |
+4 | struct Struct1 {} //~ ERROR no rules expected the token `}`
+ | ^ no rules expected this token in macro call
+
+error: no rules expected the token `(`
+ --> $DIR/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 `;`
+ --> $DIR/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`
+ --> $DIR/unsupported.rs:16:5
+ |
+16 | enum Enum { //~ ERROR no rules expected the token `enum`
+ | ^^^^ no rules expected this token in macro call
+
+error: no rules expected the token `union`
+ --> $DIR/unsupported.rs:22:5
+ |
+22 | union Union { //~ ERROR no rules expected the token `union`
+ | ^^^^^ no rules expected this token in macro call
diff --git a/third_party/rust/pin-project/.cargo-checksum.json b/third_party/rust/pin-project/.cargo-checksum.json
new file mode 100644
index 0000000000..05286ce214
--- /dev/null
+++ b/third_party/rust/pin-project/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"d724a57d897dcd5f087bb159a158acbb95ab950e9624481fc791edabbd5cc55a","Cargo.lock":"b4734689a9777d646ec24239f603651bf817731be4ead7dd2feb8b20049374f6","Cargo.toml":"61295703410f737a2e4bfe8a97762e9c01d64164ab82842bb7f601e851795609","LICENSE-APACHE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"79cf8fdde58cb1bb23be65a94e9cb4b37cc983dead3e9a95faf258734a983910","ci.sh":"0a3679631056481d69389a23600f6e42755397fbcbe8e5c23ae1c1154e080e41","ci/install-component.sh":"2d7d6276f1b2c90601bdad6c98213a26f65e332fd2433fd6649051d8145b01ef","ci/install-rust.sh":"1169f71b716fc1980ca2fcc0b3735b601519ac6d6808481bdd704714e13db9aa","compiletest.sh":"38ef7e86535fc8d04693ef88aab0527f08c802854fd37946b0b75aa2eb1880bd","examples/README.md":"8de7c0224f7cbf2fafdf969ea88e093f6ec53dac3534fe8f93217d7058fbd580","examples/enum-default-expanded.rs":"53b2a4148a3309e1b97e9f38dfa7b0222581a6ad3b9e34f097be4ecbcf448a3a","examples/enum-default.rs":"1fa270612b65eeaa03b7d4d0cf3845f7a58fced45869b87f8190fe0eebcc20a3","examples/pinned_drop-expanded.rs":"48484245a337c4534255a294c5c3a2ead8ed365b7e80e8d96b99b44b82f70509","examples/pinned_drop.rs":"42ead9c56eda3e7ee6ec835f4ec818763f92e51a4ee49774c74c7765ba7cc70d","examples/struct-default-expanded.rs":"cd4183f9d6639cfbb5e3e7648dcffca134330161e36f492c1162d7f19cdbf9ef","examples/struct-default.rs":"eb60ea5412e83ac9eba96794b31772afe0798bef304b26bff65b6845638bb729","examples/unsafe_unpin-expanded.rs":"a679ce33a596e2d2e8a46ad46d2c1bf2fae59325ef1f785e184cde9418d9a97a","examples/unsafe_unpin.rs":"55be3e2b93f32d94295c2e2d1af128d437659a557afd6a0fd97618e3ed6e5b4b","src/lib.rs":"ad1d16afe6f814747a1921b7460ed5e6b53dce45475ddd78042eee71410de28b","tests/cfg.rs":"6f7cdca06f2bd2b26154b3cdf9a8c52ea14c3e423e984b1fe348712eea5d44f4","tests/compiletest.rs":"be7b621d4778bf6ab64d3705cdb8b5d27d277eea44673f9982bfcad7e7f5d160","tests/no_infer_outlives.rs":"8ce3b21834a04789b93d3314d37af6ab8333b1f38bb0a2083a7fcbbca17afce7","tests/pin_project.rs":"927a9d3ff7db56fe6a436d72790cde8ee92548a3b0dc0280f0a3c24cbefbee8e","tests/pinned_drop.rs":"1f62999bdb5a5ee7a7fea21586d2c08323fb8ad1f6bd8eed31eeb2ab0bd480ef","tests/project.rs":"5cc7a7872a4c0c4b5eb6cbe481b01357263d1a070b66911bff3e4496846c38ff","tests/project_if_attr.rs.in":"7d068a1bfe0321ffdb8bcd52b7b430c0df3fdb883445d1964627a43d6379ab9e","tests/project_ref.rs":"92ba9726d07e6cacd530689ec77cea0b9a8dd1e09422bae17073403ebcd158b2","tests/repr_packed.rs":"1b1b84c4c7bfa5fbf0d03c1557410493d223268511900fd682e9c37d05bc289d","tests/ui/cfg/cfg_attr-resolve.rs":"f0807b6db56e2842d87cf694f929fd6695addf1ac4e8ce5fb83552447e1cb58d","tests/ui/cfg/cfg_attr-resolve.stderr":"ac9b092159e3af98edec4b6baf897590f532bc7f1569eb2a60c22713278f8d24","tests/ui/cfg/cfg_attr-type-mismatch.rs":"ef82a8dc600bad0fe861419119145d8f117cbe6ddbdbc5338dad8b7182756a2c","tests/ui/cfg/cfg_attr-type-mismatch.stderr":"eb880ef13a101062efeb5baef16fdbff276daeac039cbde6812c43e8a63efb72","tests/ui/cfg/cfg_attr-unpin.rs":"02cd72d7b6a9e08e85ec8cf3a325d773422c5ebe712213dc0907544d9976711e","tests/ui/cfg/cfg_attr-unpin.stderr":"53d74b22da1b18a1983d835d1948597fb8fb501a227c671a4dd0b3499803e6d8","tests/ui/cfg/packed_sneaky-span-issue-1.rs":"da9599823273527df8941d317d599c8772b13b866e49276c9efca8e1077532ae","tests/ui/cfg/packed_sneaky-span-issue-1.stderr":"2ee9dc9dd375b95f3d0440c8cfe4b3dae348f1a63973e5819e741b97faa034ae","tests/ui/cfg/packed_sneaky-span-issue-2.rs":"334cfa09e88452b6ad08d3566338a764b75f8b33fa9298019052459a45ad6516","tests/ui/cfg/packed_sneaky-span-issue-2.stderr":"2ee9dc9dd375b95f3d0440c8cfe4b3dae348f1a63973e5819e741b97faa034ae","tests/ui/cfg/packed_sneaky.rs":"7059ab47a1fa6c1ffdb2a5505e9c7bc51c8b20992cc0ce397e7a43b35bac7437","tests/ui/cfg/packed_sneaky.stderr":"e1a1004b1ba981fcf7ffe984496db3c898c48653fc0af8a15f2ebb118424229b","tests/ui/cfg/proper_unpin.rs":"3e6ddbe86e8ee2c4366f83ce7ef89428bba73b2bb1b8ede166b1ce3bb1e88696","tests/ui/cfg/proper_unpin.stderr":"9b9ae0c9a6521870bdd7e804d8a09a7701a5f2a918e66eeec72c20fa1815bae3","tests/ui/cfg/unsupported.rs":"b774675e0cee115c5e64ddd59008671de313d15b3b14de825f904bd25e1c3dea","tests/ui/cfg/unsupported.stderr":"d00396874289996e80a7a11e4df9e0adbcf0de52c8ef9c19cfd27cebdc7ba278","tests/ui/pin_project/add-attr-to-struct.rs":"1fde6b9e55191bc6297a5c8353da615293a2d8818886434544e8d91a4d3dd03f","tests/ui/pin_project/add-attr-to-struct.stderr":"8654c990dc52c6836a84dead5d87b0df3becd0639704dd1594b34c7dd89f73cd","tests/ui/pin_project/add-pinned-field.rs":"1704bfe7b31f1ea58b96507c730747aa109e890d48b7077096776403e8402278","tests/ui/pin_project/add-pinned-field.stderr":"cb4b226c5b6f39bbc5f8e7bc902d915774f04c310f388c3caf5226d180c3cf8d","tests/ui/pin_project/conflict-drop.rs":"93137ac53f3114038550037b304ee97c8f0e01c6f517bfdec32f9be867c5533b","tests/ui/pin_project/conflict-drop.stderr":"d7e18b7405ffe01196ffb3d65c3f67779430a1069e15c1a8c7a233ccc269df5d","tests/ui/pin_project/conflict-unpin.rs":"56d8f0eb22d547f5f9954bd37ca31c5b58b9d60bc5dc5b8c70f7d73cf8844649","tests/ui/pin_project/conflict-unpin.stderr":"3aed74d6895be645c3c81cdfc5f9a6ebfe3e7fa92713998b1a5dadf9b26c9709","tests/ui/pin_project/duplicate-argument.rs":"e4e3109d9afc23ebf1cbc5f87d5fb4749a460b1a2c6a583ca9c6ac6f9e163736","tests/ui/pin_project/duplicate-argument.stderr":"a44525259d06247b194f3906d90b7fb409fc9d49e0e1446a3dc53c147868938d","tests/ui/pin_project/invalid.rs":"11bbdcf64d87d42b8a26b5ae48139df1320b047f4b2b7dba19228531d60ac16e","tests/ui/pin_project/invalid.stderr":"24aef9cadd25685c4afbeff7d88a985e1c9fa873e300ad725143af6d5678b689","tests/ui/pin_project/overlapping_unpin_struct.rs":"d563525d945e970841002cc1f93822f50cfb9c81586363e2038a9aabf0a66ad3","tests/ui/pin_project/overlapping_unpin_struct.stderr":"223abbb21ae2dcc6711e0dc813c70dcb38f750ab001964ca0530622834a12d75","tests/ui/pin_project/packed.rs":"279fe7005a0a69bbafd2adc1d4b1e444c0e7dd284e101d0986190039bbb05017","tests/ui/pin_project/packed.stderr":"e71e8148eeb4ffe4d8e8fce0ab8d33da0bf7de993a64df0977bb473413773b62","tests/ui/pin_project/packed_sneaky-1.rs":"203499e8143f40fdcc61dbca31f96dbf3fa1bb91233dcc712be298b7765fc46f","tests/ui/pin_project/packed_sneaky-1.stderr":"ac490bd0b67b3740e9bac68115c07826ee9b6e6b99b35f9374f8ee7c6dfef7a8","tests/ui/pin_project/packed_sneaky-2.rs":"0716a5a40005b3ac558871804ed9ef809565fda35eef24c1c95d97ea5e9be6d7","tests/ui/pin_project/packed_sneaky-2.stderr":"7d9a3be663ed010b2d510c0d5a5a719df282630362786d73832c90276417b140","tests/ui/pin_project/private_in_public-enum.rs":"cf9b494164733abf98b9324141cfe666e734bb9d105166bd0f944d49452072ba","tests/ui/pin_project/private_in_public-enum.stderr":"ce58e5f6fd0d38e8f4d4215206aa341f11288442243715ca25803ab850ce3764","tests/ui/pin_project/proper_unpin.rs":"acc73e5f22373f4e91f1cfe652fd4ef27413e2dd0d5aa954b707aaa6ef15ec15","tests/ui/pin_project/proper_unpin.stderr":"69f80463679a6e899206ddd95438e12ba669060d0e957e87fc679ce9dd97269f","tests/ui/pin_project/remove-attr-from-field.rs":"e99ac2d655bde1a98e422fc1a0f7469eccbc0854abfe483c30b8464f30569533","tests/ui/pin_project/remove-attr-from-field.stderr":"bbf41a598b03a19dbd329affe7be05ad8f9c33071a5d805d2566f2c66303af00","tests/ui/pin_project/remove-attr-from-struct.rs":"2ecf262048e41551cde96f1fc419c89b93ba0bf15bd30eb13744e469655fb44b","tests/ui/pin_project/remove-attr-from-struct.stderr":"53527fbce3fe824952da9a6a4324dc46f0484452ac043cf1260de5193b7b0688","tests/ui/pin_project/safe_packed_borrows.rs":"01fae92d21252650befaaaac567b518641d45638a203a454a6735661f5f9d1b5","tests/ui/pin_project/safe_packed_borrows.stderr":"554bc0f7587ff26b22f51ca5de9786422fdb2a0bc4ea16c66b979bf0181e7cc6","tests/ui/pin_project/unpin_sneaky.rs":"7920d4e05142a0277bd9daeb40457586ec3be27372d797087aa9b693607efacd","tests/ui/pin_project/unpin_sneaky.stderr":"9e550974a9a5543749cbf4f2053ce3ed1bc2fbef95cc325e8cb5c7e9a09770e4","tests/ui/pin_project/unsupported.rs":"f10b8566fc25e971ebd16e0ec3be4e7371db637e3848d19840f11fef0cf0fc3d","tests/ui/pin_project/unsupported.stderr":"26cfc632dcef0bcf7f9cddb9db785f0931984f733224723e58f9490b2035e0d7","tests/ui/pinned_drop/forget-pinned-drop-impl.rs":"abea9c1477e0cd589c05b4405ecbf6f2b03e4de4ce36e57ea3c309e1e5db1a7a","tests/ui/pinned_drop/forget-pinned-drop-impl.stderr":"05d0eedce594fd5d4d204403bf1d5d62881c816449e31093fa4f90ed9d73b258","tests/ui/pinned_drop/invalid.rs":"80c3f83df81b2ebc0df4f31894f32c13813e1dcb0a08004f4d8777b4cacb258e","tests/ui/pinned_drop/invalid.stderr":"cb71637d4fd4e203897a281f7321e0e2ab604fabef1d390999d9dad84bc133d3","tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs":"6097441094e69ae18887171c8528900ae018707d3cfa03e2d3dc13fd06c58837","tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr":"af119418b4a88f62d538e248313596b0c528ceedaf79b94f99207f00860a634d","tests/ui/pinned_drop/ref-self.rs":"1252d4f1fd70cdff7b0fe3a105d99f5b5b6d1ccedff4f8b8b72a8c472a41a8bf","tests/ui/pinned_drop/ref-self.stderr":"ce4ae36ed0748d98e86971cd2cf1e78cc1a41b856d18ae3810a5c225a117d974","tests/ui/pinned_drop/self.rs":"4d059f302103eb6edc5a1f0a7d60a22c51612d8049ac16655ea4e80b9e532d09","tests/ui/pinned_drop/self.stderr":"5b4aede646efac30bd4b7fa4c40645c6ea1cdb733db15b6498631a7d9f2a2c59","tests/ui/pinned_drop/unsafe-code.rs":"8d0602d5f06ae3760caf094a6a211e9cc8526c261d6c39085d3f9a3c0ef6dd75","tests/ui/pinned_drop/unsafe-code.stderr":"ab3e8552f1643feacac3546b4f87ea87d59debc8b873d9002a5536ec248de090","tests/ui/project/ambiguous-let.rs":"151baeb436ddd82fcbe0892468400ffa8ed3edde7f722429d90fe916287d18cf","tests/ui/project/ambiguous-let.stderr":"e08aa651e416d9d410deef4f1b91b6204c107ca50a66ec17858c20c2e67c8db3","tests/ui/project/invalid.rs":"aa3f4f0a4b74ba92896f0b08ff8bd50ead31f9ebf4e4ed146b8b9e3c6666d365","tests/ui/project/invalid.stderr":"6b58ebe69f02dd9ce02c059197954f565e71d9f12d42572f89d5770d340130bc","tests/ui/project/type-mismatch.rs":"b358d3ea01a1a7434c23cb787e53179ee913b39173e55d3175d8782bee896312","tests/ui/project/type-mismatch.stderr":"dcebbb50aaa638d650dca10701df52e8d38baa01c801c32d5c20e81a1462c3f6","tests/ui/project/use-public.rs":"fb599e13b4d4a6f2409ea11730ef28b7713a0b0beef1b53841625864f0e8c6c7","tests/ui/project/use-public.stderr":"5092ddd2657a2d150607d38c6037865f40eba5683238cd3760242101b8e90fec","tests/ui/project/use.rs":"37d1536585bd6f9b7b8cf1560345524e2150fa19f5c1ec2ba49cbef3b9be881e","tests/ui/project/use.stderr":"b26e66da539d2d9c5470d00275bc7e315f89988e392a6563ee0663cf3ed5f51e","tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs":"cc63daa89bae170521449219e3b5b964decdcb4f5e7180d4df84ccc0031c0170","tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr":"1ce5a0a4ff8c5d225fd71a15a0819a02d7b8371bb0f12de112adf72f2ec698f7","tests/ui/unsafe_unpin/proper_unpin.rs":"00910ca9c09b80d038aa26c0b1fa4dda7d5699ba275d4c1114b0f26d24307628","tests/ui/unsafe_unpin/proper_unpin.stderr":"0d7115ce73b6dd4e11f55017ac3b342bae1a4b9453f7064ace8022cba3df3d16","tests/ui/unstable-features/README.md":"4d828aa223e725f5177513eb72fd0c9670f467aecdfbdd3d9758e35ab17f7daf","tests/ui/unstable-features/marker_trait_attr-feature-gate.rs":"164da6ff116be174646b4a458828f28460a55c226e9cd122e2d9144f5a2e9af7","tests/ui/unstable-features/marker_trait_attr-feature-gate.stderr":"46e18387c13f5715161b178bf772391231778c568e1a58f38027274a0f483eec","tests/ui/unstable-features/marker_trait_attr.rs":"f4a5aabb76983ac286f26fbf29127ead115700adcf4373b7e74f78e6162ff28c","tests/ui/unstable-features/marker_trait_attr.stderr":"94aa75cdcc28fb5c5c273040d24659686defb95f11223760c2c588b2c3c2a91c","tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs":"59f36a4b4e91fd97367679fd5decac8d603fc91a970df22e3f4628a5a02151da","tests/ui/unstable-features/overlapping_marker_traits-feature-gate.stderr":"d8858f24546c7bb6028e574c2c53aa616fe22f4283b9c3c49bf87bfcd5131ba1","tests/ui/unstable-features/overlapping_marker_traits.rs":"c6798ee243f36533b65905db7622f91976f54991ff1c75a176b3793b19278477","tests/ui/unstable-features/overlapping_marker_traits.stderr":"3918cf3f4070bf989e522998a78f77f73aee0a9c30db10e90c22ec7b37f5bc7d","tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs":"e4625be08f04772bb4fe05050e96596b5979663f5b590e29d5a3e3daa86c716c","tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs":"b9880f8db3d40317ac265785753741e3f4e0523fb5268b39f5c34460e08021c8","tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr":"76826477df6e75ed33f1264038b3fcdf2fec5f1f03821054a78869671c126e4f","tests/ui/unstable-features/trivial_bounds-bug.rs":"c5c62f5ebeebb58b4f43ab10944fa21e03350944e740738b35fcefbf922aef0c","tests/ui/unstable-features/trivial_bounds-bug.stderr":"75179b4f3ecb97b38afb535fd79d3e1ef041ac59dac66e350dc1ba411b4da965","tests/ui/unstable-features/trivial_bounds-feature-gate.rs":"e5006ca66b9023251e88669890b343cfab6479293bcb91af0b0637bb6834ac8b","tests/ui/unstable-features/trivial_bounds-feature-gate.stderr":"efb0930fc9ee50f60f6ee5e01a4bfea1a89becba9070010699e294b559d51728","tests/ui/unstable-features/trivial_bounds.rs":"e2b69a22254d6d6c1e30189165a94f86d5cb92b383c5534f80a7b6974d12f2cb","tests/ui/unstable-features/trivial_bounds.stderr":"1396ba918b519f524cc002d7c39397030d2508550d06f8268955e19608253a1b","tests/unsafe_unpin.rs":"ed069e36a98bcf879a6a3fd8f6ca824bd6d2a3120d96ed5304930372949086b4"},"package":"6f6a7f5eee6292c559c793430c55c00aea9d3b3d1905e855806ca4d7253426a2"} \ No newline at end of file
diff --git a/third_party/rust/pin-project/CHANGELOG.md b/third_party/rust/pin-project/CHANGELOG.md
new file mode 100644
index 0000000000..195948ac30
--- /dev/null
+++ b/third_party/rust/pin-project/CHANGELOG.md
@@ -0,0 +1,363 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+This project adheres to [Semantic Versioning](https://semver.org).
+
+## [Unreleased]
+
+## [0.4.9] - 2020-04-14
+
+* [Fixed lifetime inference error when associated types are used in fields.][188]
+
+* [Fixed compile error with tuple structs with `where` clauses.][186]
+
+* [`#[project]` attribute can now be used for `if let` expressions.][181]
+
+[188]: https://github.com/taiki-e/pin-project/pull/188
+[186]: https://github.com/taiki-e/pin-project/pull/186
+[181]: https://github.com/taiki-e/pin-project/pull/181
+
+## [0.4.8] - 2020-01-27
+
+* [Ensured that users cannot implement `PinnedDrop` without proper attribute argument.][180]
+
+[180]: https://github.com/taiki-e/pin-project/pull/180
+
+## [0.4.7] - 2020-01-20
+
+* [Fixed support for lifetime bounds.][176]
+
+[176]: https://github.com/taiki-e/pin-project/pull/176
+
+## [0.4.6] - 2019-11-20
+
+* [Fixed compile error when there is `Self` in the where clause.][169]
+
+[169]: https://github.com/taiki-e/pin-project/pull/169
+
+## [0.4.5] - 2019-10-21
+
+* [Fixed compile error with `dyn` types.][158]
+
+[158]: https://github.com/taiki-e/pin-project/pull/158
+
+## [0.4.4] - 2019-10-17
+
+* [Fixed an issue where `PinnedDrop` implementations can call unsafe code without an unsafe block.][149]
+
+[149]: https://github.com/taiki-e/pin-project/pull/149
+
+## [0.4.3] - 2019-10-15 - YANKED
+
+* [`#[pin_project]` can now interoperate with `#[cfg_attr()]`.][135]
+
+* [`#[pin_project]` can now interoperate with `#[cfg()]` on tuple structs and tuple variants.][135]
+
+* [Fixed support for DSTs(Dynamically Sized Types) on `#[pin_project(UnsafeUnpin)]`][120]
+
+[120]: https://github.com/taiki-e/pin-project/pull/120
+[135]: https://github.com/taiki-e/pin-project/pull/135
+
+## [0.4.2] - 2019-09-29 - YANKED
+
+* [Fixed support for DSTs(Dynamically Sized Types).][113]
+
+[113]: https://github.com/taiki-e/pin-project/pull/113
+
+## [0.4.1] - 2019-09-26 - YANKED
+
+* [Fixed an issue that caused an error when using `#[pin_project]` on a type that has `#[pin]` + `!Unpin` field with no generics or lifetime.][111]
+
+[111]: https://github.com/taiki-e/pin-project/pull/111
+
+## [0.4.0] - 2019-09-25 - YANKED
+
+* [**Pin projection has become a safe operation.**][18] In the absence of other unsafe code that you write, it is impossible to cause undefined behavior.
+
+* `#[unsafe_project]` attribute has been replaced with `#[pin_project]` attribute. ([#18][18], [#33][33])
+
+* [The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.][18]
+
+* Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl. ([#18][18], [#33][33], [#86][86])
+
+* [`Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.][18]
+
+* [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
+
+* [`#[pin_project]` can now be used for public type with private field types.][53]
+
+* [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
+
+* [Added `project_ref` method to `#[pin_project]` types.][93]
+
+* [Added `#[project_ref]` attribute.][93]
+
+* [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
+
+* [`#[project]` attribute can now be used for `impl` blocks.][46]
+
+* [`#[project]` attribute can now be used for `use` statements.][85]
+
+* [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
+
+Changes since the 0.4.0-beta.1 release:
+
+* [Fixed an issue that caused an error when using `#[pin_project(UnsafeUnpin)]` and not providing a manual `UnsafeUnpin` implementation on a type with no generics or lifetime.][107]
+
+[18]: https://github.com/taiki-e/pin-project/pull/18
+[33]: https://github.com/taiki-e/pin-project/pull/107
+[107]: https://github.com/taiki-e/pin-project/pull/107
+
+## [0.4.0-beta.1] - 2019-09-21
+
+* [Changed the argument type of project method back to `self: Pin<&mut Self>`.][90]
+
+* [Removed "project_attr" feature and always enable `#[project]` attribute.][94]
+
+* [Removed "renamed" feature.][100]
+
+* [`#[project]` attribute can now be used for `use` statements.][85]
+
+* [Added `project_ref` method and `#[project_ref]` attribute.][93]
+
+* [`#[pin_project]` attribute now determines the visibility of the projection type/method is based on the original type.][96]
+
+[85]: https://github.com/taiki-e/pin-project/pull/85
+[90]: https://github.com/taiki-e/pin-project/pull/90
+[93]: https://github.com/taiki-e/pin-project/pull/93
+[94]: https://github.com/taiki-e/pin-project/pull/94
+[96]: https://github.com/taiki-e/pin-project/pull/96
+[100]: https://github.com/taiki-e/pin-project/pull/100
+
+## [0.4.0-alpha.11] - 2019-09-11
+
+* [Changed #[pinned_drop] to trait implementation.][86]
+
+ ```rust
+ #[pinned_drop]
+ impl<T> PinnedDrop for Foo<'_, T> {
+ fn drop(mut self: Pin<&mut Self>) {
+ **self.project().was_dropped = true;
+ }
+ }
+ ```
+
+* Added some examples and generated code.
+
+* Improve error messages.
+
+[86]: https://github.com/taiki-e/pin-project/pull/86
+
+## [0.4.0-alpha.10] - 2019-09-07
+
+* [`#[pin_project]` can now interoperate with `#[cfg()]`.][77]
+
+* Improved documentation.
+
+[77]: https://github.com/taiki-e/pin-project/pull/77
+
+## [0.4.0-alpha.9] - 2019-09-05
+
+* [Added 'project_into' method to #[pin_project] types][69]. This can be useful when returning a pin projection from a method.
+ ```rust
+ fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
+ self.project_into().pinned
+ }
+ ```
+
+* [Prevented UnpinStruct from appearing in the document by default.][71] See [taiki-e/pin-project#71][71] for more details.
+
+[69]: https://github.com/taiki-e/pin-project/pull/69
+[71]: https://github.com/taiki-e/pin-project/pull/69
+
+## [0.4.0-alpha.8] - 2019-09-03
+
+* [Improved document of generated code.][62]. Also added an option to control the document of generated code. See [taiki-e/pin-project#62][62] for more details.
+
+* [Improved error messages][61]
+
+[61]: https://github.com/taiki-e/pin-project/pull/61
+[62]: https://github.com/taiki-e/pin-project/pull/62
+
+## [0.4.0-alpha.7] - 2019-09-02
+
+* [Applied `#[allow(dead_code)]` to generated types.][57]
+
+[57]: https://github.com/taiki-e/pin-project/pull/57
+
+## [0.4.0-alpha.6] - 2019-09-01
+
+* [Allowed using `#[pin_project]` type with private field types][53]
+
+[53]: https://github.com/taiki-e/pin-project/pull/53
+
+## [0.4.0-alpha.5] - 2019-08-24
+
+* [`#[project]` attribute now supports `match` expressions at the position of the initializer expression of `let` expressions.][51]
+
+[51]: https://github.com/taiki-e/pin-project/pull/51
+
+## [0.4.0-alpha.4] - 2019-08-23
+
+* Avoided clippy::drop_bounds lint in generated code.
+
+## [0.4.0-alpha.3] - 2019-08-23
+
+* [Changed `project` method generated by `#[pin_project]` attribute to take an `&mut Pin<&mut Self>` argument.][47]
+
+* [`#[project]` attribute can now be used for impl blocks.][46]
+
+* [`#[pin_project]` attribute can now detect that the type used does not have its own drop implementation without actually implementing drop.][48] This removed some restrictions.
+
+[46]: https://github.com/taiki-e/pin-project/pull/46
+[47]: https://github.com/taiki-e/pin-project/pull/47
+[48]: https://github.com/taiki-e/pin-project/pull/48
+
+## [0.4.0-alpha.2] - 2019-08-13
+
+* Updated `proc-macro2`, `syn`, and `quote` to 1.0.
+
+## [0.4.0-alpha.1] - 2019-08-11
+
+* **Pin projection has become a safe operation.**
+
+* `#[unsafe_project]` has been replaced with `#[pin_project]`.
+
+* The `Unpin` argument has been removed - an `Unpin` impl is now generated by default.
+
+* Drop impls must be specified with `#[pinned_drop]` instead of via a normal `Drop` impl.
+
+* `Unpin` impls must be specified with an impl of `UnsafeUnpin`, instead of implementing the normal `Unpin` trait.
+
+* Made `#[project]` attribute disabled by default.
+
+See also [tracking issue for 0.4 release][21].
+
+[21]: https://github.com/taiki-e/pin-project/issues/21
+
+## [0.3.5] - 2019-08-14
+
+* Updated `proc-macro2`, `syn`, and `quote` to 1.0.
+
+## [0.3.4] - 2019-07-21
+
+* Improved error messages.
+
+## [0.3.3] - 2019-07-15 - YANKED
+
+* Improved error messages.
+
+## [0.3.2] - 2019-03-30
+
+* Avoided suffixes on tuple index.
+
+## [0.3.1] - 2019-03-02
+
+* Improved documentation.
+
+* Updated minimum `syn` version to 0.15.22.
+
+## [0.3.0] - 2019-02-20
+
+* Removed `unsafe_fields` attribute.
+
+* Removed `unsafe_variants` attribute.
+
+## [0.2.2] - 2019-02-20
+
+* Fixed a bug that generates incorrect code for the some structures with trait bounds on type generics.
+
+## [0.2.1] - 2019-02-20
+
+* Fixed a bug that generates incorrect code for the structures with where clause and associated type fields.
+
+## [0.2.0] - 2019-02-11
+
+* Made `unsafe_fields` optional.
+
+* Improved documentation.
+
+## [0.1.8] - 2019-02-02
+
+* Added the feature to create projected enums to `unsafe_project`.
+
+* Added `project` attribute to support pattern matching.
+
+## [0.1.7] - 2019-01-19
+
+* Fixed documentation.
+
+## [0.1.6] - 2019-01-19
+
+* `unsafe_fields` can now opt-out.
+
+* Added `unsafe_variants` attribute. This attribute is available if pin-project is built with the "unsafe_variants" feature.
+
+## [0.1.5] - 2019-01-17
+
+* Added support for tuple struct to `unsafe_project`.
+
+## [0.1.4] - 2019-01-12
+
+* Added options for automatically implementing `Unpin` to both `unsafe_project` and `unsafe_fields`.
+
+## [0.1.3] - 2019-01-11
+
+* Fixed dependencies.
+
+* Added `unsafe_fields` attribute.
+
+## [0.1.2] - 2019-01-09
+
+* Improved documentation.
+
+## [0.1.1] - 2019-01-08
+
+* Renamed from `unsafe_pin_project` to `unsafe_project`.
+
+## [0.1.0] - 2019-01-08 - YANKED
+
+Initial release
+
+[Unreleased]: https://github.com/taiki-e/pin-project/compare/v0.4.9...HEAD
+[0.4.9]: https://github.com/taiki-e/pin-project/compare/v0.4.8...v0.4.9
+[0.4.8]: https://github.com/taiki-e/pin-project/compare/v0.4.7...v0.4.8
+[0.4.7]: https://github.com/taiki-e/pin-project/compare/v0.4.6...v0.4.7
+[0.4.6]: https://github.com/taiki-e/pin-project/compare/v0.4.5...v0.4.6
+[0.4.5]: https://github.com/taiki-e/pin-project/compare/v0.4.4...v0.4.5
+[0.4.4]: https://github.com/taiki-e/pin-project/compare/v0.4.3...v0.4.4
+[0.4.3]: https://github.com/taiki-e/pin-project/compare/v0.4.2...v0.4.3
+[0.4.2]: https://github.com/taiki-e/pin-project/compare/v0.4.1...v0.4.2
+[0.4.1]: https://github.com/taiki-e/pin-project/compare/v0.4.0...v0.4.1
+[0.4.0]: https://github.com/taiki-e/pin-project/compare/v0.4.0-beta.1...v0.4.0
+[0.4.0-beta.1]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.11...v0.4.0-beta.1
+[0.4.0-alpha.11]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.10...v0.4.0-alpha.11
+[0.4.0-alpha.10]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.9...v0.4.0-alpha.10
+[0.4.0-alpha.9]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.8...v0.4.0-alpha.9
+[0.4.0-alpha.8]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.7...v0.4.0-alpha.8
+[0.4.0-alpha.7]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.6...v0.4.0-alpha.7
+[0.4.0-alpha.6]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.5...v0.4.0-alpha.6
+[0.4.0-alpha.5]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.4...v0.4.0-alpha.5
+[0.4.0-alpha.4]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.3...v0.4.0-alpha.4
+[0.4.0-alpha.3]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.2...v0.4.0-alpha.3
+[0.4.0-alpha.2]: https://github.com/taiki-e/pin-project/compare/v0.4.0-alpha.1...v0.4.0-alpha.2
+[0.4.0-alpha.1]: https://github.com/taiki-e/pin-project/compare/v0.3.5...v0.4.0-alpha.1
+[0.3.5]: https://github.com/taiki-e/pin-project/compare/v0.3.4...v0.3.5
+[0.3.4]: https://github.com/taiki-e/pin-project/compare/v0.3.3...v0.3.4
+[0.3.3]: https://github.com/taiki-e/pin-project/compare/v0.3.2...v0.3.3
+[0.3.2]: https://github.com/taiki-e/pin-project/compare/v0.3.1...v0.3.2
+[0.3.1]: https://github.com/taiki-e/pin-project/compare/v0.3.0...v0.3.1
+[0.3.0]: https://github.com/taiki-e/pin-project/compare/v0.2.2...v0.3.0
+[0.2.2]: https://github.com/taiki-e/pin-project/compare/v0.2.1...v0.2.2
+[0.2.1]: https://github.com/taiki-e/pin-project/compare/v0.2.0...v0.2.1
+[0.2.0]: https://github.com/taiki-e/pin-project/compare/v0.1.8...v0.2.0
+[0.1.8]: https://github.com/taiki-e/pin-project/compare/v0.1.7...v0.1.8
+[0.1.7]: https://github.com/taiki-e/pin-project/compare/v0.1.6...v0.1.7
+[0.1.6]: https://github.com/taiki-e/pin-project/compare/v0.1.5...v0.1.6
+[0.1.5]: https://github.com/taiki-e/pin-project/compare/v0.1.4...v0.1.5
+[0.1.4]: https://github.com/taiki-e/pin-project/compare/v0.1.3...v0.1.4
+[0.1.3]: https://github.com/taiki-e/pin-project/compare/v0.1.2...v0.1.3
+[0.1.2]: https://github.com/taiki-e/pin-project/compare/v0.1.1...v0.1.2
+[0.1.1]: https://github.com/taiki-e/pin-project/compare/v0.1.0...v0.1.1
+[0.1.0]: https://github.com/taiki-e/pin-project/releases/tag/v0.1.0
diff --git a/third_party/rust/pin-project/Cargo.lock b/third_party/rust/pin-project/Cargo.lock
new file mode 100644
index 0000000000..2db8002ba9
--- /dev/null
+++ b/third_party/rust/pin-project/Cargo.lock
@@ -0,0 +1,56 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "pin-project"
+version = "0.4.9"
+dependencies = [
+ "pin-project-internal 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum pin-project-internal 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a"
+"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
+"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
+"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
+"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
diff --git a/third_party/rust/pin-project/Cargo.toml b/third_party/rust/pin-project/Cargo.toml
new file mode 100644
index 0000000000..b3ef6db911
--- /dev/null
+++ b/third_party/rust/pin-project/Cargo.toml
@@ -0,0 +1,28 @@
+# 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 believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "pin-project"
+version = "0.4.9"
+authors = ["Taiki Endo <te316e89@gmail.com>"]
+description = "A crate for safe and ergonomic pin-projection.\n"
+homepage = "https://github.com/taiki-e/pin-project"
+documentation = "https://docs.rs/pin-project"
+readme = "README.md"
+keywords = ["pin", "macros", "attribute"]
+categories = ["no-std", "rust-patterns"]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/taiki-e/pin-project"
+[dependencies.pin-project-internal]
+version = "=0.4.9"
+default-features = false
diff --git a/third_party/rust/pin-project/LICENSE-APACHE b/third_party/rust/pin-project/LICENSE-APACHE
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/third_party/rust/pin-project/LICENSE-APACHE
@@ -0,0 +1,202 @@
+
+ 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
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/third_party/rust/pin-project/LICENSE-MIT b/third_party/rust/pin-project/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/pin-project/LICENSE-MIT
@@ -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/third_party/rust/pin-project/README.md b/third_party/rust/pin-project/README.md
new file mode 100644
index 0000000000..a8bc573dcf
--- /dev/null
+++ b/third_party/rust/pin-project/README.md
@@ -0,0 +1,77 @@
+# pin-project
+
+[![crates-badge]][crates-url]
+[![docs-badge]][docs-url]
+[![license-badge]][license]
+[![rustc-badge]][rustc-url]
+
+[crates-badge]: https://img.shields.io/crates/v/pin-project.svg
+[crates-url]: https://crates.io/crates/pin-project
+[docs-badge]: https://docs.rs/pin-project/badge.svg
+[docs-url]: https://docs.rs/pin-project
+[license-badge]: https://img.shields.io/crates/l/pin-project.svg
+[license]: #license
+[rustc-badge]: https://img.shields.io/badge/rustc-1.33+-lightgray.svg
+[rustc-url]: https://blog.rust-lang.org/2019/02/28/Rust-1.33.0.html
+
+A crate for safe and ergonomic pin-projection.
+
+[Documentation][docs-url]
+
+[Examples](examples/README.md)
+
+## Usage
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+pin-project = "0.4"
+```
+
+The current pin-project requires Rust 1.33 or later.
+
+## Examples
+
+[`pin_project`] attribute creates a projection struct covering all the fields.
+
+```rust
+use pin_project::pin_project;
+use std::pin::Pin;
+
+#[pin_project]
+struct Struct<T, U> {
+ #[pin]
+ pinned: T,
+ unpinned: U,
+}
+
+impl<T, U> Struct<T, U> {
+ fn foo(self: Pin<&mut Self>) {
+ let this = self.project();
+ let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
+ let _: &mut U = this.unpinned; // Normal reference to the field
+ }
+}
+```
+
+[Code like this will be generated](examples/struct-default-expanded.rs)
+
+See [API documentation][docs-url] for more details.
+
+Also, there are examples and generated code of each feature in [examples](examples/README.md) directory.
+
+[`pin_project`]: https://docs.rs/pin-project/0.4/pin_project/attr.pin_project.html
+
+## License
+
+Licensed under either of
+
+* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
+* MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
diff --git a/third_party/rust/pin-project/ci.sh b/third_party/rust/pin-project/ci.sh
new file mode 100644
index 0000000000..016481d23b
--- /dev/null
+++ b/third_party/rust/pin-project/ci.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# A script to run a simplified version of the checks done by CI.
+#
+# Usage
+#
+# ```sh
+# . ./ci.sh
+# ```
+
+echo "Running 'cargo fmt -- --check'"
+cargo +nightly fmt --all -- --check
+
+echo "Running 'cargo clippy'"
+cargo +nightly clippy --all --all-features
+
+echo "Running 'cargo test'"
+cargo +nightly test --all --all-features
+
+echo "Running 'cargo doc'"
+cargo +nightly doc --no-deps --all --all-features
+
+echo "Running 'compiletest'"
+. ./compiletest.sh
diff --git a/third_party/rust/pin-project/ci/install-component.sh b/third_party/rust/pin-project/ci/install-component.sh
new file mode 100644
index 0000000000..943755c5b2
--- /dev/null
+++ b/third_party/rust/pin-project/ci/install-component.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set -euo pipefail
+
+component="${1}"
+
+if ! rustup component add "${component}" 2>/dev/null; then
+ # If the component is unavailable on the latest nightly,
+ # use the latest toolchain with the component available.
+ # Refs: https://github.com/rust-lang/rustup-components-history#the-web-part
+ target=$(curl -sSf "https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/${component}")
+ echo "'${component}' is unavailable on the default toolchain, use the toolchain 'nightly-${target}' instead"
+
+ rustup update "nightly-${target}" --no-self-update
+ rustup default "nightly-${target}"
+
+ echo "Query rust and cargo versions:"
+ rustup -V
+ rustc -V
+ cargo -V
+
+ rustup component add "${component}"
+fi
+
+echo "Query component versions:"
+case "${component}" in
+ clippy | miri) cargo "${component}" -V ;;
+ rustfmt) "${component}" -V ;;
+esac
diff --git a/third_party/rust/pin-project/ci/install-rust.sh b/third_party/rust/pin-project/ci/install-rust.sh
new file mode 100644
index 0000000000..3e0b27ae84
--- /dev/null
+++ b/third_party/rust/pin-project/ci/install-rust.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -euo pipefail
+
+toolchain="${1:-nightly}"
+
+if rustup -V 2>/dev/null; then
+ rustup set profile minimal
+ rustup update "${toolchain}" --no-self-update
+ rustup default "${toolchain}"
+else
+ curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain "${toolchain}"
+ export PATH=${PATH}:${HOME}/.cargo/bin
+ echo "##[add-path]${HOME}/.cargo/bin"
+fi
+
+echo "Query rust and cargo versions:"
+rustup -V
+rustc -V
+cargo -V
diff --git a/third_party/rust/pin-project/compiletest.sh b/third_party/rust/pin-project/compiletest.sh
new file mode 100644
index 0000000000..21351a50a9
--- /dev/null
+++ b/third_party/rust/pin-project/compiletest.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# A script to run compile tests with the same condition of the checks done by CI.
+#
+# Usage
+#
+# ```sh
+# . ./compiletest.sh
+# ```
+
+TRYBUILD=overwrite RUSTFLAGS='--cfg pin_project_show_unpin_struct' cargo +nightly test -p pin-project --all-features --test compiletest -- --ignored
+# RUSTFLAGS='--cfg pin_project_show_unpin_struct' cargo +nightly test -p pin-project --all-features --test compiletest -- --ignored
diff --git a/third_party/rust/pin-project/examples/README.md b/third_party/rust/pin-project/examples/README.md
new file mode 100644
index 0000000000..6234900131
--- /dev/null
+++ b/third_party/rust/pin-project/examples/README.md
@@ -0,0 +1,9 @@
+## Examples and generated code of each feature of pin-project
+
+* [Basic usage of `#[pin_project]` on structs.](struct-default.rs) -- [generated code](struct-default-expanded.rs)
+
+* [Basic usage of `#[pin_project]` on enums.](enum-default.rs) -- [generated code](enum-default-expanded.rs)
+
+* [Manual implementation of `Unpin` by `UnsafeUnpin`.](unsafe_unpin.rs) -- [generated code](unsafe_unpin-expanded.rs)
+
+* [Manual implementation of `Drop` by `#[pinned_drop]`.](pinned_drop.rs) -- [generated code](pinned_drop-expanded.rs)
diff --git a/third_party/rust/pin-project/examples/enum-default-expanded.rs b/third_party/rust/pin-project/examples/enum-default-expanded.rs
new file mode 100644
index 0000000000..568f9b2c23
--- /dev/null
+++ b/third_party/rust/pin-project/examples/enum-default-expanded.rs
@@ -0,0 +1,86 @@
+// Original code (./enum-default.rs):
+//
+// ```rust
+// #![allow(dead_code)]
+//
+// use pin_project::pin_project;
+//
+// #[pin_project]
+// enum Enum<T, U> {
+// Pinned(#[pin] T),
+// Unpinned(U),
+// }
+//
+// fn main() {}
+// ```
+
+#![allow(dead_code, unused_imports, unused_parens)]
+
+use pin_project::pin_project;
+
+enum Enum<T, U> {
+ Pinned(/* #[pin] */ T),
+ Unpinned(U),
+}
+
+#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
+#[allow(dead_code)] // This lint warns unused fields/variants.
+enum __EnumProjection<'pin, T, U> {
+ Pinned(::core::pin::Pin<&'pin mut (T)>),
+ Unpinned(&'pin mut (U)),
+}
+
+#[allow(dead_code)] // This lint warns unused fields/variants.
+enum __EnumProjectionRef<'pin, T, U> {
+ Pinned(::core::pin::Pin<&'pin (T)>),
+ Unpinned(&'pin (U)),
+}
+
+impl<T, U> Enum<T, U> {
+ fn project<'pin>(self: ::core::pin::Pin<&'pin mut Self>) -> __EnumProjection<'pin, T, U> {
+ unsafe {
+ match self.get_unchecked_mut() {
+ Enum::Pinned(_0) => __EnumProjection::Pinned(::core::pin::Pin::new_unchecked(_0)),
+ Enum::Unpinned(_0) => __EnumProjection::Unpinned(_0),
+ }
+ }
+ }
+ fn project_ref<'pin>(self: ::core::pin::Pin<&'pin Self>) -> __EnumProjectionRef<'pin, T, U> {
+ unsafe {
+ match self.get_ref() {
+ Enum::Pinned(_0) => {
+ __EnumProjectionRef::Pinned(::core::pin::Pin::new_unchecked(_0))
+ }
+ Enum::Unpinned(_0) => __EnumProjectionRef::Unpinned(_0),
+ }
+ }
+ }
+}
+
+// Automatically create the appropriate conditional `Unpin` implementation.
+//
+// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
+// for details.
+#[allow(non_snake_case)]
+fn __unpin_scope_Enum() {
+ struct __Enum<'pin, T, U> {
+ __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
+ __field0: T,
+ }
+ impl<'pin, T, U> ::core::marker::Unpin for Enum<T, U> where __Enum<'pin, T, U>: ::core::marker::Unpin
+ {}
+}
+
+// Ensure that enum does not implement `Drop`.
+//
+// See ./struct-default-expanded.rs for details.
+trait EnumMustNotImplDrop {}
+#[allow(clippy::drop_bounds)]
+impl<T: ::core::ops::Drop> EnumMustNotImplDrop for T {}
+#[allow(single_use_lifetimes)]
+impl<T, U> EnumMustNotImplDrop for Enum<T, U> {}
+
+// We don't need to check for '#[repr(packed)]',
+// since it does not apply to enums.
+
+fn main() {}
diff --git a/third_party/rust/pin-project/examples/enum-default.rs b/third_party/rust/pin-project/examples/enum-default.rs
new file mode 100644
index 0000000000..ab5a4bc2a5
--- /dev/null
+++ b/third_party/rust/pin-project/examples/enum-default.rs
@@ -0,0 +1,13 @@
+// See ./enum-default-expanded.rs for generated code.
+
+#![allow(dead_code)]
+
+use pin_project::pin_project;
+
+#[pin_project]
+enum Enum<T, U> {
+ Pinned(#[pin] T),
+ Unpinned(U),
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/examples/pinned_drop-expanded.rs b/third_party/rust/pin-project/examples/pinned_drop-expanded.rs
new file mode 100644
index 0000000000..d96dd98e12
--- /dev/null
+++ b/third_party/rust/pin-project/examples/pinned_drop-expanded.rs
@@ -0,0 +1,133 @@
+// Original code (./pinned_drop.rs):
+//
+// ```rust
+// #![allow(dead_code)]
+//
+// use pin_project::{pin_project, pinned_drop};
+// use std::pin::Pin;
+//
+// #[pin_project(PinnedDrop)]
+// pub struct Foo<'a, T> {
+// was_dropped: &'a mut bool,
+// #[pin]
+// field: T,
+// }
+//
+// #[pinned_drop]
+// fn drop_foo<T>(mut this: Pin<&mut Foo<'_, T>>) {
+// **this.project().was_dropped = true;
+// }
+//
+// fn main() {}
+// ```
+
+#![allow(dead_code, unused_imports, unused_parens)]
+
+use pin_project::{pin_project, pinned_drop};
+use std::pin::Pin;
+
+pub struct Foo<'a, T> {
+ was_dropped: &'a mut bool,
+ // #[pin]
+ field: T,
+}
+
+#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
+#[allow(dead_code)] // This lint warns unused fields/variants.
+pub(crate) struct __FooProjection<'pin, 'a, T> {
+ was_dropped: &'pin mut (&'a mut bool),
+ field: ::core::pin::Pin<&'pin mut (T)>,
+}
+
+#[allow(dead_code)] // This lint warns unused fields/variants.
+pub(crate) struct __FooProjectionRef<'pin, 'a, T> {
+ was_dropped: &'pin (&'a mut bool),
+ field: ::core::pin::Pin<&'pin (T)>,
+}
+
+impl<'a, T> Foo<'a, T> {
+ pub(crate) fn project<'pin>(
+ self: ::core::pin::Pin<&'pin mut Self>,
+ ) -> __FooProjection<'pin, 'a, T> {
+ unsafe {
+ let Foo { was_dropped, field } = self.get_unchecked_mut();
+ __FooProjection { was_dropped, field: ::core::pin::Pin::new_unchecked(field) }
+ }
+ }
+ pub(crate) fn project_ref<'pin>(
+ self: ::core::pin::Pin<&'pin Self>,
+ ) -> __FooProjectionRef<'pin, 'a, T> {
+ unsafe {
+ let Foo { was_dropped, field } = self.get_ref();
+ __FooProjectionRef { was_dropped, field: ::core::pin::Pin::new_unchecked(field) }
+ }
+ }
+}
+
+#[allow(single_use_lifetimes)]
+impl<'a, T> ::core::ops::Drop for Foo<'a, T> {
+ fn drop(&mut self) {
+ // Safety - we're in 'drop', so we know that 'self' will
+ // never move again.
+ let pinned_self = unsafe { ::core::pin::Pin::new_unchecked(self) };
+ // We call `pinned_drop` only once. Since `PinnedDrop::drop`
+ // is an unsafe function and a private API, it is never called again in safe
+ // code *unless the user uses a maliciously crafted macro*.
+ unsafe {
+ ::pin_project::__private::PinnedDrop::drop(pinned_self);
+ }
+ }
+}
+
+// It is safe to implement PinnedDrop::drop, but it is not safe to call it.
+// This is because destructors can be called multiple times (double dropping
+// is unsound: rust-lang/rust#62360).
+//
+// Ideally, it would be desirable to be able to prohibit manual calls in the
+// same way as Drop::drop, but the library cannot. So, by using macros and
+// replacing them with private traits, we prevent users from calling
+// PinnedDrop::drop.
+//
+// Users can implement `Drop` safely using `#[pinned_drop]`.
+// **Do not call or implement this trait directly.**
+impl<T> ::pin_project::__private::PinnedDrop for Foo<'_, T> {
+ // Since calling it twice on the same object would be UB,
+ // this method is unsafe.
+ unsafe fn drop(self: Pin<&mut Self>) {
+ fn __drop_inner<T>(__self: Pin<&mut Foo<'_, T>>) {
+ **__self.project().was_dropped = true;
+ }
+ __drop_inner(self);
+ }
+}
+
+// Automatically create the appropriate conditional `Unpin` implementation.
+//
+// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
+// for details.
+#[allow(non_snake_case)]
+fn __unpin_scope_Foo() {
+ pub struct __Foo<'pin, 'a, T> {
+ __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T)>,
+ __field0: T,
+ __lifetime0: &'a (),
+ }
+ impl<'pin, 'a, T> ::core::marker::Unpin for Foo<'a, T> where
+ __Foo<'pin, 'a, T>: ::core::marker::Unpin
+ {
+ }
+}
+
+// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+//
+// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
+// for details.
+#[allow(single_use_lifetimes)]
+#[allow(non_snake_case)]
+#[deny(safe_packed_borrows)]
+fn __pin_project_assert_not_repr_packed_Foo<'a, T>(val: &Foo<'a, T>) {
+ &val.was_dropped;
+ &val.field;
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/examples/pinned_drop.rs b/third_party/rust/pin-project/examples/pinned_drop.rs
new file mode 100644
index 0000000000..3dcfc6afe9
--- /dev/null
+++ b/third_party/rust/pin-project/examples/pinned_drop.rs
@@ -0,0 +1,22 @@
+// See ./pinned_drop-expanded.rs for generated code.
+
+#![allow(dead_code)]
+
+use pin_project::{pin_project, pinned_drop};
+use std::pin::Pin;
+
+#[pin_project(PinnedDrop)]
+pub struct Foo<'a, T> {
+ was_dropped: &'a mut bool,
+ #[pin]
+ field: T,
+}
+
+#[pinned_drop]
+impl<T> PinnedDrop for Foo<'_, T> {
+ fn drop(self: Pin<&mut Self>) {
+ **self.project().was_dropped = true;
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/examples/struct-default-expanded.rs b/third_party/rust/pin-project/examples/struct-default-expanded.rs
new file mode 100644
index 0000000000..ec454b7971
--- /dev/null
+++ b/third_party/rust/pin-project/examples/struct-default-expanded.rs
@@ -0,0 +1,128 @@
+// Original code (./struct-default.rs):
+//
+// ```rust
+// #![allow(dead_code)]
+//
+// use pin_project::pin_project;
+//
+// #[pin_project]
+// struct Struct<T, U> {
+// #[pin]
+// pinned: T,
+// unpinned: U,
+// }
+//
+// fn main() {}
+// ```
+
+#![allow(dead_code, unused_imports, unused_parens)]
+
+use pin_project::pin_project;
+
+struct Struct<T, U> {
+ // #[pin]
+ pinned: T,
+ unpinned: U,
+}
+
+#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
+#[allow(dead_code)] // This lint warns unused fields/variants.
+struct __StructProjection<'pin, T, U> {
+ pinned: ::core::pin::Pin<&'pin mut (T)>,
+ unpinned: &'pin mut (U),
+}
+#[allow(dead_code)] // This lint warns unused fields/variants.
+struct __StructProjectionRef<'pin, T, U> {
+ pinned: ::core::pin::Pin<&'pin (T)>,
+ unpinned: &'pin (U),
+}
+
+impl<T, U> Struct<T, U> {
+ fn project<'pin>(self: ::core::pin::Pin<&'pin mut Self>) -> __StructProjection<'pin, T, U> {
+ unsafe {
+ let Struct { pinned, unpinned } = self.get_unchecked_mut();
+ __StructProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
+ }
+ }
+ fn project_ref<'pin>(self: ::core::pin::Pin<&'pin Self>) -> __StructProjectionRef<'pin, T, U> {
+ unsafe {
+ let Struct { pinned, unpinned } = self.get_ref();
+ __StructProjectionRef { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
+ }
+ }
+}
+
+// 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)]
+fn __unpin_scope_Struct() {
+ struct __Struct<'pin, T, U> {
+ __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T, U)>,
+ __field0: T,
+ }
+ impl<'pin, T, U> ::core::marker::Unpin for Struct<T, U> where
+ __Struct<'pin, T, U>: ::core::marker::Unpin
+ {
+ }
+}
+
+// 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 StructMustNotImplDrop {}
+#[allow(clippy::drop_bounds)]
+impl<T: ::core::ops::Drop> StructMustNotImplDrop for T {}
+#[allow(single_use_lifetimes)]
+impl<T, U> StructMustNotImplDrop for Struct<T, U> {}
+
+// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+//
+// Taking a reference to a packed field is unsafe, and applying
+// #[deny(safe_packed_borrows)] makes sure that doing this without
+// an 'unsafe' block (which we deliberately do not generate)
+// is a hard error.
+//
+// If the struct ends up having #[repr(packed)] applied somehow,
+// this will generate an (unfriendly) error message. Under all reasonable
+// circumstances, we'll detect the #[repr(packed)] attribute, and generate
+// a much nicer error above.
+//
+// See https://github.com/taiki-e/pin-project/pull/34 for more details.
+#[allow(single_use_lifetimes)]
+#[allow(non_snake_case)]
+#[deny(safe_packed_borrows)]
+fn __pin_project_assert_not_repr_packed_Struct<T, U>(val: &Struct<T, U>) {
+ &val.pinned;
+ &val.unpinned;
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/examples/struct-default.rs b/third_party/rust/pin-project/examples/struct-default.rs
new file mode 100644
index 0000000000..46808a5827
--- /dev/null
+++ b/third_party/rust/pin-project/examples/struct-default.rs
@@ -0,0 +1,14 @@
+// See ./struct-default-expanded.rs for generated code.
+
+#![allow(dead_code)]
+
+use pin_project::pin_project;
+
+#[pin_project]
+struct Struct<T, U> {
+ #[pin]
+ pinned: T,
+ unpinned: U,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/examples/unsafe_unpin-expanded.rs b/third_party/rust/pin-project/examples/unsafe_unpin-expanded.rs
new file mode 100644
index 0000000000..acb3ee8316
--- /dev/null
+++ b/third_party/rust/pin-project/examples/unsafe_unpin-expanded.rs
@@ -0,0 +1,90 @@
+// Original code (./unsafe_unpin.rs):
+//
+// ```rust
+// #![allow(dead_code)]
+//
+// use pin_project::{pin_project, UnsafeUnpin};
+//
+// #[pin_project(UnsafeUnpin)]
+// pub struct Foo<T, U> {
+// #[pin]
+// pinned: T,
+// unpinned: U,
+// }
+//
+// unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {}
+//
+// fn main() {}
+// ```
+
+#![allow(dead_code, unused_imports, unused_parens)]
+
+use pin_project::{pin_project, UnsafeUnpin};
+
+pub struct Foo<T, U> {
+ // #[pin]
+ pinned: T,
+ unpinned: U,
+}
+
+#[allow(clippy::mut_mut)] // This lint warns `&mut &mut <ty>`.
+#[allow(dead_code)] // This lint warns unused fields/variants.
+pub(crate) struct __FooProjection<'pin, T, U> {
+ pinned: ::core::pin::Pin<&'pin mut (T)>,
+ unpinned: &'pin mut (U),
+}
+#[allow(dead_code)] // This lint warns unused fields/variants.
+pub(crate) struct __FooProjectionRef<'pin, T, U> {
+ pinned: ::core::pin::Pin<&'pin (T)>,
+ unpinned: &'pin (U),
+}
+
+impl<T, U> Foo<T, U> {
+ pub(crate) fn project<'pin>(
+ self: ::core::pin::Pin<&'pin mut Self>,
+ ) -> __FooProjection<'pin, T, U> {
+ unsafe {
+ let Foo { pinned, unpinned } = self.get_unchecked_mut();
+ __FooProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
+ }
+ }
+ pub(crate) fn project_ref<'pin>(
+ self: ::core::pin::Pin<&'pin Self>,
+ ) -> __FooProjectionRef<'pin, T, U> {
+ unsafe {
+ let Foo { pinned, unpinned } = self.get_ref();
+ __FooProjectionRef { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned }
+ }
+ }
+}
+
+unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {}
+
+#[allow(single_use_lifetimes)]
+impl<'pin, T, U> ::core::marker::Unpin for Foo<T, U> where
+ ::pin_project::__private::Wrapper<'pin, Self>: ::pin_project::UnsafeUnpin
+{
+}
+
+// Ensure that struct does not implement `Drop`.
+//
+// See ./struct-default-expanded.rs for details.
+trait FooMustNotImplDrop {}
+#[allow(clippy::drop_bounds)]
+impl<T: ::core::ops::Drop> FooMustNotImplDrop for T {}
+#[allow(single_use_lifetimes)]
+impl<T, U> FooMustNotImplDrop for Foo<T, U> {}
+
+// Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
+//
+// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/34
+// for details.
+#[allow(single_use_lifetimes)]
+#[allow(non_snake_case)]
+#[deny(safe_packed_borrows)]
+fn __pin_project_assert_not_repr_packed_Foo<T, U>(val: &Foo<T, U>) {
+ &val.pinned;
+ &val.unpinned;
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/examples/unsafe_unpin.rs b/third_party/rust/pin-project/examples/unsafe_unpin.rs
new file mode 100644
index 0000000000..9056808d6f
--- /dev/null
+++ b/third_party/rust/pin-project/examples/unsafe_unpin.rs
@@ -0,0 +1,16 @@
+// See ./pinned_drop-expanded.rs for generated code.
+
+#![allow(dead_code)]
+
+use pin_project::{pin_project, UnsafeUnpin};
+
+#[pin_project(UnsafeUnpin)]
+pub struct Foo<T, U> {
+ #[pin]
+ pinned: T,
+ unpinned: U,
+}
+
+unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/src/lib.rs b/third_party/rust/pin-project/src/lib.rs
new file mode 100644
index 0000000000..7d2de26614
--- /dev/null
+++ b/third_party/rust/pin-project/src/lib.rs
@@ -0,0 +1,205 @@
+//! A crate for safe and ergonomic pin-projection.
+//!
+//! ## Examples
+//!
+//! [`pin_project`] attribute creates a projection struct covering all the fields.
+//!
+//! ```rust
+//! use pin_project::pin_project;
+//! use std::pin::Pin;
+//!
+//! #[pin_project]
+//! struct Struct<T, U> {
+//! #[pin]
+//! pinned: T,
+//! unpinned: U,
+//! }
+//!
+//! impl<T, U> Struct<T, U> {
+//! fn foo(self: Pin<&mut Self>) {
+//! let this = self.project();
+//! let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
+//! let _: &mut U = this.unpinned; // Normal reference to the field
+//! }
+//! }
+//! ```
+//!
+//! [Code like this will be generated](https://github.com/taiki-e/pin-project/blob/master/examples/struct-default-expanded.rs)
+//!
+//! See [`pin_project`] attribute for more details.
+//!
+//! Also, there are examples and generated code of each feature in [examples](https://github.com/taiki-e/pin-project/blob/master/examples/README.md) directory.
+//!
+//! [`pin_project`]: attr.pin_project.html
+
+#![no_std]
+#![recursion_limit = "256"]
+#![doc(html_root_url = "https://docs.rs/pin-project/0.4.9")]
+#![doc(test(
+ no_crate_inject,
+ attr(deny(warnings, rust_2018_idioms, single_use_lifetimes), allow(dead_code))
+))]
+#![warn(unsafe_code)]
+#![warn(missing_docs, rust_2018_idioms, single_use_lifetimes, unreachable_pub)]
+#![warn(clippy::all)]
+// mem::take requires Rust 1.40
+#![allow(clippy::mem_replace_with_default)]
+#![allow(clippy::needless_doctest_main)]
+
+#[doc(inline)]
+pub use pin_project_internal::pin_project;
+
+#[doc(inline)]
+pub use pin_project_internal::pinned_drop;
+
+#[doc(inline)]
+pub use pin_project_internal::project;
+
+#[doc(inline)]
+pub use pin_project_internal::project_ref;
+
+/// A trait used for custom implementations of [`Unpin`].
+/// This trait is used in conjunction with the `UnsafeUnpin`
+/// argument to [`pin_project`]
+///
+/// The Rust [`Unpin`] trait is safe to implement - by itself,
+/// implementing it cannot lead to undefined behavior. Undefined
+/// behavior can only occur when other unsafe code is used.
+///
+/// It turns out that using pin projections, which requires unsafe code,
+/// imposes additional requirements on an [`Unpin`] impl. Normally, all of this
+/// unsafety is contained within this crate, ensuring that it's impossible for
+/// you to violate any of the guarantees required by pin projection.
+///
+/// However, things change if you want to provide a custom [`Unpin`] impl
+/// for your `#[pin_project]` type. As stated in [the Rust
+/// documentation](https://doc.rust-lang.org/nightly/std/pin/index.html#projections-and-structural-pinning),
+/// you must be sure to only implement [`Unpin`] when all of your `#[pin]` fields (i.e. structurally
+/// pinned fields) are also [`Unpin`].
+///
+/// To help highlight this unsafety, the `UnsafeUnpin` trait is provided.
+/// Implementing this trait is logically equivalent to implementing [`Unpin`] -
+/// this crate will generate an [`Unpin`] impl for your type that 'forwards' to
+/// your `UnsafeUnpin` impl. However, this trait is `unsafe` - since your type
+/// uses structural pinning (otherwise, you wouldn't be using this crate!),
+/// you must be sure that your `UnsafeUnpin` impls follows all of
+/// the requirements for an [`Unpin`] impl of a structurally-pinned type.
+///
+/// Note that if you specify `#[pin_project(UnsafeUnpin)]`, but do *not*
+/// provide an impl of `UnsafeUnpin`, your type will never implement [`Unpin`].
+/// This is effectively the same thing as adding a [`PhantomPinned`] to your type
+///
+/// Since this trait is `unsafe`, impls of it will be detected by the `unsafe_code` lint,
+/// and by tools like `cargo geiger`.
+///
+/// ## Examples
+///
+/// An `UnsafeUnpin` impl which, in addition to requiring that structurally pinned
+/// fields be [`Unpin`], imposes an additional requirement:
+///
+/// ```rust
+/// use pin_project::{pin_project, UnsafeUnpin};
+///
+/// #[pin_project(UnsafeUnpin)]
+/// struct Foo<K, V> {
+/// #[pin]
+/// field_1: K,
+/// field_2: V,
+/// }
+///
+/// unsafe impl<K, V> UnsafeUnpin for Foo<K, V> where K: Unpin + Clone {}
+/// ```
+///
+/// [`PhantomPinned`]: core::marker::PhantomPinned
+/// [`pin_project`]: attr.pin_project.html
+#[allow(unsafe_code)]
+pub unsafe trait UnsafeUnpin {}
+
+// Not public API.
+#[doc(hidden)]
+pub mod __private {
+ use super::UnsafeUnpin;
+ use core::{marker::PhantomData, pin::Pin};
+
+ #[doc(hidden)]
+ pub use pin_project_internal::__PinProjectInternalDerive;
+
+ // It is safe to implement PinnedDrop::drop, but it is not safe to call it.
+ // This is because destructors can be called multiple times (double dropping
+ // is unsound: rust-lang/rust#62360).
+ //
+ // Ideally, it would be desirable to be able to prohibit manual calls in the
+ // same way as Drop::drop, but the library cannot. So, by using macros and
+ // replacing them with private traits, we prevent users from calling
+ // PinnedDrop::drop.
+ //
+ // Users can implement `Drop` safely using `#[pinned_drop]`.
+ // **Do not call or implement this trait directly.**
+ #[doc(hidden)]
+ pub trait PinnedDrop {
+ // Since calling it twice on the same object would be UB,
+ // this method is unsafe.
+ #[allow(unsafe_code)]
+ #[doc(hidden)]
+ unsafe fn drop(self: Pin<&mut Self>);
+ }
+
+ // This is an internal helper struct used by `pin-project-internal`.
+ // This allows us to force an error if the user tries to provide
+ // a regular `Unpin` impl when they specify the `UnsafeUnpin` argument.
+ // This is why we need Wrapper:
+ //
+ // Supposed we have the following code:
+ //
+ // #[pin_project(UnsafeUnpin)]
+ // struct MyStruct<T> {
+ // #[pin] field: T
+ // }
+ //
+ // impl<T> Unpin for MyStruct<T> where MyStruct<T>: UnsafeUnpin {} // generated by pin-project-internal
+ // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
+ //
+ // We want this code to be rejected - the user is completely bypassing `UnsafeUnpin`,
+ // and providing an unsound Unpin impl in safe code!
+ //
+ // Unfortunately, the Rust compiler will accept the above code.
+ // Because MyStruct is declared in the same crate as the user-provided impl,
+ // the compiler will notice that 'MyStruct<T>: UnsafeUnpin' never holds.
+ //
+ // The solution is to introduce the 'Wrapper' struct, which is defined
+ // in the 'pin-project' crate.
+ //
+ // We now have code that looks like this:
+ //
+ // impl<T> Unpin for MyStruct<T> where Wrapper<MyStruct<T>>: UnsafeUnpin {} // generated by pin-project-internal
+ // impl<T> Unpin for MyStruct<T> where T: Copy // written by the user
+ //
+ // We also have 'unsafe impl<T> UnsafeUnpin for Wrapper<T> where T: UnsafeUnpin {}' in the
+ // 'pin-project' crate.
+ //
+ // Now, our generated impl has a bound involving a type defined in another crate - Wrapper.
+ // This will cause rust to conservatively assume that 'Wrapper<MyStruct<T>>: UnsafeUnpin'
+ // holds, in the interest of preserving forwards compatibility (in case such an impl is added
+ // for Wrapper<T> in a new version of the crate).
+ //
+ // This will cause rust to reject any other Unpin impls for MyStruct<T>, since it will
+ // assume that our generated impl could potentially apply in any situation.
+ //
+ // This achieves the desired effect - when the user writes `#[pin_project(UnsafeUnpin)]`,
+ // the user must either provide no impl of `UnsafeUnpin` (which is equivalent
+ // to making the type never implement Unpin), or provide an impl of `UnsafeUnpin`.
+ // It is impossible for them to provide an impl of `Unpin`
+ #[doc(hidden)]
+ pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T);
+
+ #[allow(unsafe_code)]
+ unsafe impl<T: ?Sized> UnsafeUnpin for Wrapper<'_, T> where T: UnsafeUnpin {}
+
+ // This is an internal helper struct used by `pin-project-internal`.
+ //
+ // See https://github.com/taiki-e/pin-project/pull/53 for more details.
+ #[doc(hidden)]
+ pub struct AlwaysUnpin<'a, T: ?Sized>(PhantomData<&'a ()>, PhantomData<T>);
+
+ impl<T: ?Sized> Unpin for AlwaysUnpin<'_, T> {}
+}
diff --git a/third_party/rust/pin-project/tests/cfg.rs b/third_party/rust/pin-project/tests/cfg.rs
new file mode 100644
index 0000000000..fa63227549
--- /dev/null
+++ b/third_party/rust/pin-project/tests/cfg.rs
@@ -0,0 +1,243 @@
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+// Refs: https://doc.rust-lang.org/nightly/reference/attributes.html
+
+use pin_project::pin_project;
+use std::{marker::PhantomPinned, pin::Pin};
+
+fn is_unpin<T: Unpin>() {}
+
+#[cfg(target_os = "linux")]
+pub struct Linux;
+#[cfg(not(target_os = "linux"))]
+pub struct Other;
+
+// Use this type to check that `cfg(any())` is working properly.
+// If `cfg(any())` is not working properly, `is_unpin` will fail.
+pub struct Any(PhantomPinned);
+
+#[test]
+fn cfg() {
+ // structs
+
+ #[pin_project]
+ pub struct SameName {
+ #[cfg(target_os = "linux")]
+ #[pin]
+ inner: Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[pin]
+ inner: Other,
+ #[cfg(any())]
+ #[pin]
+ any: Any,
+ }
+
+ is_unpin::<SameName>();
+
+ #[cfg(target_os = "linux")]
+ let _x = SameName { inner: Linux };
+ #[cfg(not(target_os = "linux"))]
+ let _x = SameName { inner: Other };
+
+ #[pin_project]
+ pub struct DifferentName {
+ #[cfg(target_os = "linux")]
+ #[pin]
+ l: Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[pin]
+ o: Other,
+ #[cfg(any())]
+ #[pin]
+ a: Any,
+ }
+
+ is_unpin::<DifferentName>();
+
+ #[cfg(target_os = "linux")]
+ let _x = DifferentName { l: Linux };
+ #[cfg(not(target_os = "linux"))]
+ let _x = DifferentName { o: Other };
+
+ #[pin_project]
+ pub struct TupleStruct(
+ #[cfg(target_os = "linux")]
+ #[pin]
+ Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[pin]
+ Other,
+ #[cfg(any())]
+ #[pin]
+ Any,
+ );
+
+ is_unpin::<TupleStruct>();
+
+ #[cfg(target_os = "linux")]
+ let _x = TupleStruct(Linux);
+ #[cfg(not(target_os = "linux"))]
+ let _x = TupleStruct(Other);
+
+ // enums
+
+ #[pin_project]
+ pub enum Variant {
+ #[cfg(target_os = "linux")]
+ Inner(#[pin] Linux),
+ #[cfg(not(target_os = "linux"))]
+ Inner(#[pin] Other),
+
+ #[cfg(target_os = "linux")]
+ Linux(#[pin] Linux),
+ #[cfg(not(target_os = "linux"))]
+ Other(#[pin] Other),
+ #[cfg(any())]
+ Any(#[pin] Any),
+ }
+
+ is_unpin::<Variant>();
+
+ #[cfg(target_os = "linux")]
+ let _x = Variant::Inner(Linux);
+ #[cfg(not(target_os = "linux"))]
+ let _x = Variant::Inner(Other);
+
+ #[cfg(target_os = "linux")]
+ let _x = Variant::Linux(Linux);
+ #[cfg(not(target_os = "linux"))]
+ let _x = Variant::Other(Other);
+
+ #[pin_project]
+ pub enum Field {
+ SameName {
+ #[cfg(target_os = "linux")]
+ #[pin]
+ inner: Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[pin]
+ inner: Other,
+ #[cfg(any())]
+ #[pin]
+ any: Any,
+ },
+ DifferentName {
+ #[cfg(target_os = "linux")]
+ #[pin]
+ l: Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[pin]
+ w: Other,
+ #[cfg(any())]
+ #[pin]
+ any: Any,
+ },
+ TupleVariant(
+ #[cfg(target_os = "linux")]
+ #[pin]
+ Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[pin]
+ Other,
+ #[cfg(any())]
+ #[pin]
+ Any,
+ ),
+ }
+
+ is_unpin::<Field>();
+
+ #[cfg(target_os = "linux")]
+ let _x = Field::SameName { inner: Linux };
+ #[cfg(not(target_os = "linux"))]
+ let _x = Field::SameName { inner: Other };
+
+ #[cfg(target_os = "linux")]
+ let _x = Field::DifferentName { l: Linux };
+ #[cfg(not(target_os = "linux"))]
+ let _x = Field::DifferentName { w: Other };
+
+ #[cfg(target_os = "linux")]
+ let _x = Field::TupleVariant(Linux);
+ #[cfg(not(target_os = "linux"))]
+ let _x = Field::TupleVariant(Other);
+}
+
+#[test]
+fn cfg_attr() {
+ #[pin_project]
+ pub struct SameCfg {
+ #[cfg(target_os = "linux")]
+ #[cfg_attr(target_os = "linux", pin)]
+ inner: Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[cfg_attr(not(target_os = "linux"), pin)]
+ inner: Other,
+ #[cfg(any())]
+ #[cfg_attr(any(), pin)]
+ any: Any,
+ }
+
+ is_unpin::<SameCfg>();
+
+ #[cfg(target_os = "linux")]
+ let mut x = SameCfg { inner: Linux };
+ #[cfg(not(target_os = "linux"))]
+ let mut x = SameCfg { inner: Other };
+
+ let x = Pin::new(&mut x).project();
+ #[cfg(target_os = "linux")]
+ let _: Pin<&mut Linux> = x.inner;
+ #[cfg(not(target_os = "linux"))]
+ let _: Pin<&mut Other> = x.inner;
+
+ #[pin_project]
+ pub struct DifferentCfg {
+ #[cfg(target_os = "linux")]
+ #[cfg_attr(target_os = "linux", pin)]
+ inner: Linux,
+ #[cfg(not(target_os = "linux"))]
+ #[cfg_attr(target_os = "linux", pin)]
+ inner: Other,
+ #[cfg(any())]
+ #[cfg_attr(any(), pin)]
+ any: Any,
+ }
+
+ is_unpin::<DifferentCfg>();
+
+ #[cfg(target_os = "linux")]
+ let mut x = DifferentCfg { inner: Linux };
+ #[cfg(not(target_os = "linux"))]
+ let mut x = DifferentCfg { inner: Other };
+
+ let x = Pin::new(&mut x).project();
+ #[cfg(target_os = "linux")]
+ let _: Pin<&mut Linux> = x.inner;
+ #[cfg(not(target_os = "linux"))]
+ let _: &mut Other = x.inner;
+
+ #[cfg_attr(not(any()), pin_project)]
+ struct Foo<T> {
+ #[cfg_attr(not(any()), pin)]
+ inner: T,
+ }
+
+ let mut x = Foo { inner: 0_u8 };
+ let x = Pin::new(&mut x).project();
+ let _: Pin<&mut u8> = x.inner;
+}
+
+#[test]
+fn cfg_attr_any_packed() {
+ // Since `cfg(any())` can never be true, it is okay for this to pass.
+ #[pin_project]
+ #[cfg_attr(any(), repr(packed))]
+ struct Struct {
+ #[pin]
+ field: u32,
+ }
+}
diff --git a/third_party/rust/pin-project/tests/compiletest.rs b/third_party/rust/pin-project/tests/compiletest.rs
new file mode 100644
index 0000000000..cf3986fcb1
--- /dev/null
+++ b/third_party/rust/pin-project/tests/compiletest.rs
@@ -0,0 +1,16 @@
+#![cfg(pin_project_show_unpin_struct)]
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+#[ignore]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/cfg/*.rs");
+ t.compile_fail("tests/ui/pin_project/*.rs");
+ t.compile_fail("tests/ui/pinned_drop/*.rs");
+ t.compile_fail("tests/ui/project/*.rs");
+ t.compile_fail("tests/ui/unsafe_unpin/*.rs");
+ t.compile_fail("tests/ui/unstable-features/*.rs");
+ t.pass("tests/ui/unstable-features/run-pass/*.rs");
+}
diff --git a/third_party/rust/pin-project/tests/no_infer_outlives.rs b/third_party/rust/pin-project/tests/no_infer_outlives.rs
new file mode 100644
index 0000000000..6602b62c99
--- /dev/null
+++ b/third_party/rust/pin-project/tests/no_infer_outlives.rs
@@ -0,0 +1,19 @@
+use pin_project::{pin_project, project};
+
+trait Bar<X> {
+ type Y;
+}
+
+struct Example<A>(A);
+
+impl<X, T> Bar<X> for Example<T> {
+ type Y = Option<T>;
+}
+
+#[pin_project]
+struct Foo<A, B> {
+ _x: <Example<A> as Bar<B>>::Y,
+}
+
+#[project]
+impl<A, B> Foo<A, B> {}
diff --git a/third_party/rust/pin-project/tests/pin_project.rs b/third_party/rust/pin-project/tests/pin_project.rs
new file mode 100644
index 0000000000..45f761a4ad
--- /dev/null
+++ b/third_party/rust/pin-project/tests/pin_project.rs
@@ -0,0 +1,552 @@
+#![no_std]
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+use core::{marker::PhantomPinned, pin::Pin};
+use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
+
+#[test]
+fn test_pin_project() {
+ #[pin_project]
+ struct Struct<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+
+ let mut foo = Struct { field1: 1, field2: 2 };
+
+ let mut foo_orig = Pin::new(&mut foo);
+ let foo = foo_orig.as_mut().project();
+
+ let x: Pin<&mut i32> = foo.field1;
+ assert_eq!(*x, 1);
+
+ let y: &mut i32 = foo.field2;
+ assert_eq!(*y, 2);
+
+ assert_eq!(foo_orig.as_ref().field1, 1);
+ assert_eq!(foo_orig.as_ref().field2, 2);
+
+ let mut foo = Struct { field1: 1, field2: 2 };
+
+ let foo = Pin::new(&mut foo).project();
+
+ let __StructProjection { field1, field2 } = foo;
+ let _: Pin<&mut i32> = field1;
+ let _: &mut i32 = field2;
+
+ #[pin_project]
+ struct TupleStruct<T, U>(#[pin] T, U);
+
+ let mut bar = TupleStruct(1, 2);
+
+ let bar = Pin::new(&mut bar).project();
+
+ let x: Pin<&mut i32> = bar.0;
+ assert_eq!(*x, 1);
+
+ let y: &mut i32 = bar.1;
+ assert_eq!(*y, 2);
+
+ #[pin_project]
+ #[derive(Eq, PartialEq, Debug)]
+ enum Enum<A, B, C, D> {
+ Variant1(#[pin] A, B),
+ Variant2 {
+ #[pin]
+ field1: C,
+ field2: D,
+ },
+ None,
+ }
+
+ let mut baz = Enum::Variant1(1, 2);
+
+ let mut baz_orig = Pin::new(&mut baz);
+ let baz = baz_orig.as_mut().project();
+
+ match baz {
+ __EnumProjection::Variant1(x, y) => {
+ let x: Pin<&mut i32> = x;
+ assert_eq!(*x, 1);
+
+ let y: &mut i32 = y;
+ assert_eq!(*y, 2);
+ }
+ __EnumProjection::Variant2 { field1, field2 } => {
+ let _x: Pin<&mut i32> = field1;
+ let _y: &mut i32 = field2;
+ }
+ __EnumProjection::None => {}
+ }
+
+ assert_eq!(Pin::into_ref(baz_orig).get_ref(), &Enum::Variant1(1, 2));
+
+ let mut baz = Enum::Variant2 { field1: 3, field2: 4 };
+
+ let mut baz = Pin::new(&mut baz).project();
+
+ match &mut baz {
+ __EnumProjection::Variant1(x, y) => {
+ let _x: &mut Pin<&mut i32> = x;
+ let _y: &mut &mut i32 = y;
+ }
+ __EnumProjection::Variant2 { field1, field2 } => {
+ let x: &mut Pin<&mut i32> = field1;
+ assert_eq!(**x, 3);
+
+ let y: &mut &mut i32 = field2;
+ assert_eq!(**y, 4);
+ }
+ __EnumProjection::None => {}
+ }
+
+ if let __EnumProjection::Variant2 { field1, field2 } = baz {
+ let x: Pin<&mut i32> = field1;
+ assert_eq!(*x, 3);
+
+ let y: &mut i32 = field2;
+ assert_eq!(*y, 4);
+ }
+}
+
+#[test]
+fn enum_project_set() {
+ #[pin_project]
+ #[derive(Eq, PartialEq, Debug)]
+ enum Bar {
+ Variant1(#[pin] u8),
+ Variant2(bool),
+ }
+
+ let mut bar = Bar::Variant1(25);
+ let mut bar_orig = Pin::new(&mut bar);
+ let bar_proj = bar_orig.as_mut().project();
+
+ match bar_proj {
+ __BarProjection::Variant1(val) => {
+ let new_bar = Bar::Variant2(val.as_ref().get_ref() == &25);
+ bar_orig.set(new_bar);
+ }
+ _ => unreachable!(),
+ }
+
+ assert_eq!(bar, Bar::Variant2(true));
+}
+
+#[test]
+fn where_clause_and_associated_type_fields() {
+ #[pin_project]
+ struct Struct1<I>
+ where
+ I: Iterator,
+ {
+ #[pin]
+ field1: I,
+ field2: I::Item,
+ }
+
+ #[pin_project]
+ struct Struct2<I, J>
+ where
+ I: Iterator<Item = J>,
+ {
+ #[pin]
+ field1: I,
+ field2: J,
+ }
+
+ #[pin_project]
+ pub struct Struct3<T>
+ where
+ T: 'static,
+ {
+ field: T,
+ }
+
+ trait Static: 'static {}
+
+ impl<T> Static for Struct3<T> {}
+
+ #[pin_project]
+ enum Enum<I>
+ where
+ I: Iterator,
+ {
+ Variant1(#[pin] I),
+ Variant2(I::Item),
+ }
+}
+
+#[allow(explicit_outlives_requirements)] // https://github.com/rust-lang/rust/issues/60993
+#[test]
+fn unsized_in_where_clause() {
+ #[pin_project]
+ struct Struct<I>
+ where
+ I: ?Sized,
+ {
+ #[pin]
+ field: I,
+ }
+}
+
+#[test]
+fn derive_copy() {
+ #[pin_project]
+ #[derive(Clone, Copy)]
+ struct Struct<T> {
+ val: T,
+ }
+
+ fn is_copy<T: Copy>() {}
+
+ is_copy::<Struct<u8>>();
+}
+
+#[test]
+fn move_out() {
+ struct NotCopy;
+
+ #[pin_project]
+ struct Struct {
+ val: NotCopy,
+ }
+
+ let foo = Struct { val: NotCopy };
+ let _val: NotCopy = foo.val;
+
+ #[pin_project]
+ enum Enum {
+ Variant(NotCopy),
+ }
+
+ let bar = Enum::Variant(NotCopy);
+ let _val: NotCopy = match bar {
+ Enum::Variant(val) => val,
+ };
+}
+
+#[test]
+fn trait_bounds_on_type_generics() {
+ #[pin_project]
+ pub struct Struct1<'a, T: ?Sized> {
+ field: &'a mut T,
+ }
+
+ #[pin_project]
+ pub struct Struct2<'a, T: ::core::fmt::Debug> {
+ field: &'a mut T,
+ }
+
+ #[pin_project]
+ pub struct Struct3<'a, T: core::fmt::Debug> {
+ field: &'a mut T,
+ }
+
+ #[pin_project]
+ pub struct Struct4<'a, T: core::fmt::Debug + core::fmt::Display> {
+ field: &'a mut T,
+ }
+
+ #[pin_project]
+ pub struct Struct5<'a, T: core::fmt::Debug + ?Sized> {
+ field: &'a mut T,
+ }
+
+ #[pin_project]
+ pub struct Struct6<'a, T: core::fmt::Debug = [u8; 16]> {
+ field: &'a mut T,
+ }
+
+ let _: Struct6<'_> = Struct6 { field: &mut [0u8; 16] };
+
+ #[pin_project]
+ pub struct Struct7<T: 'static> {
+ field: T,
+ }
+
+ trait Static: 'static {}
+
+ impl<T> Static for Struct7<T> {}
+
+ #[pin_project]
+ pub struct Struct8<'a, 'b: 'a> {
+ field1: &'a u8,
+ field2: &'b u8,
+ }
+
+ #[pin_project]
+ pub struct TupleStruct<'a, T: ?Sized>(&'a mut T);
+
+ #[pin_project]
+ enum Enum<'a, T: ?Sized> {
+ Variant(&'a mut T),
+ }
+}
+
+#[test]
+fn overlapping_lifetime_names() {
+ #[pin_project]
+ pub struct Foo<'pin, T> {
+ #[pin]
+ field: &'pin mut T,
+ }
+}
+
+#[test]
+fn combine() {
+ #[pin_project(PinnedDrop, UnsafeUnpin)]
+ pub struct Foo<T> {
+ field1: u8,
+ #[pin]
+ field2: T,
+ }
+
+ #[pinned_drop]
+ impl<T> PinnedDrop for Foo<T> {
+ fn drop(self: Pin<&mut Self>) {}
+ }
+
+ #[allow(unsafe_code)]
+ unsafe impl<T: Unpin> UnsafeUnpin for Foo<T> {}
+}
+
+#[test]
+fn private_type_in_public_type() {
+ #[pin_project]
+ pub struct PublicStruct<T> {
+ #[pin]
+ inner: PrivateStruct<T>,
+ }
+
+ struct PrivateStruct<T>(T);
+}
+
+#[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 mut T,
+ unpinned: U,
+ }
+
+ #[pin_project]
+ enum Enum<T, U> {
+ Variant {
+ #[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
+ }
+ }
+
+ impl<'b, T, U> Struct2<'b, T, U> {
+ fn get_pin_ref<'a>(self: Pin<&'a Self>) -> Pin<&'a &'b mut T> {
+ self.project_ref().pinned
+ }
+ fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut &'b mut 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() {
+ __EnumProjectionRef::Variant { pinned, .. } => pinned,
+ }
+ }
+ fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> {
+ match self.project() {
+ __EnumProjection::Variant { pinned, .. } => pinned,
+ }
+ }
+ }
+}
+
+#[rustversion::since(1.36)]
+#[test]
+fn lifetime_project_elided() {
+ #[pin_project]
+ struct Struct1<T, U> {
+ #[pin]
+ pinned: T,
+ unpinned: U,
+ }
+
+ #[pin_project]
+ struct Struct2<'a, T, U> {
+ #[pin]
+ pinned: &'a mut T,
+ unpinned: U,
+ }
+
+ #[pin_project]
+ enum Enum<T, U> {
+ Variant {
+ #[pin]
+ pinned: T,
+ unpinned: U,
+ },
+ }
+
+ impl<T, U> Struct1<T, U> {
+ fn get_pin_ref(self: Pin<&Self>) -> Pin<&T> {
+ self.project_ref().pinned
+ }
+ fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
+ self.project().pinned
+ }
+ }
+
+ impl<'b, T, U> Struct2<'b, T, U> {
+ fn get_pin_ref(self: Pin<&Self>) -> Pin<&&'b mut T> {
+ self.project_ref().pinned
+ }
+ fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut &'b mut T> {
+ self.project().pinned
+ }
+ }
+
+ impl<T, U> Enum<T, U> {
+ fn get_pin_ref(self: Pin<&Self>) -> Pin<&T> {
+ match self.project_ref() {
+ __EnumProjectionRef::Variant { pinned, .. } => pinned,
+ }
+ }
+ fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
+ match self.project() {
+ __EnumProjection::Variant { pinned, .. } => pinned,
+ }
+ }
+ }
+}
+
+mod visibility {
+ use pin_project::pin_project;
+
+ #[pin_project]
+ pub(crate) struct A {
+ pub b: u8,
+ }
+}
+
+#[test]
+fn visibility() {
+ let mut x = visibility::A { b: 0 };
+ let x = Pin::new(&mut x);
+ let y = x.as_ref().project_ref();
+ let _: &u8 = y.b;
+ let y = x.project();
+ let _: &mut u8 = y.b;
+}
+
+#[test]
+fn trivial_bounds() {
+ #[pin_project]
+ pub struct NoGenerics {
+ #[pin]
+ field: PhantomPinned,
+ }
+}
+
+#[test]
+fn dst() {
+ #[pin_project]
+ pub struct A<T: ?Sized> {
+ x: T,
+ }
+
+ let _: &mut A<dyn core::fmt::Debug> = &mut A { x: 0u8 } as _;
+
+ #[pin_project]
+ pub struct B<T: ?Sized> {
+ #[pin]
+ x: T,
+ }
+
+ #[pin_project]
+ pub struct C<T: ?Sized>(T);
+
+ #[pin_project]
+ pub struct D<T: ?Sized>(#[pin] T);
+}
+
+#[test]
+fn dyn_type() {
+ #[pin_project]
+ struct Struct1 {
+ a: i32,
+ f: dyn core::fmt::Debug,
+ }
+
+ #[pin_project]
+ struct Struct2 {
+ a: i32,
+ #[pin]
+ f: dyn core::fmt::Debug,
+ }
+
+ #[pin_project]
+ struct Struct3 {
+ a: i32,
+ f: dyn core::fmt::Debug + Send,
+ }
+
+ #[pin_project]
+ struct Struct4 {
+ a: i32,
+ #[pin]
+ f: dyn core::fmt::Debug + Send,
+ }
+}
+
+#[test]
+fn self_in_where_clause() {
+ pub trait Trait {}
+
+ #[pin_project]
+ pub struct Struct1<T>
+ where
+ Self: Trait,
+ {
+ x: T,
+ }
+
+ impl<T> Trait for Struct1<T> {}
+
+ pub trait Trait2 {
+ type Foo;
+ }
+
+ #[pin_project]
+ pub struct Struct2<T>
+ where
+ Self: Trait2<Foo = Struct1<T>>,
+ <Self as Trait2>::Foo: Trait,
+ {
+ x: T,
+ }
+
+ impl<T> Trait2 for Struct2<T> {
+ type Foo = Struct1<T>;
+ }
+}
diff --git a/third_party/rust/pin-project/tests/pinned_drop.rs b/third_party/rust/pin-project/tests/pinned_drop.rs
new file mode 100644
index 0000000000..932f636000
--- /dev/null
+++ b/third_party/rust/pin-project/tests/pinned_drop.rs
@@ -0,0 +1,210 @@
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+use pin_project::{pin_project, pinned_drop};
+use std::pin::Pin;
+
+#[test]
+fn safe_project() {
+ #[pin_project(PinnedDrop)]
+ pub struct Struct<'a> {
+ was_dropped: &'a mut bool,
+ #[pin]
+ field: u8,
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct<'_> {
+ fn drop(self: Pin<&mut Self>) {
+ **self.project().was_dropped = true;
+ }
+ }
+
+ let mut was_dropped = false;
+ drop(Struct { was_dropped: &mut was_dropped, field: 42 });
+ assert!(was_dropped);
+}
+
+#[test]
+fn mut_self_argument() {
+ #[pin_project(PinnedDrop)]
+ struct Struct {
+ data: usize,
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(mut self: Pin<&mut Self>) {
+ let _: &mut _ = &mut self.data;
+ }
+ }
+}
+
+#[test]
+fn self_in_vec() {
+ #[pin_project(PinnedDrop)]
+ struct Struct {
+ data: usize,
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(self: Pin<&mut Self>) {
+ let _: Vec<_> = vec![self.data];
+ }
+ }
+}
+
+#[test]
+fn self_in_macro_containing_fn() {
+ #[pin_project(PinnedDrop)]
+ pub struct Struct {
+ data: usize,
+ }
+
+ macro_rules! emit {
+ ($($tt:tt)*) => {
+ $($tt)*
+ };
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(self: Pin<&mut Self>) {
+ let _ = emit!({
+ impl Struct {
+ pub fn f(self) {}
+ }
+ });
+ self.data;
+ }
+ }
+}
+
+#[test]
+fn self_call() {
+ #[pin_project(PinnedDrop)]
+ pub struct Struct {
+ data: usize,
+ }
+
+ trait Trait {
+ fn self_ref(&self) {}
+ fn self_pin_ref(self: Pin<&Self>) {}
+ fn self_mut(&mut self) {}
+ fn self_pin_mut(self: Pin<&mut Self>) {}
+ fn assoc_fn(_this: Pin<&mut Self>) {}
+ }
+
+ impl Trait for Struct {}
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(mut self: Pin<&mut Self>) {
+ self.self_ref();
+ self.as_ref().self_pin_ref();
+ self.self_mut();
+ self.as_mut().self_pin_mut();
+ Self::assoc_fn(self.as_mut());
+ <Self>::assoc_fn(self.as_mut());
+ }
+ }
+}
+
+// See also `ui/pinned_drop/self.rs`.
+#[test]
+fn self_expr() {
+ #[pin_project(PinnedDrop)]
+ pub struct Struct {
+ x: usize,
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(mut self: Pin<&mut Self>) {
+ let _: Self = Self { x: 0 };
+ }
+ }
+
+ #[pin_project(PinnedDrop)]
+ pub struct TupleStruct(usize);
+
+ #[pinned_drop]
+ impl PinnedDrop for TupleStruct {
+ fn drop(mut self: Pin<&mut Self>) {
+ let _: Self = Self(0);
+ }
+ }
+
+ #[rustversion::since(1.37)]
+ #[pin_project(PinnedDrop)]
+ pub enum Enum {
+ StructVariant { x: usize },
+ TupleVariant(usize),
+ }
+
+ #[rustversion::since(1.37)]
+ #[pinned_drop]
+ impl PinnedDrop for Enum {
+ fn drop(mut self: Pin<&mut Self>) {
+ // let _: Self = Self::StructVariant { x: 0 }; //~ ERROR can't use generic parameters from outer function [E0401]
+ let _: Self = Self::TupleVariant(0);
+ }
+ }
+}
+
+// See also `ui/pinned_drop/self.rs`.
+#[test]
+fn self_pat() {
+ #[pin_project(PinnedDrop)]
+ pub struct Struct {
+ x: usize,
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(mut self: Pin<&mut Self>) {
+ // match *self {
+ // Self { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ // }
+ // if let Self { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ // let Self { x: _ } = *self; //~ ERROR can't use generic parameters from outer function [E0401]
+ }
+ }
+
+ #[pin_project(PinnedDrop)]
+ pub struct TupleStruct(usize);
+
+ #[pinned_drop]
+ impl PinnedDrop for TupleStruct {
+ #[allow(irrefutable_let_patterns)]
+ fn drop(mut self: Pin<&mut Self>) {
+ match *self {
+ Self(_) => {}
+ }
+ if let Self(_) = *self {}
+ let Self(_) = *self;
+ }
+ }
+
+ #[rustversion::since(1.37)]
+ #[pin_project(PinnedDrop)]
+ pub enum Enum {
+ StructVariant { x: usize },
+ TupleVariant(usize),
+ }
+
+ #[rustversion::since(1.37)]
+ #[pinned_drop]
+ impl PinnedDrop for Enum {
+ fn drop(mut self: Pin<&mut Self>) {
+ // match *self {
+ // Self::StructVariant { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ // Self::TupleVariant(_) => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ // }
+ // if let Self::StructVariant { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ // if let Self::TupleVariant(_) = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ }
+ }
+}
diff --git a/third_party/rust/pin-project/tests/project.rs b/third_party/rust/pin-project/tests/project.rs
new file mode 100644
index 0000000000..b88ccd839e
--- /dev/null
+++ b/third_party/rust/pin-project/tests/project.rs
@@ -0,0 +1,217 @@
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+// This hack is needed until https://github.com/rust-lang/rust/pull/69201
+// makes it way into stable.
+// Ceurrently, `#[attr] if true {}` doesn't even *parse* on stable,
+// which means that it will error even behind a `#[rustversion::nightly]`
+//
+// This trick makes sure that we don't even attempt to parse
+// the `#[project] if let _` test on stable.
+#[rustversion::nightly]
+include!("project_if_attr.rs.in");
+
+use pin_project::{pin_project, project};
+use std::pin::Pin;
+
+#[project] // Nightly does not need a dummy attribute to the function.
+#[test]
+fn project_stmt_expr() {
+ // struct
+
+ #[pin_project]
+ struct Foo<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+
+ let mut foo = Foo { field1: 1, field2: 2 };
+
+ #[project]
+ let Foo { field1, field2 } = Pin::new(&mut foo).project();
+
+ let x: Pin<&mut i32> = field1;
+ assert_eq!(*x, 1);
+
+ let y: &mut i32 = field2;
+ assert_eq!(*y, 2);
+
+ // tuple struct
+
+ #[pin_project]
+ struct Bar<T, U>(#[pin] T, U);
+
+ let mut bar = Bar(1, 2);
+
+ #[project]
+ let Bar(x, y) = Pin::new(&mut bar).project();
+
+ let x: Pin<&mut i32> = x;
+ assert_eq!(*x, 1);
+
+ let y: &mut i32 = y;
+ assert_eq!(*y, 2);
+
+ // enum
+
+ #[pin_project]
+ enum Baz<A, B, C, D> {
+ Variant1(#[pin] A, B),
+ Variant2 {
+ #[pin]
+ field1: C,
+ field2: D,
+ },
+ None,
+ }
+
+ let mut baz = Baz::Variant1(1, 2);
+
+ let mut baz = Pin::new(&mut baz).project();
+
+ #[project]
+ match &mut baz {
+ Baz::Variant1(x, y) => {
+ let x: &mut Pin<&mut i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &mut &mut i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Baz::Variant2 { field1, field2 } => {
+ let _x: &mut Pin<&mut i32> = field1;
+ let _y: &mut &mut i32 = field2;
+ }
+ Baz::None => {}
+ }
+
+ #[project]
+ let val = match &mut baz {
+ Baz::Variant1(_, _) => true,
+ Baz::Variant2 { .. } => false,
+ Baz::None => false,
+ };
+ assert_eq!(val, true);
+}
+
+#[test]
+fn project_impl() {
+ #[pin_project]
+ struct HasGenerics<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+
+ #[project]
+ impl<T, U> HasGenerics<T, U> {
+ fn a(self) {
+ let Self { field1, field2 } = self;
+
+ let _x: Pin<&mut T> = field1;
+ let _y: &mut U = field2;
+ }
+ }
+
+ #[pin_project]
+ struct NoneGenerics {
+ #[pin]
+ field1: i32,
+ field2: u32,
+ }
+
+ #[project]
+ impl NoneGenerics {}
+
+ #[pin_project]
+ struct HasLifetimes<'a, T, U> {
+ #[pin]
+ field1: &'a mut T,
+ field2: U,
+ }
+
+ #[project]
+ impl<T, U> HasLifetimes<'_, T, U> {}
+
+ #[pin_project]
+ struct HasOverlappingLifetimes<'pin, T, U> {
+ #[pin]
+ field1: &'pin mut T,
+ field2: U,
+ }
+
+ #[allow(single_use_lifetimes)]
+ #[project]
+ impl<'pin, T, U> HasOverlappingLifetimes<'pin, T, U> {}
+
+ #[pin_project]
+ struct HasOverlappingLifetimes2<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+
+ #[allow(single_use_lifetimes)]
+ #[project]
+ impl<T, U> HasOverlappingLifetimes2<T, U> {
+ fn foo<'pin>(&'pin self) {}
+ }
+}
+
+#[pin_project]
+struct A {
+ #[pin]
+ field: u8,
+}
+
+mod project_use_1 {
+ use crate::A;
+ use core::pin::Pin;
+ use pin_project::project;
+
+ #[project]
+ use crate::A;
+
+ #[project]
+ #[test]
+ fn project_use() {
+ let mut x = A { field: 0 };
+ #[project]
+ let A { field } = Pin::new(&mut x).project();
+ let _: Pin<&mut u8> = field;
+ }
+}
+
+mod project_use_2 {
+ #[project]
+ use crate::A;
+ use pin_project::project;
+
+ #[project]
+ impl A {
+ fn project_use(self) {}
+ }
+}
+
+#[pin_project]
+struct StructWhereClause<T>
+where
+ T: Copy,
+{
+ field: T,
+}
+
+#[pin_project]
+struct TupleStructWhereClause<T>(T)
+where
+ T: Copy;
+
+#[pin_project]
+enum EnumWhereClause<T>
+where
+ T: Copy,
+{
+ Variant(T),
+}
diff --git a/third_party/rust/pin-project/tests/project_if_attr.rs.in b/third_party/rust/pin-project/tests/project_if_attr.rs.in
new file mode 100644
index 0000000000..2d1eb26785
--- /dev/null
+++ b/third_party/rust/pin-project/tests/project_if_attr.rs.in
@@ -0,0 +1,29 @@
+// FIXME: Once https://github.com/rust-lang/rust/pull/69201 makes its
+// way into stable, move this back into `project.rs
+
+#[test]
+#[project]
+fn project_if_let() {
+ #[pin_project]
+ enum Foo<A, B> {
+ Variant1(#[pin] A),
+ Variant2(u8),
+ Variant3 {
+ #[pin] field: B
+ }
+ }
+
+ let mut foo: Foo<bool, f32> = Foo::Variant1(true);
+ let foo = Pin::new(&mut foo).project();
+
+ #[project]
+ if let Foo::Variant1(a) = foo {
+ let a: Pin<&mut bool> = a;
+ assert_eq!(*a, true);
+ } else if let Foo::Variant2(_) = foo {
+ unreachable!();
+ } else if let Foo::Variant3 { .. } = foo {
+ unreachable!();
+ }
+}
+
diff --git a/third_party/rust/pin-project/tests/project_ref.rs b/third_party/rust/pin-project/tests/project_ref.rs
new file mode 100644
index 0000000000..a90e016100
--- /dev/null
+++ b/third_party/rust/pin-project/tests/project_ref.rs
@@ -0,0 +1,151 @@
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+use pin_project::{pin_project, project_ref};
+use std::pin::Pin;
+
+#[project_ref] // Nightly does not need a dummy attribute to the function.
+#[test]
+fn project_stmt_expr() {
+ // struct
+
+ #[pin_project]
+ struct Foo<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+
+ let foo = Foo { field1: 1, field2: 2 };
+
+ #[project_ref]
+ let Foo { field1, field2 } = Pin::new(&foo).project_ref();
+
+ let x: Pin<&i32> = field1;
+ assert_eq!(*x, 1);
+
+ let y: &i32 = field2;
+ assert_eq!(*y, 2);
+
+ // tuple struct
+
+ #[pin_project]
+ struct Bar<T, U>(#[pin] T, U);
+
+ let bar = Bar(1, 2);
+
+ #[project_ref]
+ let Bar(x, y) = Pin::new(&bar).project_ref();
+
+ let x: Pin<&i32> = x;
+ assert_eq!(*x, 1);
+
+ let y: &i32 = y;
+ assert_eq!(*y, 2);
+
+ // enum
+
+ #[pin_project]
+ enum Baz<A, B, C, D> {
+ Variant1(#[pin] A, B),
+ Variant2 {
+ #[pin]
+ field1: C,
+ field2: D,
+ },
+ None,
+ }
+
+ let baz = Baz::Variant1(1, 2);
+
+ let baz = Pin::new(&baz).project_ref();
+
+ #[project_ref]
+ match &baz {
+ Baz::Variant1(x, y) => {
+ let x: &Pin<&i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &&i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Baz::Variant2 { field1, field2 } => {
+ let _x: &Pin<&i32> = field1;
+ let _y: &&i32 = field2;
+ }
+ Baz::None => {}
+ }
+
+ #[project_ref]
+ let val = match &baz {
+ Baz::Variant1(_, _) => true,
+ Baz::Variant2 { .. } => false,
+ Baz::None => false,
+ };
+ assert_eq!(val, true);
+}
+
+#[test]
+fn project_impl() {
+ #[pin_project]
+ struct HasGenerics<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+
+ #[project_ref]
+ impl<T, U> HasGenerics<T, U> {
+ fn a(self) {
+ let Self { field1, field2 } = self;
+
+ let _x: Pin<&T> = field1;
+ let _y: &U = field2;
+ }
+ }
+
+ #[pin_project]
+ struct NoneGenerics {
+ #[pin]
+ field1: i32,
+ field2: u32,
+ }
+
+ #[project_ref]
+ impl NoneGenerics {}
+
+ #[pin_project]
+ struct HasLifetimes<'a, T, U> {
+ #[pin]
+ field1: &'a mut T,
+ field2: U,
+ }
+
+ #[project_ref]
+ impl<T, U> HasLifetimes<'_, T, U> {}
+
+ #[pin_project]
+ struct HasOverlappingLifetimes<'pin, T, U> {
+ #[pin]
+ field1: &'pin mut T,
+ field2: U,
+ }
+
+ #[allow(single_use_lifetimes)]
+ #[project_ref]
+ impl<'pin, T, U> HasOverlappingLifetimes<'pin, T, U> {}
+
+ #[pin_project]
+ struct HasOverlappingLifetimes2<T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ }
+
+ #[allow(single_use_lifetimes)]
+ #[project_ref]
+ impl<T, U> HasOverlappingLifetimes2<T, U> {
+ fn foo<'pin>(&'pin self) {}
+ }
+}
diff --git a/third_party/rust/pin-project/tests/repr_packed.rs b/third_party/rust/pin-project/tests/repr_packed.rs
new file mode 100644
index 0000000000..3b196511b7
--- /dev/null
+++ b/third_party/rust/pin-project/tests/repr_packed.rs
@@ -0,0 +1,50 @@
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+#![deny(safe_packed_borrows)]
+
+use std::cell::Cell;
+
+// Ensure that the compiler doesn't copy the fields
+// of #[repr(packed)] types during drop, if the field has alignment 1
+// (that is, any reference to the field is guaranteed to have proper alignment)
+// We are currently unable to statically prevent the usage of #[pin_project]
+// on #[repr(packed)] types composed entirely of fields of alignment 1.
+// This shouldn't lead to undefined behavior, as long as the compiler doesn't
+// try to move the field anyway during drop.
+//
+// This tests validates that the compiler is doing what we expect.
+#[test]
+fn weird_repr_packed() {
+ // We keep track of the field address during
+ // drop using a thread local, to avoid changing
+ // the layout of our #[repr(packed)] type.
+ thread_local! {
+ static FIELD_ADDR: Cell<usize> = Cell::new(0);
+ }
+
+ #[repr(packed)]
+ struct Foo {
+ field: u8,
+ }
+
+ impl Drop for Foo {
+ fn drop(&mut self) {
+ FIELD_ADDR.with(|f| {
+ f.set(&self.field as *const u8 as usize);
+ })
+ }
+ }
+
+ let field_addr = {
+ // We let this field drop by going out of scope,
+ // rather than explicitly calling drop(foo).
+ // Calling drop(foo) causes 'foo' to be moved
+ // into the 'drop' function, resulting in a different
+ // address.
+ let foo = Foo { field: 27 };
+ let field_addr = &foo.field as *const u8 as usize;
+ field_addr
+ };
+ assert_eq!(field_addr, FIELD_ADDR.with(|f| f.get()));
+}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.rs b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.rs
new file mode 100644
index 0000000000..e16f3e8de2
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.rs
@@ -0,0 +1,11 @@
+use std::pin::Pin;
+
+#[cfg_attr(any(), pin_project::pin_project)]
+struct Foo<T> {
+ inner: T,
+}
+
+fn main() {
+ let mut x = Foo { inner: 0_u8 };
+ let _x = Pin::new(&mut x).project(); //~ ERROR E0599
+}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.stderr b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.stderr
new file mode 100644
index 0000000000..45af3ae05a
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-resolve.stderr
@@ -0,0 +1,5 @@
+error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Foo<u8>>` in the current scope
+ --> $DIR/cfg_attr-resolve.rs:10:31
+ |
+10 | let _x = Pin::new(&mut x).project(); //~ ERROR E0599
+ | ^^^^^^^ method not found in `std::pin::Pin<&mut Foo<u8>>`
diff --git a/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.rs b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.rs
new file mode 100644
index 0000000000..2807c8768b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.rs
@@ -0,0 +1,24 @@
+use pin_project::pin_project;
+use std::pin::Pin;
+
+#[cfg_attr(not(any()), pin_project)]
+struct Foo<T> {
+ #[cfg_attr(any(), pin)]
+ inner: T,
+}
+
+#[cfg_attr(not(any()), pin_project)]
+struct Bar<T> {
+ #[cfg_attr(not(any()), pin)]
+ inner: T,
+}
+
+fn main() {
+ let mut x = Foo { inner: 0_u8 };
+ let x = Pin::new(&mut x).project();
+ let _: Pin<&mut u8> = x.inner; //~ ERROR E0308
+
+ let mut x = Bar { inner: 0_u8 };
+ let x = Pin::new(&mut x).project();
+ let _: &mut u8 = x.inner; //~ ERROR E0308
+}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.stderr b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.stderr
new file mode 100644
index 0000000000..286829911f
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-type-mismatch.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+ --> $DIR/cfg_attr-type-mismatch.rs:19:27
+ |
+19 | let _: Pin<&mut u8> = x.inner; //~ ERROR E0308
+ | ------------ ^^^^^^^ expected struct `std::pin::Pin`, found `&mut u8`
+ | |
+ | expected due to this
+ |
+ = note: expected struct `std::pin::Pin<&mut u8>`
+ found mutable reference `&mut u8`
+
+error[E0308]: mismatched types
+ --> $DIR/cfg_attr-type-mismatch.rs:23:22
+ |
+23 | let _: &mut u8 = x.inner; //~ ERROR E0308
+ | ------- ^^^^^^^
+ | | |
+ | | expected `&mut u8`, found struct `std::pin::Pin`
+ | | help: consider mutably borrowing here: `&mut x.inner`
+ | expected due to this
+ |
+ = note: expected mutable reference `&mut u8`
+ found struct `std::pin::Pin<&mut u8>`
diff --git a/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.rs b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.rs
new file mode 100644
index 0000000000..7b88205542
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.rs
@@ -0,0 +1,21 @@
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[cfg_attr(any(), pin_project)]
+struct Foo<T> {
+ inner: T,
+}
+
+#[cfg_attr(not(any()), pin_project)]
+struct Bar<T> {
+ #[cfg_attr(not(any()), pin)]
+ inner: T,
+}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Foo<PhantomPinned>>(); // ERROR E0277
+ is_unpin::<Bar<()>>(); // Ok
+ is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
+}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.stderr b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.stderr
new file mode 100644
index 0000000000..8879d020e8
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/cfg_attr-unpin.stderr
@@ -0,0 +1,22 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/cfg_attr-unpin.rs:18:5
+ |
+15 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+18 | is_unpin::<Foo<PhantomPinned>>(); // ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `Foo<std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `Foo<std::marker::PhantomPinned>`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/cfg_attr-unpin.rs:20:5
+ |
+15 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+20 | is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `__Bar<'_, std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<std::marker::PhantomPinned>`
diff --git a/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.rs b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.rs
new file mode 100644
index 0000000000..3776dac3df
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.rs
@@ -0,0 +1,18 @@
+use auxiliary_macros::hidden_repr;
+use pin_project::pin_project;
+
+//~ ERROR may not be used on #[repr(packed)] types
+// span is lost.
+// Refs: https://github.com/rust-lang/rust/issues/43081
+#[pin_project]
+#[hidden_repr(packed)]
+struct Foo {
+ #[cfg(not(any()))]
+ #[pin]
+ field: u32,
+ #[cfg(any())]
+ #[pin]
+ field: u8,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.stderr b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.stderr
new file mode 100644
index 0000000000..f4d7dee6b7
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-1.stderr
@@ -0,0 +1 @@
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
diff --git a/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.rs b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.rs
new file mode 100644
index 0000000000..aa65d33149
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.rs
@@ -0,0 +1,18 @@
+use auxiliary_macros::hidden_repr;
+use pin_project::pin_project;
+
+//~ ERROR may not be used on #[repr(packed)] types
+// span is lost.
+// Refs: https://github.com/rust-lang/rust/issues/43081
+#[pin_project]
+#[hidden_repr(packed)]
+struct Foo {
+ #[cfg(any())]
+ #[pin]
+ field: u32,
+ #[cfg(not(any()))]
+ #[pin]
+ field: u8,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.stderr b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.stderr
new file mode 100644
index 0000000000..f4d7dee6b7
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky-span-issue-2.stderr
@@ -0,0 +1 @@
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
diff --git a/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.rs b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.rs
new file mode 100644
index 0000000000..3305ed39c5
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.rs
@@ -0,0 +1,12 @@
+use auxiliary_macros::hidden_repr_cfg_not_any;
+use pin_project::pin_project;
+
+// `#[hidden_repr_cfg_not_any(packed)]` generates `#[cfg_attr(not(any()), repr(packed))]`.
+#[pin_project]
+#[hidden_repr_cfg_not_any(packed)] //~ ERROR may not be used on #[repr(packed)] types
+struct Foo {
+ #[pin]
+ field: u32,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.stderr b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.stderr
new file mode 100644
index 0000000000..5910cf4b64
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/packed_sneaky.stderr
@@ -0,0 +1,7 @@
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed_sneaky.rs:6:1
+ |
+6 | #[hidden_repr_cfg_not_any(packed)] //~ ERROR may not be used on #[repr(packed)] types
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/cfg/proper_unpin.rs b/third_party/rust/pin-project/tests/ui/cfg/proper_unpin.rs
new file mode 100644
index 0000000000..b7bb04de80
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/proper_unpin.rs
@@ -0,0 +1,28 @@
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[pin_project]
+struct Foo<T> {
+ #[cfg(any())]
+ #[pin]
+ inner: T,
+ #[cfg(not(any()))]
+ inner: T,
+}
+
+#[pin_project]
+struct Bar<T> {
+ #[cfg(any())]
+ inner: T,
+ #[cfg(not(any()))]
+ #[pin]
+ inner: T,
+}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Foo<PhantomPinned>>(); // Ok
+ is_unpin::<Bar<()>>(); // Ok
+ is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
+}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/proper_unpin.stderr b/third_party/rust/pin-project/tests/ui/cfg/proper_unpin.stderr
new file mode 100644
index 0000000000..1f58ea218b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/proper_unpin.stderr
@@ -0,0 +1,11 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:27:5
+ |
+22 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+27 | is_unpin::<Bar<PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Bar<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `__Bar<'_, std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar<std::marker::PhantomPinned>`
diff --git a/third_party/rust/pin-project/tests/ui/cfg/unsupported.rs b/third_party/rust/pin-project/tests/ui/cfg/unsupported.rs
new file mode 100644
index 0000000000..5205307d22
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/unsupported.rs
@@ -0,0 +1,13 @@
+use pin_project::pin_project;
+
+//~ ERROR may not be used on structs with zero fields
+// span is lost.
+// Refs: https://github.com/rust-lang/rust/issues/43081
+#[pin_project]
+struct Struct {
+ #[cfg(any())]
+ #[pin]
+ f: u8,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/cfg/unsupported.stderr b/third_party/rust/pin-project/tests/ui/cfg/unsupported.stderr
new file mode 100644
index 0000000000..0ee8676705
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/cfg/unsupported.stderr
@@ -0,0 +1 @@
+error: #[pin_project] attribute may not be used on structs with zero fields
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.rs b/third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.rs
new file mode 100644
index 0000000000..ea7c917d54
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.rs
@@ -0,0 +1,19 @@
+use auxiliary_macros::add_attr;
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[pin_project]
+#[add_attr(struct)] //~ ERROR duplicate #[pin] attribute
+struct Foo {
+ #[pin]
+ field: PhantomPinned,
+}
+
+#[add_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
+#[pin_project]
+struct Bar {
+ #[pin]
+ field: PhantomPinned,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.stderr b/third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.stderr
new file mode 100644
index 0000000000..cb2c9638bb
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/add-attr-to-struct.stderr
@@ -0,0 +1,15 @@
+error: duplicate #[pin] attribute
+ --> $DIR/add-attr-to-struct.rs:6:1
+ |
+6 | #[add_attr(struct)] //~ ERROR duplicate #[pin] attribute
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: #[pin] attribute may only be used on fields of structs or variants
+ --> $DIR/add-attr-to-struct.rs:12:1
+ |
+12 | #[add_attr(struct)] //~ ERROR #[pin] attribute may only be used on fields of structs or variants
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.rs b/third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.rs
new file mode 100644
index 0000000000..76394cf506
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.rs
@@ -0,0 +1,23 @@
+use auxiliary_macros::add_pinned_field;
+use pin_project::pin_project;
+
+fn is_unpin<T: Unpin>() {}
+
+#[pin_project]
+#[add_pinned_field]
+struct Foo {
+ #[pin]
+ field: u32,
+}
+
+#[add_pinned_field]
+#[pin_project]
+struct Bar {
+ #[pin]
+ field: u32,
+}
+
+fn main() {
+ is_unpin::<Foo>(); //~ ERROR E0277
+ is_unpin::<Bar>(); //~ ERROR E0277
+}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.stderr b/third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.stderr
new file mode 100644
index 0000000000..3de6f4ac5a
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/add-pinned-field.stderr
@@ -0,0 +1,23 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/add-pinned-field.rs:21:5
+ |
+4 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+21 | is_unpin::<Foo>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^ within `__Foo<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `__Foo<'_>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/add-pinned-field.rs:22:5
+ |
+4 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+22 | is_unpin::<Bar>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^ within `__Bar<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `__Bar<'_>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Bar`
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.rs b/third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.rs
new file mode 100644
index 0000000000..c9651848a4
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.rs
@@ -0,0 +1,31 @@
+use pin_project::{pin_project, pinned_drop};
+use std::pin::Pin;
+
+#[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) {}
+}
+
+#[pin_project(PinnedDrop)] //~ ERROR E0119
+struct Bar<T, U> {
+ #[pin]
+ future: T,
+ field: U,
+}
+
+#[pinned_drop]
+impl<T, U> PinnedDrop for Bar<T, U> {
+ fn drop(self: Pin<&mut Self>) {}
+}
+
+impl<T, U> Drop for Bar<T, U> {
+ fn drop(&mut self) {}
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.stderr b/third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.stderr
new file mode 100644
index 0000000000..1724fcc07d
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/conflict-drop.stderr
@@ -0,0 +1,21 @@
+error[E0119]: conflicting implementations of trait `FooMustNotImplDrop` for type `Foo<_, _>`:
+ --> $DIR/conflict-drop.rs:4:1
+ |
+4 | #[pin_project] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^
+ | |
+ | first implementation here
+ | conflicting implementation for `Foo<_, _>`
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `Bar<_, _>`:
+ --> $DIR/conflict-drop.rs:15:1
+ |
+15 | #[pin_project(PinnedDrop)] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
+...
+27 | impl<T, U> Drop for Bar<T, U> {
+ | ----------------------------- first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.rs b/third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.rs
new file mode 100644
index 0000000000..0c48d27907
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.rs
@@ -0,0 +1,37 @@
+use pin_project::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/third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.stderr b/third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.stderr
new file mode 100644
index 0000000000..0d6f439b8b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/conflict-unpin.stderr
@@ -0,0 +1,32 @@
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_, _>`:
+ --> $DIR/conflict-unpin.rs:5:1
+ |
+5 | #[pin_project] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^ conflicting implementation for `Foo<_, _>`
+...
+13 | impl<T, U> Unpin for Foo<T, U> where T: Unpin {} // Conditional Unpin impl
+ | --------------------------------------------- first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Bar<_, _>`:
+ --> $DIR/conflict-unpin.rs:17:1
+ |
+17 | #[pin_project] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^ conflicting implementation for `Bar<_, _>`
+...
+25 | impl<T, U> Unpin for Bar<T, U> {} // Non-conditional Unpin impl
+ | ------------------------------ first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Baz<_, _>`:
+ --> $DIR/conflict-unpin.rs:27:1
+ |
+27 | #[pin_project] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^ conflicting implementation for `Baz<_, _>`
+...
+35 | impl<T: Unpin, U: Unpin> Unpin for Baz<T, U> {} // Conditional Unpin impl
+ | -------------------------------------------- first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.rs b/third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.rs
new file mode 100644
index 0000000000..df8bf1b751
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.rs
@@ -0,0 +1,27 @@
+use pin_project::pin_project;
+
+#[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
+struct UnsafeUnpin<T> {
+ #[pin]
+ pinned: T,
+}
+
+#[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
+struct PinnedDrop<T> {
+ #[pin]
+ pinned: T,
+}
+
+#[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
+struct Duplicate3<T> {
+ #[pin]
+ pinned: T,
+}
+
+#[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
+struct Duplicate4<T> {
+ #[pin]
+ pinned: T,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.stderr b/third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.stderr
new file mode 100644
index 0000000000..338e3f4e2d
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/duplicate-argument.stderr
@@ -0,0 +1,23 @@
+error: duplicate `UnsafeUnpin` argument
+ --> $DIR/duplicate-argument.rs:3:28
+ |
+3 | #[pin_project(UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
+ | ^^^^^^^^^^^
+
+error: duplicate `PinnedDrop` argument
+ --> $DIR/duplicate-argument.rs:9:27
+ |
+9 | #[pin_project(PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
+ | ^^^^^^^^^^
+
+error: duplicate `UnsafeUnpin` argument
+ --> $DIR/duplicate-argument.rs:15:40
+ |
+15 | #[pin_project(PinnedDrop, UnsafeUnpin, UnsafeUnpin)] //~ ERROR duplicate `UnsafeUnpin` argument
+ | ^^^^^^^^^^^
+
+error: duplicate `PinnedDrop` argument
+ --> $DIR/duplicate-argument.rs:21:40
+ |
+21 | #[pin_project(PinnedDrop, UnsafeUnpin, PinnedDrop, PinnedDrop)] //~ ERROR duplicate `PinnedDrop` argument
+ | ^^^^^^^^^^
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/invalid.rs b/third_party/rust/pin-project/tests/ui/pin_project/invalid.rs
new file mode 100644
index 0000000000..f545018c1e
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/invalid.rs
@@ -0,0 +1,56 @@
+use pin_project::pin_project;
+
+#[pin_project]
+struct A<T> {
+ #[pin()] //~ ERROR unexpected token
+ pinned: T,
+}
+
+#[pin_project]
+struct B<T>(#[pin(foo)] T); //~ ERROR unexpected token
+
+#[pin_project]
+enum C<T> {
+ A(#[pin(foo)] T), //~ ERROR unexpected token
+}
+
+#[pin_project]
+enum D<T> {
+ A {
+ #[pin(foo)] //~ ERROR unexpected token
+ pinned: T,
+ },
+}
+
+#[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
+struct E<T> {
+ #[pin]
+ pinned: T,
+}
+
+#[pin_project(Foo)] //~ ERROR unexpected argument
+struct F<T> {
+ #[pin]
+ pinned: T,
+}
+
+#[pin_project]
+enum G<T> {
+ #[pin] //~ ERROR may only be used on fields of structs or variants
+ A(T),
+}
+
+#[pin_project]
+#[pin] //~ ERROR may only be used on fields of structs or variants
+enum H<T> {
+ A(T),
+}
+
+#[pin_project]
+struct I<T> {
+ #[pin]
+ #[pin] //~ ERROR duplicate #[pin] attribute
+ pinned: T,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/invalid.stderr b/third_party/rust/pin-project/tests/ui/pin_project/invalid.stderr
new file mode 100644
index 0000000000..308d476670
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/invalid.stderr
@@ -0,0 +1,53 @@
+error: unexpected token: ()
+ --> $DIR/invalid.rs:5:10
+ |
+5 | #[pin()] //~ ERROR unexpected token
+ | ^^
+
+error: unexpected token: (foo)
+ --> $DIR/invalid.rs:10:18
+ |
+10 | struct B<T>(#[pin(foo)] T); //~ ERROR unexpected token
+ | ^^^^^
+
+error: unexpected token: (foo)
+ --> $DIR/invalid.rs:14:12
+ |
+14 | A(#[pin(foo)] T), //~ ERROR unexpected token
+ | ^^^^^
+
+error: unexpected token: (foo)
+ --> $DIR/invalid.rs:20:14
+ |
+20 | #[pin(foo)] //~ ERROR unexpected token
+ | ^^^^^
+
+error: expected identifier
+ --> $DIR/invalid.rs:25:27
+ |
+25 | #[pin_project(UnsafeUnpin,,)] //~ ERROR expected identifier
+ | ^
+
+error: unexpected argument: Foo
+ --> $DIR/invalid.rs:31:15
+ |
+31 | #[pin_project(Foo)] //~ ERROR unexpected argument
+ | ^^^
+
+error: #[pin] attribute may only be used on fields of structs or variants
+ --> $DIR/invalid.rs:39:5
+ |
+39 | #[pin] //~ ERROR may only be used on fields of structs or variants
+ | ^^^^^^
+
+error: #[pin] attribute may only be used on fields of structs or variants
+ --> $DIR/invalid.rs:44:1
+ |
+44 | #[pin] //~ ERROR may only be used on fields of structs or variants
+ | ^^^^^^
+
+error: duplicate #[pin] attribute
+ --> $DIR/invalid.rs:52:5
+ |
+52 | #[pin] //~ ERROR duplicate #[pin] attribute
+ | ^^^^^^
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.rs b/third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.rs
new file mode 100644
index 0000000000..00fef3cc3b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.rs
@@ -0,0 +1,18 @@
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[pin_project]
+struct Foo<T> {
+ #[pin]
+ inner: T,
+}
+
+struct __Foo {}
+
+impl Unpin for __Foo {}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
+}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.stderr b/third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.stderr
new file mode 100644
index 0000000000..60f4116dbd
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/overlapping_unpin_struct.stderr
@@ -0,0 +1,11 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/overlapping_unpin_struct.rs:17:5
+ |
+14 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+17 | is_unpin::<Foo<PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `__Foo<'_, std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned>`
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/packed.rs b/third_party/rust/pin-project/tests/ui/pin_project/packed.rs
new file mode 100644
index 0000000000..86f3ecf33d
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/packed.rs
@@ -0,0 +1,25 @@
+use pin_project::pin_project;
+
+#[pin_project]
+#[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] types
+struct A {
+ #[pin]
+ field: u8,
+}
+
+// Test putting 'repr' before the 'pin_project' attribute
+#[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] types
+#[pin_project]
+struct B {
+ #[pin]
+ field: u8,
+}
+
+#[pin_project]
+#[repr(packed(2))] //~ ERROR may not be used on #[repr(packed)] types
+struct C {
+ #[pin]
+ field: u32,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/packed.stderr b/third_party/rust/pin-project/tests/ui/pin_project/packed.stderr
new file mode 100644
index 0000000000..969faea211
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/packed.stderr
@@ -0,0 +1,17 @@
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed.rs:4:8
+ |
+4 | #[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] types
+ | ^^^^^^
+
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed.rs:11:8
+ |
+11 | #[repr(packed, C)] //~ ERROR may not be used on #[repr(packed)] types
+ | ^^^^^^
+
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed.rs:19:8
+ |
+19 | #[repr(packed(2))] //~ ERROR may not be used on #[repr(packed)] types
+ | ^^^^^^^^^
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.rs b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.rs
new file mode 100644
index 0000000000..dcf5464e4c
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.rs
@@ -0,0 +1,33 @@
+use auxiliary_macros::hidden_repr;
+use pin_project::{pin_project, pinned_drop, UnsafeUnpin};
+use std::pin::Pin;
+
+#[pin_project] //~ ERROR may not be used on #[repr(packed)] types
+#[hidden_repr(packed)]
+struct A {
+ #[pin]
+ field: u32,
+}
+
+#[pin_project(UnsafeUnpin)] //~ ERROR may not be used on #[repr(packed)] types
+#[hidden_repr(packed)]
+struct C {
+ #[pin]
+ field: u32,
+}
+
+unsafe impl UnsafeUnpin for C {}
+
+#[pin_project(PinnedDrop)] //~ ERROR may not be used on #[repr(packed)] types
+#[hidden_repr(packed)]
+struct D {
+ #[pin]
+ field: u32,
+}
+
+#[pinned_drop]
+impl PinnedDrop for D {
+ fn drop(self: Pin<&mut Self>) {}
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.stderr b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.stderr
new file mode 100644
index 0000000000..06a4f6266c
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-1.stderr
@@ -0,0 +1,23 @@
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed_sneaky-1.rs:6:1
+ |
+6 | #[hidden_repr(packed)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed_sneaky-1.rs:13:1
+ |
+13 | #[hidden_repr(packed)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed_sneaky-1.rs:22:1
+ |
+22 | #[hidden_repr(packed)]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.rs b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.rs
new file mode 100644
index 0000000000..d16270635e
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.rs
@@ -0,0 +1,12 @@
+use auxiliary_macros::hidden_repr_macro;
+use pin_project::pin_project;
+
+hidden_repr_macro! { //~ ERROR may not be used on #[repr(packed)] types
+ #[pin_project]
+ struct B {
+ #[pin]
+ field: u32,
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.stderr b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.stderr
new file mode 100644
index 0000000000..d653a4d29f
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/packed_sneaky-2.stderr
@@ -0,0 +1,13 @@
+error: #[pin_project] attribute may not be used on #[repr(packed)] types
+ --> $DIR/packed_sneaky-2.rs:4:1
+ |
+4 | / hidden_repr_macro! { //~ ERROR may not be used on #[repr(packed)] types
+5 | | #[pin_project]
+6 | | struct B {
+7 | | #[pin]
+8 | | field: u32,
+9 | | }
+10 | | }
+ | |_^
+ |
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.rs b/third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.rs
new file mode 100644
index 0000000000..66ddefa4d8
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.rs
@@ -0,0 +1,23 @@
+// Even if allows private_in_public, these are errors.
+
+#![allow(private_in_public)]
+
+pub enum PublicEnum {
+ Variant(PrivateEnum),
+}
+
+enum PrivateEnum {
+ Variant(u8),
+}
+
+mod foo {
+ pub(crate) enum CrateEnum {
+ Variant(PrivateEnum),
+ }
+
+ enum PrivateEnum {
+ Variant(u8),
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.stderr b/third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.stderr
new file mode 100644
index 0000000000..2a5ae992c0
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/private_in_public-enum.stderr
@@ -0,0 +1,17 @@
+error[E0446]: private type `PrivateEnum` in public interface
+ --> $DIR/private_in_public-enum.rs:6:13
+ |
+6 | Variant(PrivateEnum),
+ | ^^^^^^^^^^^ can't leak private type
+...
+9 | enum PrivateEnum {
+ | - `PrivateEnum` declared as private
+
+error[E0446]: private type `foo::PrivateEnum` in public interface
+ --> $DIR/private_in_public-enum.rs:15:17
+ |
+15 | Variant(PrivateEnum),
+ | ^^^^^^^^^^^ can't leak private type
+...
+18 | enum PrivateEnum {
+ | - `foo::PrivateEnum` declared as private
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.rs b/third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.rs
new file mode 100644
index 0000000000..7121cc84a3
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.rs
@@ -0,0 +1,38 @@
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+struct Inner<T> {
+ val: T,
+}
+
+#[pin_project]
+struct Foo<T, U> {
+ #[pin]
+ inner: Inner<T>,
+ other: U,
+}
+
+#[pin_project]
+pub struct TrivialBounds {
+ #[pin]
+ field1: PhantomPinned,
+}
+
+#[pin_project]
+struct Bar<'a, T, U> {
+ #[pin]
+ inner: &'a mut Inner<T>,
+ other: U,
+}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
+ is_unpin::<Foo<(), PhantomPinned>>(); // Ok
+ is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
+
+ is_unpin::<TrivialBounds>(); //~ ERROR E0277
+
+ is_unpin::<Bar<'_, PhantomPinned, PhantomPinned>>(); //~ Ok
+}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.stderr b/third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.stderr
new file mode 100644
index 0000000000..73fd289438
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/proper_unpin.stderr
@@ -0,0 +1,37 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:31:5
+ |
+28 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+31 | is_unpin::<Foo<PhantomPinned, ()>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, std::marker::PhantomPinned, ()>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
+ = note: required because it appears within the type `__Foo<'_, std::marker::PhantomPinned, ()>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, ()>`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:33:5
+ |
+28 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+33 | is_unpin::<Foo<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `Inner<std::marker::PhantomPinned>`
+ = note: required because it appears within the type `__Foo<'_, std::marker::PhantomPinned, std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Foo<std::marker::PhantomPinned, std::marker::PhantomPinned>`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:35:5
+ |
+28 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+35 | is_unpin::<TrivialBounds>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `__TrivialBounds<'_>`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `__TrivialBounds<'_>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.rs b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.rs
new file mode 100644
index 0000000000..eebd3cd27f
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.rs
@@ -0,0 +1,32 @@
+use auxiliary_macros::remove_attr;
+use pin_project::pin_project;
+use std::{marker::PhantomPinned, pin::Pin};
+
+fn is_unpin<T: Unpin>() {}
+
+#[pin_project]
+#[remove_attr(field)]
+struct Foo {
+ #[pin]
+ field: PhantomPinned,
+}
+
+#[remove_attr(field)]
+#[pin_project]
+struct Bar {
+ #[pin]
+ field: PhantomPinned,
+}
+
+fn main() {
+ is_unpin::<Foo>();
+ is_unpin::<Bar>();
+
+ let mut x = Foo { field: PhantomPinned };
+ let x = Pin::new(&mut x).project();
+ let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
+
+ let mut x = Bar { field: PhantomPinned };
+ let x = Pin::new(&mut x).project();
+ let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
+}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.stderr b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.stderr
new file mode 100644
index 0000000000..15195e7737
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-field.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/remove-attr-from-field.rs:27:38
+ |
+27 | let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
+ | ----------------------- ^^^^^^^ expected struct `std::pin::Pin`, found `&mut std::marker::PhantomPinned`
+ | |
+ | expected due to this
+ |
+ = note: expected struct `std::pin::Pin<&mut std::marker::PhantomPinned>`
+ found mutable reference `&mut std::marker::PhantomPinned`
+
+error[E0308]: mismatched types
+ --> $DIR/remove-attr-from-field.rs:31:38
+ |
+31 | let _: Pin<&mut PhantomPinned> = x.field; //~ ERROR E0308
+ | ----------------------- ^^^^^^^ expected struct `std::pin::Pin`, found `&mut std::marker::PhantomPinned`
+ | |
+ | expected due to this
+ |
+ = note: expected struct `std::pin::Pin<&mut std::marker::PhantomPinned>`
+ found mutable reference `&mut std::marker::PhantomPinned`
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.rs b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.rs
new file mode 100644
index 0000000000..b395a42354
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.rs
@@ -0,0 +1,30 @@
+use auxiliary_macros::remove_attr;
+use pin_project::pin_project;
+use std::{marker::PhantomPinned, pin::Pin};
+
+fn is_unpin<T: Unpin>() {}
+
+#[pin_project]
+#[remove_attr(struct)]
+struct Foo {
+ #[pin] //~ ERROR cannot find attribute `pin` in this scope
+ field: PhantomPinned,
+}
+
+#[remove_attr(struct)]
+#[pin_project]
+struct Bar {
+ #[pin] //~ ERROR cannot find attribute `pin` in this scope
+ field: PhantomPinned,
+}
+
+fn main() {
+ is_unpin::<Foo>(); //~ ERROR E0277
+ is_unpin::<Bar>(); //~ ERROR E0277
+
+ let mut x = Foo { field: PhantomPinned };
+ let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+
+ let mut x = Bar { field: PhantomPinned };
+ let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.stderr b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.stderr
new file mode 100644
index 0000000000..3173248daa
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/remove-attr-from-struct.stderr
@@ -0,0 +1,63 @@
+error: cannot find attribute `pin` in this scope
+ --> $DIR/remove-attr-from-struct.rs:10:7
+ |
+10 | #[pin] //~ ERROR cannot find attribute `pin` in this scope
+ | ^^^
+
+error: cannot find attribute `pin` in this scope
+ --> $DIR/remove-attr-from-struct.rs:17:7
+ |
+17 | #[pin] //~ ERROR cannot find attribute `pin` in this scope
+ | ^^^
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/remove-attr-from-struct.rs:22:5
+ |
+5 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+22 | is_unpin::<Foo>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^ within `Foo`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `Foo`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/remove-attr-from-struct.rs:23:5
+ |
+5 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+23 | is_unpin::<Bar>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^ within `Bar`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `Bar`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/remove-attr-from-struct.rs:26:14
+ |
+26 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+ | ^^^^^^^^ within `Foo`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `Foo`
+ = note: required by `std::pin::Pin::<P>::new`
+
+error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Foo>` in the current scope
+ --> $DIR/remove-attr-from-struct.rs:26:31
+ |
+26 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+ | ^^^^^^^ method not found in `std::pin::Pin<&mut Foo>`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/remove-attr-from-struct.rs:29:14
+ |
+29 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+ | ^^^^^^^^ within `Bar`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `Bar`
+ = note: required by `std::pin::Pin::<P>::new`
+
+error[E0599]: no method named `project` found for struct `std::pin::Pin<&mut Bar>` in the current scope
+ --> $DIR/remove-attr-from-struct.rs:29:31
+ |
+29 | let _x = Pin::new(&mut x).project(); //~ ERROR E0277,E0599
+ | ^^^^^^^ method not found in `std::pin::Pin<&mut Bar>`
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.rs b/third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.rs
new file mode 100644
index 0000000000..c1a7d55dda
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.rs
@@ -0,0 +1,21 @@
+#![deny(safe_packed_borrows)]
+
+// Refs: https://github.com/rust-lang/rust/issues/46043
+
+#[repr(packed)]
+struct A {
+ field: u32,
+}
+
+#[repr(packed(2))]
+struct B {
+ field: u32,
+}
+
+fn main() {
+ let a = A { field: 1 };
+ &a.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+
+ let b = B { field: 1 };
+ &b.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.stderr b/third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.stderr
new file mode 100644
index 0000000000..7b4cc08ec6
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/safe_packed_borrows.stderr
@@ -0,0 +1,24 @@
+error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
+ --> $DIR/safe_packed_borrows.rs:17:5
+ |
+17 | &a.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/safe_packed_borrows.rs:1:9
+ |
+1 | #![deny(safe_packed_borrows)]
+ | ^^^^^^^^^^^^^^^^^^^
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
+ = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
+
+error: borrow of packed field is unsafe and requires unsafe function or block (error E0133)
+ --> $DIR/safe_packed_borrows.rs:20:5
+ |
+20 | &b.field; //~ ERROR borrow of packed field is unsafe and requires unsafe function or block
+ | ^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
+ = note: fields of packed structs might be misaligned: dereferencing a misaligned pointer or even just creating a misaligned reference is undefined behavior
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.rs b/third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.rs
new file mode 100644
index 0000000000..3ccb1a95d1
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.rs
@@ -0,0 +1,11 @@
+use pin_project::pin_project;
+
+#[pin_project]
+struct Foo {
+ #[pin]
+ inner: u8,
+}
+
+impl Unpin for __Foo {} //~ ERROR E0412,E0321
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.stderr b/third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.stderr
new file mode 100644
index 0000000000..d96050bb54
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/unpin_sneaky.stderr
@@ -0,0 +1,16 @@
+error[E0412]: cannot find type `__Foo` in this scope
+ --> $DIR/unpin_sneaky.rs:9:16
+ |
+9 | impl Unpin for __Foo {} //~ ERROR E0412,E0321
+ | ^^^^^ not found in this scope
+ |
+help: possible candidate is found in another module, you can import it into scope
+ |
+1 | use crate::__Foo;
+ |
+
+error[E0321]: cross-crate traits with a default impl, like `std::marker::Unpin`, can only be implemented for a struct/enum type, not `[type error]`
+ --> $DIR/unpin_sneaky.rs:9:1
+ |
+9 | impl Unpin for __Foo {} //~ ERROR E0412,E0321
+ | ^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/unsupported.rs b/third_party/rust/pin-project/tests/ui/pin_project/unsupported.rs
new file mode 100644
index 0000000000..f7b8eb94a0
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/unsupported.rs
@@ -0,0 +1,32 @@
+use pin_project::pin_project;
+
+#[pin_project]
+struct Struct1 {} //~ ERROR may not be used on structs with zero fields
+
+#[pin_project]
+struct Struct2(); //~ ERROR may not be used on structs with zero fields
+
+#[pin_project]
+struct Struct3; //~ ERROR may not be used on structs with units
+
+#[pin_project]
+enum Enum1 {} //~ ERROR may not be used on enums without variants
+
+#[pin_project]
+enum Enum2 {
+ A = 2, //~ ERROR may not be used on enums with discriminants
+}
+
+#[pin_project]
+enum Enum3 {
+ A, //~ ERROR may not be used on enums that have no field
+ B,
+}
+
+#[pin_project]
+union Union {
+ //~^ ERROR may only be used on structs or enums
+ x: u8,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pin_project/unsupported.stderr b/third_party/rust/pin-project/tests/ui/pin_project/unsupported.stderr
new file mode 100644
index 0000000000..89ffd949f5
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pin_project/unsupported.stderr
@@ -0,0 +1,45 @@
+error: #[pin_project] attribute may not be used on structs with zero fields
+ --> $DIR/unsupported.rs:4:16
+ |
+4 | struct Struct1 {} //~ ERROR may not be used on structs with zero fields
+ | ^^
+
+error: #[pin_project] attribute may not be used on structs with zero fields
+ --> $DIR/unsupported.rs:7:15
+ |
+7 | struct Struct2(); //~ ERROR may not be used on structs with zero fields
+ | ^^
+
+error: #[pin_project] attribute may not be used on structs with units
+ --> $DIR/unsupported.rs:10:8
+ |
+10 | struct Struct3; //~ ERROR may not be used on structs with units
+ | ^^^^^^^
+
+error: #[pin_project] attribute may not be used on enums without variants
+ --> $DIR/unsupported.rs:13:12
+ |
+13 | enum Enum1 {} //~ ERROR may not be used on enums without variants
+ | ^^
+
+error: #[pin_project] attribute may not be used on enums with discriminants
+ --> $DIR/unsupported.rs:17:9
+ |
+17 | A = 2, //~ ERROR may not be used on enums with discriminants
+ | ^
+
+error: #[pin_project] attribute may not be used on enums that have no field
+ --> $DIR/unsupported.rs:22:5
+ |
+22 | / A, //~ ERROR may not be used on enums that have no field
+23 | | B,
+ | |______^
+
+error: #[pin_project] attribute may only be used on structs or enums
+ --> $DIR/unsupported.rs:27:1
+ |
+27 | / union Union {
+28 | | //~^ ERROR may only be used on structs or enums
+29 | | x: u8,
+30 | | }
+ | |_^
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.rs b/third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.rs
new file mode 100644
index 0000000000..b291fbae54
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.rs
@@ -0,0 +1,9 @@
+use pin_project::pin_project;
+
+#[pin_project(PinnedDrop)] //~ ERROR E0277
+pub struct Struct {
+ #[pin]
+ field: u8,
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr b/third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr
new file mode 100644
index 0000000000..67bdbe11bd
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/forget-pinned-drop-impl.stderr
@@ -0,0 +1,7 @@
+error[E0277]: the trait bound `Struct: pin_project::__private::PinnedDrop` is not satisfied
+ --> $DIR/forget-pinned-drop-impl.rs:3:15
+ |
+3 | #[pin_project(PinnedDrop)] //~ ERROR E0277
+ | ^^^^^^^^^^ the trait `pin_project::__private::PinnedDrop` is not implemented for `Struct`
+ |
+ = note: required by `pin_project::__private::PinnedDrop::drop`
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/invalid.rs b/third_party/rust/pin-project/tests/ui/pinned_drop/invalid.rs
new file mode 100644
index 0000000000..651d76856e
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/invalid.rs
@@ -0,0 +1,152 @@
+use pin_project::{pin_project, pinned_drop};
+
+#[pin_project(PinnedDrop)]
+pub struct A {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop(foo)] //~ ERROR unexpected token
+impl PinnedDrop for A {
+ fn drop(self: Pin<&mut Self>) {}
+}
+
+#[pin_project(PinnedDrop)]
+pub struct B {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl Drop for B {
+ //~^ ERROR #[pinned_drop] may only be used on implementation for the `PinnedDrop` trait
+ fn drop(&mut self) {}
+}
+
+#[pin_project(PinnedDrop)]
+pub struct C {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl C {
+ //~^ ERROR #[pinned_drop] may only be used on implementation for the `PinnedDrop` trait
+ fn drop(&mut self) {}
+}
+
+#[pin_project(PinnedDrop)]
+pub struct D {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for D {
+ fn drop(&mut self) {} //~ ERROR method `drop` must take an argument `self: Pin<&mut Self>`
+}
+
+#[pin_project(PinnedDrop)]
+pub struct E {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for E {
+ fn drop_baz(&mut self) {} //~ ERROR method `drop_baz` is not a member of trait `PinnedDrop
+}
+
+#[pin_project(PinnedDrop)]
+pub struct F {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+unsafe impl PinnedDrop for F {
+ //~^ ERROR implementing the trait `PinnedDrop` is not unsafe
+ fn drop(self: Pin<&mut Self>) {}
+}
+
+#[pin_project(PinnedDrop)]
+pub struct G {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for G {
+ unsafe fn drop(self: Pin<&mut Self>) {} //~ ERROR implementing the method `drop` is not unsafe
+}
+
+#[pin_project(PinnedDrop)]
+pub struct H {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for H {
+ const A: u8 = 0; //~ ERROR const `A` is not a member of trait `PinnedDrop`
+ fn drop(self: Pin<&mut Self>) {}
+}
+
+#[pin_project(PinnedDrop)]
+pub struct I {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for I {
+ fn drop(self: Pin<&mut Self>) {}
+ const A: u8 = 0; //~ ERROR const `A` is not a member of trait `PinnedDrop`
+}
+
+#[pin_project(PinnedDrop)]
+pub struct J {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for J {
+ type A = u8; //~ ERROR type `A` is not a member of trait `PinnedDrop`
+ fn drop(self: Pin<&mut Self>) {}
+}
+
+#[pin_project(PinnedDrop)]
+pub struct K {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for K {
+ fn drop(self: Pin<&mut Self>) {}
+ type A = u8; //~ ERROR type `A` is not a member of trait `PinnedDrop`
+}
+
+#[pin_project(PinnedDrop)]
+pub struct L {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for L {
+ fn drop(self: Pin<&mut Self>) {}
+ fn drop(self: Pin<&mut Self>) {} //~ ERROR duplicate definitions with name `drop`
+}
+
+#[pin_project(PinnedDrop)] //~ ERROR E0277
+pub struct M {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+fn drop(_this: Pin<&mut M>) {} //~ ERROR expected `impl`
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/invalid.stderr b/third_party/rust/pin-project/tests/ui/pinned_drop/invalid.stderr
new file mode 100644
index 0000000000..c767fbb113
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/invalid.stderr
@@ -0,0 +1,85 @@
+error: unexpected token: foo
+ --> $DIR/invalid.rs:9:15
+ |
+9 | #[pinned_drop(foo)] //~ ERROR unexpected token
+ | ^^^
+
+error: #[pinned_drop] may only be used on implementation for the `PinnedDrop` trait
+ --> $DIR/invalid.rs:21:6
+ |
+21 | impl Drop for B {
+ | ^^^^
+
+error: #[pinned_drop] may only be used on implementation for the `PinnedDrop` trait
+ --> $DIR/invalid.rs:33:6
+ |
+33 | impl C {
+ | ^
+
+error: method `drop` must take an argument `self: Pin<&mut Self>`
+ --> $DIR/invalid.rs:46:13
+ |
+46 | fn drop(&mut self) {} //~ ERROR method `drop` must take an argument `self: Pin<&mut Self>`
+ | ^^^^^^^^^
+
+error: method `drop_baz` is not a member of trait `PinnedDrop
+ --> $DIR/invalid.rs:57:8
+ |
+57 | fn drop_baz(&mut self) {} //~ ERROR method `drop_baz` is not a member of trait `PinnedDrop
+ | ^^^^^^^^
+
+error: implementing the trait `PinnedDrop` is not unsafe
+ --> $DIR/invalid.rs:67:1
+ |
+67 | unsafe impl PinnedDrop for F {
+ | ^^^^^^
+
+error: implementing the method `drop` is not unsafe
+ --> $DIR/invalid.rs:80:5
+ |
+80 | unsafe fn drop(self: Pin<&mut Self>) {} //~ ERROR implementing the method `drop` is not unsafe
+ | ^^^^^^
+
+error: const `A` is not a member of trait `PinnedDrop`
+ --> $DIR/invalid.rs:91:5
+ |
+91 | const A: u8 = 0; //~ ERROR const `A` is not a member of trait `PinnedDrop`
+ | ^^^^^^^^^^^^^^^^
+
+error: const `A` is not a member of trait `PinnedDrop`
+ --> $DIR/invalid.rs:104:5
+ |
+104 | const A: u8 = 0; //~ ERROR const `A` is not a member of trait `PinnedDrop`
+ | ^^^^^^^^^^^^^^^^
+
+error: type `A` is not a member of trait `PinnedDrop`
+ --> $DIR/invalid.rs:115:5
+ |
+115 | type A = u8; //~ ERROR type `A` is not a member of trait `PinnedDrop`
+ | ^^^^^^^^^^^^
+
+error: type `A` is not a member of trait `PinnedDrop`
+ --> $DIR/invalid.rs:128:5
+ |
+128 | type A = u8; //~ ERROR type `A` is not a member of trait `PinnedDrop`
+ | ^^^^^^^^^^^^
+
+error: duplicate definitions with name `drop`
+ --> $DIR/invalid.rs:140:5
+ |
+140 | fn drop(self: Pin<&mut Self>) {} //~ ERROR duplicate definitions with name `drop`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: expected `impl`
+ --> $DIR/invalid.rs:150:1
+ |
+150 | fn drop(_this: Pin<&mut M>) {} //~ ERROR expected `impl`
+ | ^^
+
+error[E0277]: the trait bound `M: pin_project::__private::PinnedDrop` is not satisfied
+ --> $DIR/invalid.rs:143:15
+ |
+143 | #[pin_project(PinnedDrop)] //~ ERROR E0277
+ | ^^^^^^^^^^ the trait `pin_project::__private::PinnedDrop` is not implemented for `M`
+ |
+ = note: required by `pin_project::__private::PinnedDrop::drop`
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs b/third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs
new file mode 100644
index 0000000000..1241b5be84
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.rs
@@ -0,0 +1,15 @@
+use pin_project::{pin_project, pinned_drop};
+use std::pin::Pin;
+
+#[pin_project]
+struct Foo {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for Foo { //~ ERROR E0119
+ fn drop(self: Pin<&mut Self>) {}
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr b/third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr
new file mode 100644
index 0000000000..7353dc483b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/pinned-drop-no-attr-arg.stderr
@@ -0,0 +1,8 @@
+error[E0119]: conflicting implementations of trait `pin_project::__private::PinnedDrop` for type `Foo`:
+ --> $DIR/pinned-drop-no-attr-arg.rs:11:1
+ |
+4 | #[pin_project]
+ | -------------- first implementation here
+...
+11 | impl PinnedDrop for Foo { //~ ERROR E0119
+ | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Foo`
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.rs b/third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.rs
new file mode 100644
index 0000000000..79ae05cd7e
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.rs
@@ -0,0 +1,14 @@
+// `ref (mut) self` are rejected by rustc.
+
+use std::pin::Pin;
+
+pub struct Struct {
+ field: u8,
+}
+
+impl Struct {
+ fn method_ref(ref self: Pin<&mut Self>) {} //~ ERROR expected identifier, found keyword `self`
+ fn method_ref_mut(ref mut self: Pin<&mut Self>) {} //~ ERROR expected identifier, found keyword `self`
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.stderr b/third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.stderr
new file mode 100644
index 0000000000..3ab489813c
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/ref-self.stderr
@@ -0,0 +1,11 @@
+error: expected identifier, found keyword `self`
+ --> $DIR/ref-self.rs:10:23
+ |
+10 | fn method_ref(ref self: Pin<&mut Self>) {} //~ ERROR expected identifier, found keyword `self`
+ | ^^^^ expected identifier, found keyword
+
+error: expected identifier, found keyword `self`
+ --> $DIR/ref-self.rs:11:31
+ |
+11 | fn method_ref_mut(ref mut self: Pin<&mut Self>) {} //~ ERROR expected identifier, found keyword `self`
+ | ^^^^ expected identifier, found keyword
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/self.rs b/third_party/rust/pin-project/tests/ui/pinned_drop/self.rs
new file mode 100644
index 0000000000..6d552a71a6
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/self.rs
@@ -0,0 +1,93 @@
+use pin_project::{pin_project, pinned_drop};
+use std::pin::Pin;
+
+fn self_expr() {
+ #[pin_project(PinnedDrop)]
+ pub struct Struct {
+ x: usize,
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(mut self: Pin<&mut Self>) {
+ let _: Self = Self { x: 0 };
+ }
+ }
+
+ #[pin_project(PinnedDrop)]
+ pub struct TupleStruct(usize);
+
+ #[pinned_drop]
+ impl PinnedDrop for TupleStruct {
+ fn drop(mut self: Pin<&mut Self>) {
+ let _: Self = Self(0);
+ }
+ }
+
+ #[pin_project(PinnedDrop)]
+ pub enum Enum {
+ StructVariant { x: usize },
+ TupleVariant(usize),
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Enum {
+ fn drop(mut self: Pin<&mut Self>) {
+ let _: Self = Self::StructVariant { x: 0 }; //~ ERROR can't use generic parameters from outer function [E0401]
+ let _: Self = Self::TupleVariant(0);
+ }
+ }
+}
+
+fn self_pat() {
+ #[pin_project(PinnedDrop)]
+ pub struct Struct {
+ x: usize,
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Struct {
+ fn drop(mut self: Pin<&mut Self>) {
+ match *self {
+ Self { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ }
+ if let Self { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ let Self { x: _ } = *self; //~ ERROR can't use generic parameters from outer function [E0401]
+ }
+ }
+
+ #[pin_project(PinnedDrop)]
+ pub struct TupleStruct(usize);
+
+ #[pinned_drop]
+ impl PinnedDrop for TupleStruct {
+ #[allow(irrefutable_let_patterns)]
+ fn drop(mut self: Pin<&mut Self>) {
+ match *self {
+ Self(_) => {}
+ }
+ if let Self(_) = *self {}
+ let Self(_) = *self;
+ }
+ }
+
+ #[pin_project(PinnedDrop)]
+ pub enum Enum {
+ StructVariant { x: usize },
+ TupleVariant(usize),
+ }
+
+ #[pinned_drop]
+ impl PinnedDrop for Enum {
+ fn drop(mut self: Pin<&mut Self>) {
+ match *self {
+ Self::StructVariant { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ Self::TupleVariant(_) => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ }
+ if let Self::StructVariant { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ if let Self::TupleVariant(_) = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ }
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/self.stderr b/third_party/rust/pin-project/tests/ui/pinned_drop/self.stderr
new file mode 100644
index 0000000000..54c7b676a3
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/self.stderr
@@ -0,0 +1,95 @@
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:36:27
+ |
+34 | impl PinnedDrop for Enum {
+ | ---- `Self` type implicitly declared here, by this `impl`
+35 | fn drop(mut self: Pin<&mut Self>) {
+36 | let _: Self = Self::StructVariant { x: 0 }; //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:52:17
+ |
+49 | impl PinnedDrop for Struct {
+ | ---- `Self` type implicitly declared here, by this `impl`
+...
+52 | Self { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:54:20
+ |
+49 | impl PinnedDrop for Struct {
+ | ---- `Self` type implicitly declared here, by this `impl`
+...
+54 | if let Self { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:55:17
+ |
+49 | impl PinnedDrop for Struct {
+ | ---- `Self` type implicitly declared here, by this `impl`
+...
+55 | let Self { x: _ } = *self; //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:84:17
+ |
+81 | impl PinnedDrop for Enum {
+ | ---- `Self` type implicitly declared here, by this `impl`
+...
+84 | Self::StructVariant { x: _ } => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:85:17
+ |
+81 | impl PinnedDrop for Enum {
+ | ---- `Self` type implicitly declared here, by this `impl`
+...
+85 | Self::TupleVariant(_) => {} //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^^^^^^^^^^^^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:87:20
+ |
+81 | impl PinnedDrop for Enum {
+ | ---- `Self` type implicitly declared here, by this `impl`
+...
+87 | if let Self::StructVariant { x: _ } = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^^^^^^^^^^^^^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
+
+error[E0401]: can't use generic parameters from outer function
+ --> $DIR/self.rs:88:20
+ |
+81 | impl PinnedDrop for Enum {
+ | ---- `Self` type implicitly declared here, by this `impl`
+...
+88 | if let Self::TupleVariant(_) = *self {} //~ ERROR can't use generic parameters from outer function [E0401]
+ | ^^^^^^^^^^^^^^^^^^
+ | |
+ | use of generic parameter from outer function
+ | use a type here instead
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.rs b/third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.rs
new file mode 100644
index 0000000000..78f8a11ced
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.rs
@@ -0,0 +1,17 @@
+use pin_project::{pin_project, pinned_drop};
+use std::pin::Pin;
+
+#[pin_project(PinnedDrop)]
+pub struct Struct {
+ #[pin]
+ field: u8,
+}
+
+#[pinned_drop]
+impl PinnedDrop for Struct {
+ fn drop(self: Pin<&mut Self>) {
+ self.project().field.get_unchecked_mut(); //~ ERROR call to unsafe function is unsafe and requires unsafe function or block [E0133]
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.stderr b/third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.stderr
new file mode 100644
index 0000000000..98a945f6eb
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/pinned_drop/unsafe-code.stderr
@@ -0,0 +1,7 @@
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-code.rs:13:9
+ |
+13 | self.project().field.get_unchecked_mut(); //~ ERROR call to unsafe function is unsafe and requires unsafe function or block [E0133]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
diff --git a/third_party/rust/pin-project/tests/ui/project/ambiguous-let.rs b/third_party/rust/pin-project/tests/ui/project/ambiguous-let.rs
new file mode 100644
index 0000000000..a7067494ec
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/ambiguous-let.rs
@@ -0,0 +1,24 @@
+use pin_project::{pin_project, project};
+
+#[pin_project]
+enum Enum<A, B> {
+ A(#[pin] A),
+ B(B),
+}
+
+struct Struct<T>(T);
+
+#[project]
+fn foo() {
+ let mut foo: Enum<bool, bool> = Enum::A(true);
+
+ #[project]
+ let Struct(x) = match Pin::new(&mut foo).project() {
+ //~^ ERROR Both initializer expression and pattern are replaceable, you need to split the initializer expression into separate let bindings to avoid ambiguity
+ Enum::A(_) => Struct(true),
+ Enum::B(_) => unreachable!(),
+ };
+ assert!(x);
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/project/ambiguous-let.stderr b/third_party/rust/pin-project/tests/ui/project/ambiguous-let.stderr
new file mode 100644
index 0000000000..e6552c83ec
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/ambiguous-let.stderr
@@ -0,0 +1,5 @@
+error: Both initializer expression and pattern are replaceable, you need to split the initializer expression into separate let bindings to avoid ambiguity
+ --> $DIR/ambiguous-let.rs:16:9
+ |
+16 | let Struct(x) = match Pin::new(&mut foo).project() {
+ | ^^^^^^^^^
diff --git a/third_party/rust/pin-project/tests/ui/project/invalid.rs b/third_party/rust/pin-project/tests/ui/project/invalid.rs
new file mode 100644
index 0000000000..bc7226deb2
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/invalid.rs
@@ -0,0 +1,24 @@
+use pin_project::{pin_project, project};
+
+#[pin_project]
+struct A<T> {
+ #[pin]
+ future: T,
+}
+
+#[project]
+fn foo() {
+ let mut x = A { future: 0 };
+ #[project(foo)] //~ ERROR unexpected token
+ let A { future } = Pin::new(&mut x).project();
+}
+
+#[project]
+fn bar() {
+ let mut x = A { future: 0 };
+ #[project]
+ #[project] //~ ERROR duplicate #[project] attribute
+ let A { future } = Pin::new(&mut x).project();
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/project/invalid.stderr b/third_party/rust/pin-project/tests/ui/project/invalid.stderr
new file mode 100644
index 0000000000..a361b72aa3
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/invalid.stderr
@@ -0,0 +1,11 @@
+error: unexpected token: (foo)
+ --> $DIR/invalid.rs:12:14
+ |
+12 | #[project(foo)] //~ ERROR unexpected token
+ | ^^^^^
+
+error: duplicate #[project] attribute
+ --> $DIR/invalid.rs:20:5
+ |
+20 | #[project] //~ ERROR duplicate #[project] attribute
+ | ^^^^^^^^^^
diff --git a/third_party/rust/pin-project/tests/ui/project/type-mismatch.rs b/third_party/rust/pin-project/tests/ui/project/type-mismatch.rs
new file mode 100644
index 0000000000..41a70eb87b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/type-mismatch.rs
@@ -0,0 +1,74 @@
+#![feature(proc_macro_hygiene, stmt_expr_attributes)]
+
+use pin_project::{pin_project, project};
+use std::pin::Pin;
+
+#[project]
+fn type_mismatch() {
+ #[pin_project]
+ enum Enum<A, B, C, D> {
+ Variant1(#[pin] A, B),
+ Variant2 {
+ #[pin]
+ field1: C,
+ field2: D,
+ },
+ None,
+ }
+
+ let mut foo = Enum::Variant1(1, 2);
+ let mut foo = Pin::new(&mut foo).project();
+
+ #[project]
+ match &mut foo {
+ Enum::Variant1(x, y) => {
+ let x: &mut Pin<&mut i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &mut &mut i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Enum::Variant2 { field1, field2 } => {
+ let _x: &mut Pin<&mut i32> = field1;
+ let _y: &mut &mut i32 = field2;
+ }
+ None => {} //~ ERROR mismatched types
+ }
+}
+
+//~ ERROR mismatched types
+// span is lost.
+// Refs: https://github.com/rust-lang/rust/issues/43081
+fn type_mismatch_span_issue() {
+ #[pin_project]
+ enum Enum<A, B, C, D> {
+ Variant1(#[pin] A, B),
+ Variant2 {
+ #[pin]
+ field1: C,
+ field2: D,
+ },
+ None,
+ }
+
+ let mut foo = Enum::Variant1(1, 2);
+ let mut foo = Pin::new(&mut foo).project();
+
+ #[project]
+ match &mut foo {
+ Enum::Variant1(x, y) => {
+ let x: &mut Pin<&mut i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &mut &mut i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Enum::Variant2 { field1, field2 } => {
+ let _x: &mut Pin<&mut i32> = field1;
+ let _y: &mut &mut i32 = field2;
+ }
+ None => {}
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/project/type-mismatch.stderr b/third_party/rust/pin-project/tests/ui/project/type-mismatch.stderr
new file mode 100644
index 0000000000..b4c97d5a99
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/type-mismatch.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+ --> $DIR/type-mismatch.rs:35:9
+ |
+23 | match &mut foo {
+ | -------- this expression has type `&mut type_mismatch::__EnumProjection<'_, {integer}, {integer}, _, _>`
+...
+35 | None => {} //~ ERROR mismatched types
+ | ^^^^ expected enum `type_mismatch::__EnumProjection`, found enum `std::option::Option`
+ |
+ = note: expected enum `type_mismatch::__EnumProjection<'_, {integer}, {integer}, _, _>`
+ found enum `std::option::Option<_>`
+
+error[E0308]: mismatched types
+ |
+ = note: expected enum `type_mismatch_span_issue::__EnumProjection<'_, {integer}, {integer}, _, _>`
+ found enum `std::option::Option<_>`
diff --git a/third_party/rust/pin-project/tests/ui/project/use-public.rs b/third_party/rust/pin-project/tests/ui/project/use-public.rs
new file mode 100644
index 0000000000..23c9b89d00
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/use-public.rs
@@ -0,0 +1,15 @@
+use pin_project::pin_project;
+
+#[pin_project]
+struct A {
+ field: u8,
+}
+
+pub mod b {
+ use pin_project::project;
+
+ #[project]
+ pub use crate::A; //~ ERROR E0365
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/project/use-public.stderr b/third_party/rust/pin-project/tests/ui/project/use-public.stderr
new file mode 100644
index 0000000000..7919d65cbe
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/use-public.stderr
@@ -0,0 +1,7 @@
+error[E0365]: `__AProjection` is private, and cannot be re-exported
+ --> $DIR/use-public.rs:12:13
+ |
+12 | pub use crate::A; //~ ERROR E0365
+ | ^^^^^^^^ re-export of private `__AProjection`
+ |
+ = note: consider declaring type or module `__AProjection` with `pub`
diff --git a/third_party/rust/pin-project/tests/ui/project/use.rs b/third_party/rust/pin-project/tests/ui/project/use.rs
new file mode 100644
index 0000000000..d4b02c1d60
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/use.rs
@@ -0,0 +1,17 @@
+use pin_project::pin_project;
+
+#[pin_project]
+struct A {
+ field: u8,
+}
+
+mod b {
+ use pin_project::project;
+
+ #[project]
+ use crate::A as B; //~ ERROR #[project] attribute may not be used on renamed imports
+ #[project]
+ use crate::*; //~ ERROR #[project] attribute may not be used on glob imports
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/project/use.stderr b/third_party/rust/pin-project/tests/ui/project/use.stderr
new file mode 100644
index 0000000000..07d024160b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/project/use.stderr
@@ -0,0 +1,11 @@
+error: #[project] attribute may not be used on renamed imports
+ --> $DIR/use.rs:12:16
+ |
+12 | use crate::A as B; //~ ERROR #[project] attribute may not be used on renamed imports
+ | ^^^^^^
+
+error: #[project] attribute may not be used on glob imports
+ --> $DIR/use.rs:14:16
+ |
+14 | use crate::*; //~ ERROR #[project] attribute may not be used on glob imports
+ | ^
diff --git a/third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs b/third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs
new file mode 100644
index 0000000000..429d60f044
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.rs
@@ -0,0 +1,14 @@
+use pin_project::pin_project;
+
+#[pin_project(UnsafeUnpin)]
+struct Struct<T, U> {
+ #[pin]
+ inner: T,
+ other: U,
+}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Struct<(), ()>>(); //~ ERROR E0277
+}
diff --git a/third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr b/third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr
new file mode 100644
index 0000000000..0baefe3e1a
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unsafe_unpin/not-implement-unsafe-unpin.stderr
@@ -0,0 +1,11 @@
+error[E0277]: the trait bound `Struct<(), ()>: pin_project::UnsafeUnpin` is not satisfied
+ --> $DIR/not-implement-unsafe-unpin.rs:13:16
+ |
+10 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+13 | is_unpin::<Struct<(), ()>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^ the trait `pin_project::UnsafeUnpin` is not implemented for `Struct<(), ()>`
+ |
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, Struct<(), ()>>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Struct<(), ()>`
diff --git a/third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.rs b/third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.rs
new file mode 100644
index 0000000000..8896bfd2ae
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.rs
@@ -0,0 +1,43 @@
+use pin_project::{pin_project, UnsafeUnpin};
+use std::marker::PhantomPinned;
+
+fn is_unpin<T: Unpin>() {}
+
+#[pin_project(UnsafeUnpin)]
+pub struct Blah<T, U> {
+ field1: U,
+ #[pin]
+ field2: T,
+}
+
+#[allow(unsafe_code)]
+unsafe impl<T: Unpin, U> UnsafeUnpin for Blah<T, U> {}
+
+#[pin_project(UnsafeUnpin)]
+pub struct TrivialBounds {
+ #[pin]
+ field1: PhantomPinned,
+}
+
+#[pin_project(UnsafeUnpin)]
+pub struct OverlappingLifetimeNames<'pin, T, U> {
+ #[pin]
+ field1: U,
+ #[pin]
+ field2: Option<T>,
+ field3: &'pin (),
+}
+
+#[allow(unsafe_code)]
+unsafe impl<T: Unpin, U: Unpin> UnsafeUnpin for OverlappingLifetimeNames<'_, T, U> {}
+
+fn main() {
+ is_unpin::<Blah<PhantomPinned, ()>>(); //~ ERROR E0277
+ is_unpin::<Blah<(), PhantomPinned>>(); // Ok
+ is_unpin::<Blah<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
+
+ is_unpin::<TrivialBounds>(); //~ ERROR E0277
+
+ is_unpin::<OverlappingLifetimeNames<'_, PhantomPinned, ()>>(); //~ ERROR E0277
+ is_unpin::<OverlappingLifetimeNames<'_, (), PhantomPinned>>(); //~ ERROR E0277
+}
diff --git a/third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.stderr b/third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.stderr
new file mode 100644
index 0000000000..5494666ecc
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unsafe_unpin/proper_unpin.stderr
@@ -0,0 +1,63 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:35:5
+ |
+4 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+35 | is_unpin::<Blah<PhantomPinned, ()>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `Blah<std::marker::PhantomPinned, ()>`
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, Blah<std::marker::PhantomPinned, ()>>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Blah<std::marker::PhantomPinned, ()>`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:37:5
+ |
+4 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+37 | is_unpin::<Blah<PhantomPinned, PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `Blah<std::marker::PhantomPinned, std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, Blah<std::marker::PhantomPinned, std::marker::PhantomPinned>>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `Blah<std::marker::PhantomPinned, std::marker::PhantomPinned>`
+
+error[E0277]: the trait bound `TrivialBounds: pin_project::UnsafeUnpin` is not satisfied
+ --> $DIR/proper_unpin.rs:39:16
+ |
+4 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+39 | is_unpin::<TrivialBounds>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^ the trait `pin_project::UnsafeUnpin` is not implemented for `TrivialBounds`
+ |
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, TrivialBounds>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `TrivialBounds`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:41:5
+ |
+4 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+41 | is_unpin::<OverlappingLifetimeNames<'_, PhantomPinned, ()>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `OverlappingLifetimeNames<'_, std::marker::PhantomPinned, ()>`
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, OverlappingLifetimeNames<'_, std::marker::PhantomPinned, ()>>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `OverlappingLifetimeNames<'_, std::marker::PhantomPinned, ()>`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/proper_unpin.rs:42:5
+ |
+4 | fn is_unpin<T: Unpin>() {}
+ | ----- required by this bound in `is_unpin`
+...
+42 | is_unpin::<OverlappingLifetimeNames<'_, (), PhantomPinned>>(); //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `OverlappingLifetimeNames<'_, (), std::marker::PhantomPinned>`
+ = note: required because of the requirements on the impl of `pin_project::UnsafeUnpin` for `pin_project::__private::Wrapper<'_, OverlappingLifetimeNames<'_, (), std::marker::PhantomPinned>>`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `OverlappingLifetimeNames<'_, (), std::marker::PhantomPinned>`
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/README.md b/third_party/rust/pin-project/tests/ui/unstable-features/README.md
new file mode 100644
index 0000000000..b9215b6500
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/README.md
@@ -0,0 +1,5 @@
+# UI tests for unstable features
+
+These tests check how the guarantees and features provided by pin-project interact with unstable language features.
+
+The names of the files contained in this directory need to begin with the name of the feature.
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs
new file mode 100644
index 0000000000..22185eeaf4
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.rs
@@ -0,0 +1,19 @@
+// NB: If you change this test, change 'marker_trait_attr.rs' at the same time.
+
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[pin_project] //~ ERROR E0119
+struct Foo<T> {
+ #[pin]
+ x: T,
+}
+
+// unsound Unpin impl
+impl<T> Unpin for Foo<T> {}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Foo<PhantomPinned>>()
+}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.stderr
new file mode 100644
index 0000000000..da2c8ea695
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr-feature-gate.stderr
@@ -0,0 +1,10 @@
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_>`:
+ --> $DIR/marker_trait_attr-feature-gate.rs:6:1
+ |
+6 | #[pin_project] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^ conflicting implementation for `Foo<_>`
+...
+13 | impl<T> Unpin for Foo<T> {}
+ | ------------------------ first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.rs b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.rs
new file mode 100644
index 0000000000..0b8b30ad64
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.rs
@@ -0,0 +1,25 @@
+// NB: If you change this test, change 'marker_trait_attr-feature-gate.rs' at the same time.
+
+// marker_trait_attr
+// Tracking issue: https://github.com/rust-lang/rust/issues/29864
+#![feature(marker_trait_attr)]
+
+// See https://github.com/taiki-e/pin-project/issues/105#issuecomment-535355974
+
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[pin_project] //~ ERROR E0119
+struct Struct<T> {
+ #[pin]
+ x: T,
+}
+
+// unsound Unpin impl
+impl<T> Unpin for Struct<T> {}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Struct<PhantomPinned>>()
+}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.stderr
new file mode 100644
index 0000000000..9b3ec57ea4
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/marker_trait_attr.stderr
@@ -0,0 +1,10 @@
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Struct<_>`:
+ --> $DIR/marker_trait_attr.rs:12:1
+ |
+12 | #[pin_project] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^ conflicting implementation for `Struct<_>`
+...
+19 | impl<T> Unpin for Struct<T> {}
+ | --------------------------- first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs
new file mode 100644
index 0000000000..0bd4a32cc1
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.rs
@@ -0,0 +1,19 @@
+// NB: If you change this test, change 'overlapping_marker_traits.rs' at the same time.
+
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[pin_project] //~ ERROR E0119
+struct Struct<T> {
+ #[pin]
+ x: T,
+}
+
+// unsound Unpin impl
+impl<T> Unpin for Struct<T> {}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Struct<PhantomPinned>>()
+}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.stderr
new file mode 100644
index 0000000000..4a8e23843c
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits-feature-gate.stderr
@@ -0,0 +1,10 @@
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Struct<_>`:
+ --> $DIR/overlapping_marker_traits-feature-gate.rs:6:1
+ |
+6 | #[pin_project] //~ ERROR E0119
+ | ^^^^^^^^^^^^^^ conflicting implementation for `Struct<_>`
+...
+13 | impl<T> Unpin for Struct<T> {}
+ | --------------------------- first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.rs b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.rs
new file mode 100644
index 0000000000..28b23fe394
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.rs
@@ -0,0 +1,29 @@
+// NB: If you change this test, change 'overlapping_marker_traits-feature-gate.rs' at the same time.
+
+// This feature could break the guarantee for Unpin provided by pin-project,
+// but was removed in https://github.com/rust-lang/rust/pull/68544 (nightly-2020-02-06).
+// Refs:
+// * https://github.com/rust-lang/rust/issues/29864#issuecomment-515780867.
+// * https://github.com/taiki-e/pin-project/issues/105
+
+// overlapping_marker_traits
+// Tracking issue: https://github.com/rust-lang/rust/issues/29864
+#![feature(overlapping_marker_traits)]
+
+use pin_project::pin_project;
+use std::marker::PhantomPinned;
+
+#[pin_project]
+struct Foo<T> {
+ #[pin]
+ x: T,
+}
+
+// unsound Unpin impl
+impl<T> Unpin for Foo<T> {}
+
+fn is_unpin<T: Unpin>() {}
+
+fn main() {
+ is_unpin::<Foo<PhantomPinned>>()
+}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.stderr
new file mode 100644
index 0000000000..13ad810f69
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/overlapping_marker_traits.stderr
@@ -0,0 +1,18 @@
+error[E0557]: feature has been removed
+ --> $DIR/overlapping_marker_traits.rs:11:12
+ |
+11 | #![feature(overlapping_marker_traits)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ feature has been removed
+ |
+ = note: removed in favor of `#![feature(marker_trait_attr)]`
+
+error[E0119]: conflicting implementations of trait `std::marker::Unpin` for type `Foo<_>`:
+ --> $DIR/overlapping_marker_traits.rs:16:1
+ |
+16 | #[pin_project]
+ | ^^^^^^^^^^^^^^ conflicting implementation for `Foo<_>`
+...
+23 | impl<T> Unpin for Foo<T> {}
+ | ------------------------ first implementation here
+ |
+ = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs b/third_party/rust/pin-project/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs
new file mode 100644
index 0000000000..8ad8e41bb1
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/run-pass/stmt_expr_attributes.rs
@@ -0,0 +1,62 @@
+// NB: If you change this test, change 'stmt_expr_attributes-feature-gate.rs' at the same time.
+
+// proc_macro_hygiene
+// Tracking issue: https://github.com/rust-lang/rust/issues/54727
+#![feature(proc_macro_hygiene)]
+// stmt_expr_attributes
+// Tracking issue: https://github.com/rust-lang/rust/issues/15701
+#![feature(stmt_expr_attributes)]
+
+use pin_project::{pin_project, project};
+use std::pin::Pin;
+
+fn project_stmt_expr_nightly() {
+ #[pin_project]
+ enum Baz<A, B, C, D> {
+ Variant1(#[pin] A, B),
+ Variant2 {
+ #[pin]
+ field1: C,
+ field2: D,
+ },
+ None,
+ }
+
+ let mut baz = Baz::Variant1(1, 2);
+
+ let mut baz = Pin::new(&mut baz).project();
+
+ #[project]
+ match &mut baz {
+ Baz::Variant1(x, y) => {
+ let x: &mut Pin<&mut i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &mut &mut i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Baz::Variant2 { field1, field2 } => {
+ let _x: &mut Pin<&mut i32> = field1;
+ let _y: &mut &mut i32 = field2;
+ }
+ Baz::None => {}
+ }
+
+ let () = #[project]
+ match &mut baz {
+ Baz::Variant1(x, y) => {
+ let x: &mut Pin<&mut i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &mut &mut i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Baz::Variant2 { field1, field2 } => {
+ let _x: &mut Pin<&mut i32> = field1;
+ let _y: &mut &mut i32 = field2;
+ }
+ Baz::None => {}
+ };
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs b/third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs
new file mode 100644
index 0000000000..82267238f4
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.rs
@@ -0,0 +1,55 @@
+// NB: If you change this test, change 'stmt_expr_attributes.rs' at the same time.
+
+use pin_project::{pin_project, project};
+use std::pin::Pin;
+
+fn project_stmt_expr_nightly() {
+ #[pin_project]
+ enum Enum<A, B, C, D> {
+ Variant1(#[pin] A, B),
+ Variant2 {
+ #[pin]
+ field1: C,
+ field2: D,
+ },
+ None,
+ }
+
+ let mut baz = Enum::Variant1(1, 2);
+
+ let mut baz = Pin::new(&mut baz).project();
+
+ #[project] //~ ERROR E0658
+ match &mut baz {
+ Enum::Variant1(x, y) => {
+ let x: &mut Pin<&mut i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &mut &mut i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Enum::Variant2 { field1, field2 } => {
+ let _x: &mut Pin<&mut i32> = field1;
+ let _y: &mut &mut i32 = field2;
+ }
+ Enum::None => {}
+ }
+
+ let () = #[project] //~ ERROR E0658
+ match &mut baz {
+ Enum::Variant1(x, y) => {
+ let x: &mut Pin<&mut i32> = x;
+ assert_eq!(**x, 1);
+
+ let y: &mut &mut i32 = y;
+ assert_eq!(**y, 2);
+ }
+ Enum::Variant2 { field1, field2 } => {
+ let _x: &mut Pin<&mut i32> = field1;
+ let _y: &mut &mut i32 = field2;
+ }
+ Enum::None => {}
+ };
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr
new file mode 100644
index 0000000000..6510ec760b
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/stmt_expr_attributes-feature-gate.stderr
@@ -0,0 +1,35 @@
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/stmt_expr_attributes-feature-gate.rs:22:5
+ |
+22 | #[project] //~ ERROR E0658
+ | ^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: attributes on expressions are experimental
+ --> $DIR/stmt_expr_attributes-feature-gate.rs:38:14
+ |
+38 | let () = #[project] //~ ERROR E0658
+ | ^^^^^^^^^^
+ |
+ = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
+ = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to expressions
+ --> $DIR/stmt_expr_attributes-feature-gate.rs:22:5
+ |
+22 | #[project] //~ ERROR E0658
+ | ^^^^^^^^^^
+ |
+ = note: see issue #54727 <https://github.com/rust-lang/rust/issues/54727> for more information
+ = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
+
+error[E0658]: custom attributes cannot be applied to expressions
+ --> $DIR/stmt_expr_attributes-feature-gate.rs:38:14
+ |
+38 | let () = #[project] //~ ERROR E0658
+ | ^^^^^^^^^^
+ |
+ = note: see issue #54727 <https://github.com/rust-lang/rust/issues/54727> for more information
+ = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.rs b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.rs
new file mode 100644
index 0000000000..66e0ec4a4f
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.rs
@@ -0,0 +1,33 @@
+// NB: If you change this test, change 'trivial_bounds-feature-gate.rs' at the same time.
+
+// trivial_bounds
+// Tracking issue: https://github.com/rust-lang/rust/issues/48214
+#![feature(trivial_bounds)]
+
+use std::marker::{PhantomData, PhantomPinned};
+
+fn phantom_pinned() {
+ struct A(PhantomPinned);
+
+ // bug of trivial_bounds?
+ impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
+
+ struct Wrapper<T>(T);
+
+ impl<T> Unpin for Wrapper<T> where T: Unpin {}
+
+ struct B(PhantomPinned);
+
+ impl Unpin for B where Wrapper<PhantomPinned>: Unpin {} //~ Ok
+
+ struct WrapperWithLifetime<'a, T>(PhantomData<&'a ()>, T);
+
+ impl<T> Unpin for WrapperWithLifetime<'_, T> where T: Unpin {}
+
+ struct C(PhantomPinned);
+
+ impl<'a> Unpin for C where WrapperWithLifetime<'a, PhantomPinned>: Unpin {}
+ // Ok
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.stderr
new file mode 100644
index 0000000000..8370c456cc
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-bug.stderr
@@ -0,0 +1,5 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/trivial_bounds-bug.rs:13:43
+ |
+13 | impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
+ | ^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.rs b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.rs
new file mode 100644
index 0000000000..a6a4d84e61
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.rs
@@ -0,0 +1,52 @@
+// NB: If you change this test, change 'trivial_bounds.rs' at the same time.
+
+use std::marker::{PhantomData, PhantomPinned};
+
+fn phantom_pinned() {
+ struct A(PhantomPinned);
+
+ impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
+
+ struct Wrapper<T>(T);
+
+ impl<T> Unpin for Wrapper<T> where T: Unpin {}
+
+ struct B(PhantomPinned);
+
+ impl Unpin for B where Wrapper<PhantomPinned>: Unpin {} //~ ERROR E0277
+
+ struct WrapperWithLifetime<'a, T>(PhantomData<&'a ()>, T);
+
+ impl<T> Unpin for WrapperWithLifetime<'_, T> where T: Unpin {}
+
+ struct C(PhantomPinned);
+
+ impl<'a> Unpin for C where WrapperWithLifetime<'a, PhantomPinned>: Unpin {}
+ // Ok
+}
+
+fn inner() {
+ struct Inner(PhantomPinned);
+
+ struct A(Inner);
+
+ impl Unpin for A where Inner: Unpin {} //~ ERROR E0277
+
+ struct Wrapper<T>(T);
+
+ impl<T> Unpin for Wrapper<T> where T: Unpin {}
+
+ struct B(Inner);
+
+ impl Unpin for B where Wrapper<Inner>: Unpin {} //~ ERROR E0277
+
+ struct WrapperWithLifetime<'a, T>(PhantomData<&'a ()>, T);
+
+ impl<T> Unpin for WrapperWithLifetime<'_, T> where T: Unpin {}
+
+ struct C(Inner);
+
+ impl<'a> Unpin for C where WrapperWithLifetime<'a, Inner>: Unpin {} // Ok
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr
new file mode 100644
index 0000000000..f8ef886065
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds-feature-gate.stderr
@@ -0,0 +1,45 @@
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/trivial_bounds-feature-gate.rs:8:5
+ |
+8 | impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = help: see issue #48214
+ = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/trivial_bounds-feature-gate.rs:8:43
+ |
+8 | impl Unpin for A where PhantomPinned: Unpin {} //~ ERROR E0277
+ | ^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/trivial_bounds-feature-gate.rs:16:5
+ |
+16 | impl Unpin for B where Wrapper<PhantomPinned>: Unpin {} //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `phantom_pinned::Wrapper<std::marker::PhantomPinned>`
+ = help: see issue #48214
+ = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/trivial_bounds-feature-gate.rs:33:5
+ |
+33 | impl Unpin for A where Inner: Unpin {} //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `inner::Inner`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `inner::Inner`
+ = help: see issue #48214
+ = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error[E0277]: `std::marker::PhantomPinned` cannot be unpinned
+ --> $DIR/trivial_bounds-feature-gate.rs:41:5
+ |
+41 | impl Unpin for B where Wrapper<Inner>: Unpin {} //~ ERROR E0277
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `inner::Inner`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
+ |
+ = note: required because it appears within the type `inner::Inner`
+ = note: required because of the requirements on the impl of `std::marker::Unpin` for `inner::Wrapper<inner::Inner>`
+ = help: see issue #48214
+ = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.rs b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.rs
new file mode 100644
index 0000000000..680effe61d
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.rs
@@ -0,0 +1,34 @@
+// NB: If you change this test, change 'trivial_bounds-feature-gate.rs' at the same time.
+
+// trivial_bounds
+// Tracking issue: https://github.com/rust-lang/rust/issues/48214
+#![feature(trivial_bounds)]
+#![deny(trivial_bounds)]
+
+use std::marker::{PhantomData, PhantomPinned};
+
+fn inner() {
+ struct Inner(PhantomPinned);
+
+ struct A(Inner);
+
+ impl Unpin for A where Inner: Unpin {} //~ ERROR std::marker::Unpin does not depend on any type or lifetime parameters
+
+ struct Wrapper<T>(T);
+
+ impl<T> Unpin for Wrapper<T> where T: Unpin {}
+
+ struct B(Inner);
+
+ impl Unpin for B where Wrapper<Inner>: Unpin {} //~ ERROR std::marker::Unpin does not depend on any type or lifetime parameters
+
+ struct WrapperWithLifetime<'a, T>(PhantomData<&'a ()>, T);
+
+ impl<T> Unpin for WrapperWithLifetime<'_, T> where T: Unpin {}
+
+ struct C(Inner);
+
+ impl<'a> Unpin for C where WrapperWithLifetime<'a, Inner>: Unpin {} // Ok
+}
+
+fn main() {}
diff --git a/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.stderr b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.stderr
new file mode 100644
index 0000000000..03d0161443
--- /dev/null
+++ b/third_party/rust/pin-project/tests/ui/unstable-features/trivial_bounds.stderr
@@ -0,0 +1,17 @@
+error: Trait bound inner::Inner: std::marker::Unpin does not depend on any type or lifetime parameters
+ --> $DIR/trivial_bounds.rs:15:35
+ |
+15 | impl Unpin for A where Inner: Unpin {} //~ ERROR std::marker::Unpin does not depend on any type or lifetime parameters
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/trivial_bounds.rs:6:9
+ |
+6 | #![deny(trivial_bounds)]
+ | ^^^^^^^^^^^^^^
+
+error: Trait bound inner::Wrapper<inner::Inner>: std::marker::Unpin does not depend on any type or lifetime parameters
+ --> $DIR/trivial_bounds.rs:23:44
+ |
+23 | impl Unpin for B where Wrapper<Inner>: Unpin {} //~ ERROR std::marker::Unpin does not depend on any type or lifetime parameters
+ | ^^^^^
diff --git a/third_party/rust/pin-project/tests/unsafe_unpin.rs b/third_party/rust/pin-project/tests/unsafe_unpin.rs
new file mode 100644
index 0000000000..74673ca126
--- /dev/null
+++ b/third_party/rust/pin-project/tests/unsafe_unpin.rs
@@ -0,0 +1,76 @@
+#![warn(unsafe_code)]
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+#![allow(dead_code)]
+
+use pin_project::{pin_project, UnsafeUnpin};
+use std::{marker::PhantomPinned, pin::Pin};
+
+fn is_unpin<T: Unpin>() {}
+
+#[pin_project(UnsafeUnpin)]
+pub struct Blah<T, U> {
+ field1: U,
+ #[pin]
+ field2: T,
+}
+
+#[allow(unsafe_code)]
+unsafe impl<T: Unpin, U> UnsafeUnpin for Blah<T, U> {}
+
+#[pin_project(UnsafeUnpin)]
+pub struct OverlappingLifetimeNames<'pin, T, U> {
+ #[pin]
+ field1: T,
+ field2: U,
+ field3: &'pin (),
+}
+
+#[allow(unsafe_code)]
+unsafe impl<T: Unpin, U> UnsafeUnpin for OverlappingLifetimeNames<'_, T, U> {}
+
+#[test]
+fn unsafe_unpin() {
+ is_unpin::<Blah<(), PhantomPinned>>();
+ is_unpin::<OverlappingLifetimeNames<'_, (), ()>>();
+}
+
+#[test]
+fn trivial_bounds() {
+ #[pin_project(UnsafeUnpin)]
+ pub struct NotImplementUnsafUnpin {
+ #[pin]
+ field: PhantomPinned,
+ }
+}
+
+#[test]
+fn dst() {
+ #[pin_project(UnsafeUnpin)]
+ pub struct A<T: ?Sized> {
+ x: T,
+ }
+
+ #[pin_project(UnsafeUnpin)]
+ pub struct B<T: ?Sized> {
+ #[pin]
+ x: T,
+ }
+
+ #[pin_project(UnsafeUnpin)]
+ pub struct C<T: ?Sized>(T);
+
+ #[pin_project(UnsafeUnpin)]
+ pub struct D<T: ?Sized>(#[pin] T);
+}
+
+#[test]
+fn test() {
+ let mut x = OverlappingLifetimeNames { field1: 0, field2: 1, field3: &() };
+ let x = Pin::new(&mut x);
+ let y = x.as_ref().project_ref();
+ let _: Pin<&u8> = y.field1;
+ let _: &u8 = y.field2;
+ let y = x.project();
+ let _: Pin<&mut u8> = y.field1;
+ let _: &mut u8 = y.field2;
+}