summaryrefslogtreecommitdiffstats
path: root/third_party/rust/thiserror
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/thiserror
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/thiserror')
-rw-r--r--third_party/rust/thiserror/.cargo-checksum.json1
-rw-r--r--third_party/rust/thiserror/Cargo.toml47
-rw-r--r--third_party/rust/thiserror/LICENSE-APACHE201
-rw-r--r--third_party/rust/thiserror/LICENSE-MIT23
-rw-r--r--third_party/rust/thiserror/README.md222
-rw-r--r--third_party/rust/thiserror/build.rs66
-rw-r--r--third_party/rust/thiserror/rust-toolchain.toml2
-rw-r--r--third_party/rust/thiserror/src/aserror.rs48
-rw-r--r--third_party/rust/thiserror/src/display.rs28
-rw-r--r--third_party/rust/thiserror/src/lib.rs254
-rw-r--r--third_party/rust/thiserror/src/provide.rs15
-rw-r--r--third_party/rust/thiserror/tests/compiletest.rs7
-rw-r--r--third_party/rust/thiserror/tests/test_backtrace.rs297
-rw-r--r--third_party/rust/thiserror/tests/test_deprecated.rs10
-rw-r--r--third_party/rust/thiserror/tests/test_display.rs301
-rw-r--r--third_party/rust/thiserror/tests/test_error.rs56
-rw-r--r--third_party/rust/thiserror/tests/test_expr.rs88
-rw-r--r--third_party/rust/thiserror/tests/test_from.rs62
-rw-r--r--third_party/rust/thiserror/tests/test_generics.rs161
-rw-r--r--third_party/rust/thiserror/tests/test_lints.rs18
-rw-r--r--third_party/rust/thiserror/tests/test_option.rs108
-rw-r--r--third_party/rust/thiserror/tests/test_path.rs37
-rw-r--r--third_party/rust/thiserror/tests/test_source.rs65
-rw-r--r--third_party/rust/thiserror/tests/test_transparent.rs78
-rw-r--r--third_party/rust/thiserror/tests/ui/bad-field-attr.rs7
-rw-r--r--third_party/rust/thiserror/tests/ui/bad-field-attr.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/concat-display.rs15
-rw-r--r--third_party/rust/thiserror/tests/ui/concat-display.stderr10
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-enum-source.rs13
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-enum-source.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-fmt.rs8
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-fmt.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-struct-source.rs11
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-struct-source.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-transparent.rs8
-rw-r--r--third_party/rust/thiserror/tests/ui/duplicate-transparent.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.rs10
-rw-r--r--third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/from-not-source.rs11
-rw-r--r--third_party/rust/thiserror/tests/ui/from-not-source.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/lifetime.rs24
-rw-r--r--third_party/rust/thiserror/tests/ui/lifetime.stderr11
-rw-r--r--third_party/rust/thiserror/tests/ui/missing-fmt.rs10
-rw-r--r--third_party/rust/thiserror/tests/ui/missing-fmt.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/no-display.rs12
-rw-r--r--third_party/rust/thiserror/tests/ui/no-display.stderr17
-rw-r--r--third_party/rust/thiserror/tests/ui/source-enum-not-error.rs14
-rw-r--r--third_party/rust/thiserror/tests/ui/source-enum-not-error.stderr22
-rw-r--r--third_party/rust/thiserror/tests/ui/source-struct-not-error.rs12
-rw-r--r--third_party/rust/thiserror/tests/ui/source-struct-not-error.stderr21
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-display.rs8
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-display.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-enum-many.rs9
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-enum-many.stderr6
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-enum-source.rs9
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-enum-source.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-struct-many.rs10
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-struct-many.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-struct-source.rs7
-rw-r--r--third_party/rust/thiserror/tests/ui/transparent-struct-source.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/unexpected-field-fmt.rs11
-rw-r--r--third_party/rust/thiserror/tests/ui/unexpected-field-fmt.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/unexpected-struct-source.rs7
-rw-r--r--third_party/rust/thiserror/tests/ui/unexpected-struct-source.stderr5
-rw-r--r--third_party/rust/thiserror/tests/ui/union.rs9
-rw-r--r--third_party/rust/thiserror/tests/ui/union.stderr8
66 files changed, 2585 insertions, 0 deletions
diff --git a/third_party/rust/thiserror/.cargo-checksum.json b/third_party/rust/thiserror/.cargo-checksum.json
new file mode 100644
index 0000000000..46c80b7902
--- /dev/null
+++ b/third_party/rust/thiserror/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"5f5626ddedfae1d837620c7726546c50dc22e766b02c69c1e9c5b52e9ff618e9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"af998cfaa7f9967500104ee0ae347686d784e3b66be659ff87c89aab24ddda06","build.rs":"8b8d9cbf84b9a2fd108b49ecb4bae327da688d80b818acda9ee17170c788e193","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/aserror.rs":"c93bd9191f26a7599043b397e26822564d9bafaa339a19861182a9909e8a3811","src/display.rs":"63c492bfa8b8e9180ad5abcbe63c1173b4ad490c47ec33cac9a338f96c8f8e42","src/lib.rs":"3fcc3c1ab31a64215978b92e68c1421ec8c5fcb942e57eb35adb9cc07a865730","src/provide.rs":"b2f7a33f44f44a03e94f54cc4b79ba2dcc5fcf0fdf64b07cdd9588a6544c8d8e","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test_backtrace.rs":"fd1f326bc23e6c1611a51bc43c1d5092b32ee18a1613abe20da0818e5729c0ed","tests/test_deprecated.rs":"7b80a10f090a3982da017556d3d71398abcead59afd8278c7b9d9b1f7b66c7b3","tests/test_display.rs":"f7d023365adbd47a24cb62cea02905503fd54705cbfdffdfdb3412dc210737a9","tests/test_error.rs":"d06dca3c38f22d7ce4e27dadd6c0f78e5cefe3a2ebbc5fe44abc9ddd5ee1985f","tests/test_expr.rs":"388402702a3be4ffcd0574d66733e8932bf7d5de37544a00ecb0e4f8d8246da4","tests/test_from.rs":"de1347e62069f826d8616b9e45ce6cccc3a8a8049cb51bd22d6763efe6118b0c","tests/test_generics.rs":"4f33747e3f62550d5af94687679af230ef92fbb3247ae4b41df46792a040e4dc","tests/test_lints.rs":"c17d79d77edfcdd4b8f6dcdcd1c70ad065cfbc747e1a618ac6343315d0b59ea4","tests/test_option.rs":"3a82af1ad206444b9955e3f2fda508d70f887ad0b7f7986bafc17496f63b07ab","tests/test_path.rs":"ef5452c7e828a0179f5ace7e19f95b9762aa887caf10244adbfe36ded712c090","tests/test_source.rs":"f2f04f11bf8a709eddb1c68f113cda0c2be87e56800d6b9d991bedd545b4642f","tests/test_transparent.rs":"cd8d5be14d00d610a1782104bea6c013618501dab5c3625178ecfcf66e31f939","tests/ui/bad-field-attr.rs":"c5b567e3091969a01061843fb2d95c5e1aa3fa81edfeecdf416a84a6fba40aa8","tests/ui/bad-field-attr.stderr":"78f576d5ec66464a77f1cdf0f5bb7dcdf18f7f04f1165983a6239ec59d908ea3","tests/ui/concat-display.rs":"3995bd6b3bdd67df7bb16499775d89600c0dd20895633fe807396a64c117078d","tests/ui/concat-display.stderr":"256dfde61ee689ebe51588b135e2e030bdf95ba5adef1cb59f588c797bbdeef2","tests/ui/duplicate-enum-source.rs":"bfe28ce18042d446a76c7411aa233598211ce1157fdd3cb87bff3b3fa7c33131","tests/ui/duplicate-enum-source.stderr":"3d32fead420b27b4497be49080bc3b78f7f0ba339ead3de6c94e5dc20302c18f","tests/ui/duplicate-fmt.rs":"af53b66445bcce076a114376747f176b42c060a156563a41ccb638ae14c451fd","tests/ui/duplicate-fmt.stderr":"998bb121ce6f1595fd99529a7a1b06451b6bf476924337dce5524a83a7a5f1a1","tests/ui/duplicate-struct-source.rs":"f3d5f8e3d6fccfcdbb630db291353709583a920c6bf46f9f9de9966b67ea4c0f","tests/ui/duplicate-struct-source.stderr":"fb761d76668ac42357cf37b03c0abdbae5de0a828034990850291c9cb6ab766d","tests/ui/duplicate-transparent.rs":"41a9447e85f1a47027023442acde55c3d8610ec46d91b39bd43a42d7a004d747","tests/ui/duplicate-transparent.stderr":"4975abad43e973df158f18098d9bcb9dc39f8e75d3e733ed5d6620d1ee065c11","tests/ui/from-backtrace-backtrace.rs":"1fd51c5a1f7f6b6ee676d9fc798b6276ef2ce75def33d07f0e4b7bbde3291859","tests/ui/from-backtrace-backtrace.stderr":"f9774e9dad51374501ef4a55fa2dacece4d1c70e29ca18761394bdb80a9a74da","tests/ui/from-not-source.rs":"744a55aeffe11066830159ac023c33aaa5576e313b341fa24440ee13dfe3ac98","tests/ui/from-not-source.stderr":"525038e8b841707b927434cca4549168f73bd305faca17552a0d1fffa542ccc4","tests/ui/lifetime.rs":"e72e0391695e47fcd07edbf3819f114e468e2097086ec687781c7c8d6b4b7da7","tests/ui/lifetime.stderr":"d889a23f71324afe95dafc5f9d15337fbdbc9977cb8924f0cafe3a3becf4ced7","tests/ui/missing-fmt.rs":"bc9e2830e54c2474ff6c27a766ed3dee88d29e40f93f30e8d64d63233866c17d","tests/ui/missing-fmt.stderr":"9a20ccee9b660fe31a5b3199307b48580bb8305cb9ce33d97d3fc767a0cfc614","tests/ui/no-display.rs":"962245372272d23e9833311c15e73221b3c7da822a2ff90189613af56ffb5c2e","tests/ui/no-display.stderr":"d7bdecccb74d21677361fb7f89dc784dc859258afcf663fa1c48da6c172a61aa","tests/ui/source-enum-not-error.rs":"7c57c63b3ec37bc456738acea2e1038de5b0f32fe7e83984037d7ad1ed921737","tests/ui/source-enum-not-error.stderr":"feac587e2436fd7bed73e7265dceb31b495587f1a8eea5c5fefd9da66b912dac","tests/ui/source-struct-not-error.rs":"09fb7713637242dca9192585a6daeb8d732dc1c1d0fa522b74f1c98618e6d949","tests/ui/source-struct-not-error.stderr":"66fb5fa85d59f11d8b5f7ec99469a843c51943b0010e554bdf56376a0614a2ca","tests/ui/transparent-display.rs":"b3c59583eb64b0b5a246444456d03cf52d51bcdc08885023600dbb44fd87e5f2","tests/ui/transparent-display.stderr":"16d538914e0d92026bde4b4bec75660217da9ecc6b621d12d2eb81d33ed1d1da","tests/ui/transparent-enum-many.rs":"2a40a764fb4683bff57973eec61507a6c00f7d4d7a32da6e7bd0190c2e445434","tests/ui/transparent-enum-many.stderr":"f1d78c1d6d8edbef153420db4fb9ca3dc6076fa043b5b1bc0cd291daa417a3ea","tests/ui/transparent-enum-source.rs":"18f606a98ac0a53f08dc56f5f923b9cbe75d25ed34479c777b48dac305d5968c","tests/ui/transparent-enum-source.stderr":"1b2e0ac53951034575d43ec0396c4e2b3cfb272db2aef8d6baa13a7e1632cc84","tests/ui/transparent-struct-many.rs":"72c6b6c1a44c203d3bc68989b2f1ec092531ef75b745432824c3776c290326f6","tests/ui/transparent-struct-many.stderr":"7bd0536dbb54a0ce7d4a8e66ca7624a1b132d8a1d1e4fecca642ec77494ac01c","tests/ui/transparent-struct-source.rs":"863fa691ed7d27e8767da58d9ee11fd40d6642274b36338ca1074c07964ea2b3","tests/ui/transparent-struct-source.stderr":"267dab65929e67d32347fb467a00b43af931f8205d727d7671938580217fc70e","tests/ui/unexpected-field-fmt.rs":"29fba7b4d81c642ec8e47cfe053aa515acf9080a86d65e685363a48993becfe3","tests/ui/unexpected-field-fmt.stderr":"20731c4a08af04bed3ff513903adadd690b6bc532b15604557e7f25575a8338f","tests/ui/unexpected-struct-source.rs":"c6cbe882d622635c216feb8290b1bd536ce0ec4feee16bc087667a21b3641d5c","tests/ui/unexpected-struct-source.stderr":"7c8227513478f6cc09e8a28be337c8a0e758a06ca5978d774c91bd43c4a54043","tests/ui/union.rs":"331adff27cebd8b95b03b6742cc8247331fda1f961e1590ed39c8d39f50cf1d8","tests/ui/union.stderr":"5f67ad29753d6fb14bc03aef7d4a1f660ee7796e469c037efbf8b13456934ad3"},"package":"6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"} \ No newline at end of file
diff --git a/third_party/rust/thiserror/Cargo.toml b/third_party/rust/thiserror/Cargo.toml
new file mode 100644
index 0000000000..e235408d80
--- /dev/null
+++ b/third_party/rust/thiserror/Cargo.toml
@@ -0,0 +1,47 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.31"
+name = "thiserror"
+version = "1.0.38"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+description = "derive(Error)"
+documentation = "https://docs.rs/thiserror"
+readme = "README.md"
+keywords = [
+ "error",
+ "error-handling",
+ "derive",
+]
+categories = ["rust-patterns"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/thiserror"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies.thiserror-impl]
+version = "=1.0.38"
+
+[dev-dependencies.anyhow]
+version = "1.0.65"
+
+[dev-dependencies.ref-cast]
+version = "1.0"
+
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.trybuild]
+version = "1.0.66"
+features = ["diff"]
diff --git a/third_party/rust/thiserror/LICENSE-APACHE b/third_party/rust/thiserror/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/thiserror/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ 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/thiserror/LICENSE-MIT b/third_party/rust/thiserror/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/thiserror/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/thiserror/README.md b/third_party/rust/thiserror/README.md
new file mode 100644
index 0000000000..3ba375ff3f
--- /dev/null
+++ b/third_party/rust/thiserror/README.md
@@ -0,0 +1,222 @@
+derive(Error)
+=============
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/thiserror-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/thiserror)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/thiserror.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/thiserror)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-thiserror-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/thiserror)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/thiserror/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/thiserror/actions?query=branch%3Amaster)
+
+This library provides a convenient derive macro for the standard library's
+[`std::error::Error`] trait.
+
+[`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
+
+```toml
+[dependencies]
+thiserror = "1.0"
+```
+
+*Compiler support: requires rustc 1.31+*
+
+<br>
+
+## Example
+
+```rust
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum DataStoreError {
+ #[error("data store disconnected")]
+ Disconnect(#[from] io::Error),
+ #[error("the data for key `{0}` is not available")]
+ Redaction(String),
+ #[error("invalid header (expected {expected:?}, found {found:?})")]
+ InvalidHeader {
+ expected: String,
+ found: String,
+ },
+ #[error("unknown data store error")]
+ Unknown,
+}
+```
+
+<br>
+
+## Details
+
+- Thiserror deliberately does not appear in your public API. You get the same
+ thing as if you had written an implementation of `std::error::Error` by hand,
+ and switching from handwritten impls to thiserror or vice versa is not a
+ breaking change.
+
+- Errors may be enums, structs with named fields, tuple structs, or unit
+ structs.
+
+- A `Display` impl is generated for your error if you provide `#[error("...")]`
+ messages on the struct or each variant of your enum, as shown above in the
+ example.
+
+ The messages support a shorthand for interpolating fields from the error.
+
+ - `#[error("{var}")]`&ensp;⟶&ensp;`write!("{}", self.var)`
+ - `#[error("{0}")]`&ensp;⟶&ensp;`write!("{}", self.0)`
+ - `#[error("{var:?}")]`&ensp;⟶&ensp;`write!("{:?}", self.var)`
+ - `#[error("{0:?}")]`&ensp;⟶&ensp;`write!("{:?}", self.0)`
+
+ These shorthands can be used together with any additional format args, which
+ may be arbitrary expressions. For example:
+
+ ```rust
+ #[derive(Error, Debug)]
+ pub enum Error {
+ #[error("invalid rdo_lookahead_frames {0} (expected < {})", i32::MAX)]
+ InvalidLookahead(u32),
+ }
+ ```
+
+ If one of the additional expression arguments needs to refer to a field of the
+ struct or enum, then refer to named fields as `.var` and tuple fields as `.0`.
+
+ ```rust
+ #[derive(Error, Debug)]
+ pub enum Error {
+ #[error("first letter must be lowercase but was {:?}", first_char(.0))]
+ WrongCase(String),
+ #[error("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)]
+ OutOfBounds { idx: usize, limits: Limits },
+ }
+ ```
+
+- A `From` impl is generated for each variant containing a `#[from]` attribute.
+
+ Note that the variant must not contain any other fields beyond the source
+ error and possibly a backtrace. A backtrace is captured from within the `From`
+ impl if there is a field for it.
+
+ ```rust
+ #[derive(Error, Debug)]
+ pub enum MyError {
+ Io {
+ #[from]
+ source: io::Error,
+ backtrace: Backtrace,
+ },
+ }
+ ```
+
+- The Error trait's `source()` method is implemented to return whichever field
+ has a `#[source]` attribute or is named `source`, if any. This is for
+ identifying the underlying lower level error that caused your error.
+
+ The `#[from]` attribute always implies that the same field is `#[source]`, so
+ you don't ever need to specify both attributes.
+
+ Any error type that implements `std::error::Error` or dereferences to `dyn
+ std::error::Error` will work as a source.
+
+ ```rust
+ #[derive(Error, Debug)]
+ pub struct MyError {
+ msg: String,
+ #[source] // optional if field name is `source`
+ source: anyhow::Error,
+ }
+ ```
+
+- The Error trait's `provide()` method is implemented to provide whichever field
+ has a type named `Backtrace`, if any, as a `std::backtrace::Backtrace`.
+
+ ```rust
+ use std::backtrace::Backtrace;
+
+ #[derive(Error, Debug)]
+ pub struct MyError {
+ msg: String,
+ backtrace: Backtrace, // automatically detected
+ }
+ ```
+
+- If a field is both a source (named `source`, or has `#[source]` or `#[from]`
+ attribute) *and* is marked `#[backtrace]`, then the Error trait's `provide()`
+ method is forwarded to the source's `provide` so that both layers of the error
+ share the same backtrace.
+
+ ```rust
+ #[derive(Error, Debug)]
+ pub enum MyError {
+ Io {
+ #[backtrace]
+ source: io::Error,
+ },
+ }
+ ```
+
+- Errors may use `error(transparent)` to forward the source and Display methods
+ straight through to an underlying error without adding an additional message.
+ This would be appropriate for enums that need an "anything else" variant.
+
+ ```rust
+ #[derive(Error, Debug)]
+ pub enum MyError {
+ ...
+
+ #[error(transparent)]
+ Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error
+ }
+ ```
+
+ Another use case is hiding implementation details of an error representation
+ behind an opaque error type, so that the representation is able to evolve
+ without breaking the crate's public API.
+
+ ```rust
+ // PublicError is public, but opaque and easy to keep compatible.
+ #[derive(Error, Debug)]
+ #[error(transparent)]
+ pub struct PublicError(#[from] ErrorRepr);
+
+ impl PublicError {
+ // Accessors for anything we do want to expose publicly.
+ }
+
+ // Private and free to change across minor version of the crate.
+ #[derive(Error, Debug)]
+ enum ErrorRepr {
+ ...
+ }
+ ```
+
+- See also the [`anyhow`] library for a convenient single error type to use in
+ application code.
+
+ [`anyhow`]: https://github.com/dtolnay/anyhow
+
+<br>
+
+## Comparison to anyhow
+
+Use thiserror if you care about designing your own dedicated error type(s) so
+that the caller receives exactly the information that you choose in the event of
+failure. This most often applies to library-like code. Use [Anyhow] if you don't
+care what error type your functions return, you just want it to be easy. This is
+common in application-like code.
+
+[Anyhow]: https://github.com/dtolnay/anyhow
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+</sub>
diff --git a/third_party/rust/thiserror/build.rs b/third_party/rust/thiserror/build.rs
new file mode 100644
index 0000000000..004dfb0159
--- /dev/null
+++ b/third_party/rust/thiserror/build.rs
@@ -0,0 +1,66 @@
+use std::env;
+use std::fs;
+use std::path::Path;
+use std::process::{Command, ExitStatus, Stdio};
+use std::str;
+
+// This code exercises the surface area that we expect of the Provider API. If
+// the current toolchain is able to compile it, then thiserror is able to use
+// providers for backtrace support.
+const PROBE: &str = r#"
+ #![feature(provide_any)]
+
+ use std::any::{Demand, Provider};
+
+ fn _f<'a, P: Provider>(p: &'a P, demand: &mut Demand<'a>) {
+ p.provide(demand);
+ }
+"#;
+
+fn main() {
+ match compile_probe() {
+ Some(status) if status.success() => println!("cargo:rustc-cfg=provide_any"),
+ _ => {}
+ }
+}
+
+fn compile_probe() -> Option<ExitStatus> {
+ let rustc = env::var_os("RUSTC")?;
+ let out_dir = env::var_os("OUT_DIR")?;
+ let probefile = Path::new(&out_dir).join("probe.rs");
+ fs::write(&probefile, PROBE).ok()?;
+
+ // Make sure to pick up Cargo rustc configuration.
+ let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
+ let mut cmd = Command::new(wrapper);
+ // The wrapper's first argument is supposed to be the path to rustc.
+ cmd.arg(rustc);
+ cmd
+ } else {
+ Command::new(rustc)
+ };
+
+ cmd.stderr(Stdio::null())
+ .arg("--edition=2018")
+ .arg("--crate-name=thiserror_build")
+ .arg("--crate-type=lib")
+ .arg("--emit=metadata")
+ .arg("--out-dir")
+ .arg(out_dir)
+ .arg(probefile);
+
+ if let Some(target) = env::var_os("TARGET") {
+ cmd.arg("--target").arg(target);
+ }
+
+ // If Cargo wants to set RUSTFLAGS, use that.
+ if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
+ if !rustflags.is_empty() {
+ for arg in rustflags.split('\x1f') {
+ cmd.arg(arg);
+ }
+ }
+ }
+
+ cmd.status().ok()
+}
diff --git a/third_party/rust/thiserror/rust-toolchain.toml b/third_party/rust/thiserror/rust-toolchain.toml
new file mode 100644
index 0000000000..20fe888c30
--- /dev/null
+++ b/third_party/rust/thiserror/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+components = ["rust-src"]
diff --git a/third_party/rust/thiserror/src/aserror.rs b/third_party/rust/thiserror/src/aserror.rs
new file mode 100644
index 0000000000..5fea84ef88
--- /dev/null
+++ b/third_party/rust/thiserror/src/aserror.rs
@@ -0,0 +1,48 @@
+use std::error::Error;
+use std::panic::UnwindSafe;
+
+pub trait AsDynError<'a>: Sealed {
+ fn as_dyn_error(&self) -> &(dyn Error + 'a);
+}
+
+impl<'a, T: Error + 'a> AsDynError<'a> for T {
+ #[inline]
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
+ self
+ }
+}
+
+impl<'a> AsDynError<'a> for dyn Error + 'a {
+ #[inline]
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
+ self
+ }
+}
+
+impl<'a> AsDynError<'a> for dyn Error + Send + 'a {
+ #[inline]
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
+ self
+ }
+}
+
+impl<'a> AsDynError<'a> for dyn Error + Send + Sync + 'a {
+ #[inline]
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
+ self
+ }
+}
+
+impl<'a> AsDynError<'a> for dyn Error + Send + Sync + UnwindSafe + 'a {
+ #[inline]
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
+ self
+ }
+}
+
+pub trait Sealed {}
+impl<'a, T: Error + 'a> Sealed for T {}
+impl<'a> Sealed for dyn Error + 'a {}
+impl<'a> Sealed for dyn Error + Send + 'a {}
+impl<'a> Sealed for dyn Error + Send + Sync + 'a {}
+impl<'a> Sealed for dyn Error + Send + Sync + UnwindSafe + 'a {}
diff --git a/third_party/rust/thiserror/src/display.rs b/third_party/rust/thiserror/src/display.rs
new file mode 100644
index 0000000000..0eb0dd9e20
--- /dev/null
+++ b/third_party/rust/thiserror/src/display.rs
@@ -0,0 +1,28 @@
+use std::fmt::Display;
+use std::path::{self, Path, PathBuf};
+
+pub trait DisplayAsDisplay {
+ fn as_display(&self) -> Self;
+}
+
+impl<T: Display> DisplayAsDisplay for &T {
+ fn as_display(&self) -> Self {
+ self
+ }
+}
+
+pub trait PathAsDisplay {
+ fn as_display(&self) -> path::Display<'_>;
+}
+
+impl PathAsDisplay for Path {
+ fn as_display(&self) -> path::Display<'_> {
+ self.display()
+ }
+}
+
+impl PathAsDisplay for PathBuf {
+ fn as_display(&self) -> path::Display<'_> {
+ self.display()
+ }
+}
diff --git a/third_party/rust/thiserror/src/lib.rs b/third_party/rust/thiserror/src/lib.rs
new file mode 100644
index 0000000000..aae6552d09
--- /dev/null
+++ b/third_party/rust/thiserror/src/lib.rs
@@ -0,0 +1,254 @@
+//! [![github]](https://github.com/dtolnay/thiserror)&ensp;[![crates-io]](https://crates.io/crates/thiserror)&ensp;[![docs-rs]](https://docs.rs/thiserror)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! This library provides a convenient derive macro for the standard library's
+//! [`std::error::Error`] trait.
+//!
+//! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
+//!
+//! <br>
+//!
+//! # Example
+//!
+//! ```rust
+//! # use std::io;
+//! use thiserror::Error;
+//!
+//! #[derive(Error, Debug)]
+//! pub enum DataStoreError {
+//! #[error("data store disconnected")]
+//! Disconnect(#[from] io::Error),
+//! #[error("the data for key `{0}` is not available")]
+//! Redaction(String),
+//! #[error("invalid header (expected {expected:?}, found {found:?})")]
+//! InvalidHeader {
+//! expected: String,
+//! found: String,
+//! },
+//! #[error("unknown data store error")]
+//! Unknown,
+//! }
+//! ```
+//!
+//! <br>
+//!
+//! # Details
+//!
+//! - Thiserror deliberately does not appear in your public API. You get the
+//! same thing as if you had written an implementation of `std::error::Error`
+//! by hand, and switching from handwritten impls to thiserror or vice versa
+//! is not a breaking change.
+//!
+//! - Errors may be enums, structs with named fields, tuple structs, or unit
+//! structs.
+//!
+//! - A `Display` impl is generated for your error if you provide
+//! `#[error("...")]` messages on the struct or each variant of your enum, as
+//! shown above in the example.
+//!
+//! The messages support a shorthand for interpolating fields from the error.
+//!
+//! - `#[error("{var}")]`&ensp;⟶&ensp;`write!("{}", self.var)`
+//! - `#[error("{0}")]`&ensp;⟶&ensp;`write!("{}", self.0)`
+//! - `#[error("{var:?}")]`&ensp;⟶&ensp;`write!("{:?}", self.var)`
+//! - `#[error("{0:?}")]`&ensp;⟶&ensp;`write!("{:?}", self.0)`
+//!
+//! These shorthands can be used together with any additional format args,
+//! which may be arbitrary expressions. For example:
+//!
+//! ```rust
+//! # use std::i32;
+//! # use thiserror::Error;
+//! #
+//! #[derive(Error, Debug)]
+//! pub enum Error {
+//! #[error("invalid rdo_lookahead_frames {0} (expected < {})", i32::MAX)]
+//! InvalidLookahead(u32),
+//! }
+//! ```
+//!
+//! If one of the additional expression arguments needs to refer to a field of
+//! the struct or enum, then refer to named fields as `.var` and tuple fields
+//! as `.0`.
+//!
+//! ```rust
+//! # use thiserror::Error;
+//! #
+//! # fn first_char(s: &String) -> char {
+//! # s.chars().next().unwrap()
+//! # }
+//! #
+//! # #[derive(Debug)]
+//! # struct Limits {
+//! # lo: usize,
+//! # hi: usize,
+//! # }
+//! #
+//! #[derive(Error, Debug)]
+//! pub enum Error {
+//! #[error("first letter must be lowercase but was {:?}", first_char(.0))]
+//! WrongCase(String),
+//! #[error("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)]
+//! OutOfBounds { idx: usize, limits: Limits },
+//! }
+//! ```
+//!
+//! - A `From` impl is generated for each variant containing a `#[from]`
+//! attribute.
+//!
+//! Note that the variant must not contain any other fields beyond the source
+//! error and possibly a backtrace. A backtrace is captured from within the
+//! `From` impl if there is a field for it.
+//!
+//! ```rust
+//! # const IGNORE: &str = stringify! {
+//! #[derive(Error, Debug)]
+//! pub enum MyError {
+//! Io {
+//! #[from]
+//! source: io::Error,
+//! backtrace: Backtrace,
+//! },
+//! }
+//! # };
+//! ```
+//!
+//! - The Error trait's `source()` method is implemented to return whichever
+//! field has a `#[source]` attribute or is named `source`, if any. This is
+//! for identifying the underlying lower level error that caused your error.
+//!
+//! The `#[from]` attribute always implies that the same field is `#[source]`,
+//! so you don't ever need to specify both attributes.
+//!
+//! Any error type that implements `std::error::Error` or dereferences to `dyn
+//! std::error::Error` will work as a source.
+//!
+//! ```rust
+//! # use std::fmt::{self, Display};
+//! # use thiserror::Error;
+//! #
+//! #[derive(Error, Debug)]
+//! pub struct MyError {
+//! msg: String,
+//! #[source] // optional if field name is `source`
+//! source: anyhow::Error,
+//! }
+//! #
+//! # impl Display for MyError {
+//! # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+//! # unimplemented!()
+//! # }
+//! # }
+//! ```
+//!
+//! - The Error trait's `provide()` method is implemented to provide whichever
+//! field has a type named `Backtrace`, if any, as a
+//! `std::backtrace::Backtrace`.
+//!
+//! ```rust
+//! # const IGNORE: &str = stringify! {
+//! use std::backtrace::Backtrace;
+//!
+//! #[derive(Error, Debug)]
+//! pub struct MyError {
+//! msg: String,
+//! backtrace: Backtrace, // automatically detected
+//! }
+//! # };
+//! ```
+//!
+//! - If a field is both a source (named `source`, or has `#[source]` or
+//! `#[from]` attribute) *and* is marked `#[backtrace]`, then the Error
+//! trait's `provide()` method is forwarded to the source's `provide` so that
+//! both layers of the error share the same backtrace.
+//!
+//! ```rust
+//! # const IGNORE: &str = stringify! {
+//! #[derive(Error, Debug)]
+//! pub enum MyError {
+//! Io {
+//! #[backtrace]
+//! source: io::Error,
+//! },
+//! }
+//! # };
+//! ```
+//!
+//! - Errors may use `error(transparent)` to forward the source and Display
+//! methods straight through to an underlying error without adding an
+//! additional message. This would be appropriate for enums that need an
+//! "anything else" variant.
+//!
+//! ```
+//! # use thiserror::Error;
+//! #
+//! #[derive(Error, Debug)]
+//! pub enum MyError {
+//! # /*
+//! ...
+//! # */
+//!
+//! #[error(transparent)]
+//! Other(#[from] anyhow::Error), // source and Display delegate to anyhow::Error
+//! }
+//! ```
+//!
+//! Another use case is hiding implementation details of an error
+//! representation behind an opaque error type, so that the representation is
+//! able to evolve without breaking the crate's public API.
+//!
+//! ```
+//! # use thiserror::Error;
+//! #
+//! // PublicError is public, but opaque and easy to keep compatible.
+//! #[derive(Error, Debug)]
+//! #[error(transparent)]
+//! pub struct PublicError(#[from] ErrorRepr);
+//!
+//! impl PublicError {
+//! // Accessors for anything we do want to expose publicly.
+//! }
+//!
+//! // Private and free to change across minor version of the crate.
+//! #[derive(Error, Debug)]
+//! enum ErrorRepr {
+//! # /*
+//! ...
+//! # */
+//! }
+//! ```
+//!
+//! - See also the [`anyhow`] library for a convenient single error type to use
+//! in application code.
+//!
+//! [`anyhow`]: https://github.com/dtolnay/anyhow
+
+#![allow(
+ // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7421
+ clippy::doc_markdown,
+ clippy::module_name_repetitions,
+ clippy::return_self_not_must_use,
+ clippy::wildcard_imports,
+)]
+#![cfg_attr(provide_any, feature(provide_any))]
+
+mod aserror;
+mod display;
+#[cfg(provide_any)]
+mod provide;
+
+pub use thiserror_impl::*;
+
+// Not public API.
+#[doc(hidden)]
+pub mod __private {
+ pub use crate::aserror::AsDynError;
+ pub use crate::display::{DisplayAsDisplay, PathAsDisplay};
+ #[cfg(provide_any)]
+ pub use crate::provide::ThiserrorProvide;
+}
diff --git a/third_party/rust/thiserror/src/provide.rs b/third_party/rust/thiserror/src/provide.rs
new file mode 100644
index 0000000000..524e7435d7
--- /dev/null
+++ b/third_party/rust/thiserror/src/provide.rs
@@ -0,0 +1,15 @@
+use std::any::{Demand, Provider};
+
+pub trait ThiserrorProvide: Sealed {
+ fn thiserror_provide<'a>(&'a self, demand: &mut Demand<'a>);
+}
+
+impl<T: Provider + ?Sized> ThiserrorProvide for T {
+ #[inline]
+ fn thiserror_provide<'a>(&'a self, demand: &mut Demand<'a>) {
+ self.provide(demand);
+ }
+}
+
+pub trait Sealed {}
+impl<T: Provider + ?Sized> Sealed for T {}
diff --git a/third_party/rust/thiserror/tests/compiletest.rs b/third_party/rust/thiserror/tests/compiletest.rs
new file mode 100644
index 0000000000..7974a6249e
--- /dev/null
+++ b/third_party/rust/thiserror/tests/compiletest.rs
@@ -0,0 +1,7 @@
+#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/third_party/rust/thiserror/tests/test_backtrace.rs b/third_party/rust/thiserror/tests/test_backtrace.rs
new file mode 100644
index 0000000000..43f68b8b7e
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_backtrace.rs
@@ -0,0 +1,297 @@
+#![cfg_attr(
+ thiserror_nightly_testing,
+ feature(error_generic_member_access, provide_any)
+)]
+
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct Inner;
+
+#[cfg(thiserror_nightly_testing)]
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct InnerBacktrace {
+ backtrace: std::backtrace::Backtrace,
+}
+
+#[cfg(thiserror_nightly_testing)]
+pub mod structs {
+ use super::{Inner, InnerBacktrace};
+ use std::any;
+ use std::backtrace::Backtrace;
+ use std::error::Error;
+ use std::sync::Arc;
+ use thiserror::Error;
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct PlainBacktrace {
+ backtrace: Backtrace,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct ExplicitBacktrace {
+ #[backtrace]
+ backtrace: Backtrace,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct OptBacktrace {
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct ArcBacktrace {
+ #[backtrace]
+ backtrace: Arc<Backtrace>,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct BacktraceFrom {
+ #[from]
+ source: Inner,
+ #[backtrace]
+ backtrace: Backtrace,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct CombinedBacktraceFrom {
+ #[from]
+ #[backtrace]
+ source: InnerBacktrace,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct OptBacktraceFrom {
+ #[from]
+ source: Inner,
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct ArcBacktraceFrom {
+ #[from]
+ source: Inner,
+ #[backtrace]
+ backtrace: Arc<Backtrace>,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct AnyhowBacktrace {
+ #[backtrace]
+ source: anyhow::Error,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct BoxDynErrorBacktrace {
+ #[backtrace]
+ source: Box<dyn Error>,
+ }
+
+ #[test]
+ fn test_backtrace() {
+ let error = PlainBacktrace {
+ backtrace: Backtrace::capture(),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = ExplicitBacktrace {
+ backtrace: Backtrace::capture(),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = OptBacktrace {
+ backtrace: Some(Backtrace::capture()),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = ArcBacktrace {
+ backtrace: Arc::new(Backtrace::capture()),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = BacktraceFrom::from(Inner);
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = CombinedBacktraceFrom::from(InnerBacktrace {
+ backtrace: Backtrace::capture(),
+ });
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = OptBacktraceFrom::from(Inner);
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = ArcBacktraceFrom::from(Inner);
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = AnyhowBacktrace {
+ source: anyhow::Error::msg("..."),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = BoxDynErrorBacktrace {
+ source: Box::new(PlainBacktrace {
+ backtrace: Backtrace::capture(),
+ }),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+ }
+
+ // https://github.com/dtolnay/thiserror/issues/185 -- std::error::Error and
+ // std::any::Provide both have a method called 'provide', so directly
+ // calling it from generated code could be ambiguous.
+ #[test]
+ fn test_provide_name_collision() {
+ use std::any::Provider;
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ struct MyError {
+ #[source]
+ #[backtrace]
+ x: std::io::Error,
+ }
+
+ let _: dyn Error;
+ let _: dyn Provider;
+ }
+}
+
+#[cfg(thiserror_nightly_testing)]
+pub mod enums {
+ use super::{Inner, InnerBacktrace};
+ use std::any;
+ use std::backtrace::Backtrace;
+ use std::sync::Arc;
+ use thiserror::Error;
+
+ #[derive(Error, Debug)]
+ pub enum PlainBacktrace {
+ #[error("...")]
+ Test { backtrace: Backtrace },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum ExplicitBacktrace {
+ #[error("...")]
+ Test {
+ #[backtrace]
+ backtrace: Backtrace,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum OptBacktrace {
+ #[error("...")]
+ Test {
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum ArcBacktrace {
+ #[error("...")]
+ Test {
+ #[backtrace]
+ backtrace: Arc<Backtrace>,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum BacktraceFrom {
+ #[error("...")]
+ Test {
+ #[from]
+ source: Inner,
+ #[backtrace]
+ backtrace: Backtrace,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum CombinedBacktraceFrom {
+ #[error("...")]
+ Test {
+ #[from]
+ #[backtrace]
+ source: InnerBacktrace,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum OptBacktraceFrom {
+ #[error("...")]
+ Test {
+ #[from]
+ source: Inner,
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum ArcBacktraceFrom {
+ #[error("...")]
+ Test {
+ #[from]
+ source: Inner,
+ #[backtrace]
+ backtrace: Arc<Backtrace>,
+ },
+ }
+
+ #[test]
+ fn test_backtrace() {
+ let error = PlainBacktrace::Test {
+ backtrace: Backtrace::capture(),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = ExplicitBacktrace::Test {
+ backtrace: Backtrace::capture(),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = OptBacktrace::Test {
+ backtrace: Some(Backtrace::capture()),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = ArcBacktrace::Test {
+ backtrace: Arc::new(Backtrace::capture()),
+ };
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = BacktraceFrom::from(Inner);
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = CombinedBacktraceFrom::from(InnerBacktrace {
+ backtrace: Backtrace::capture(),
+ });
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = OptBacktraceFrom::from(Inner);
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+ let error = ArcBacktraceFrom::from(Inner);
+ assert!(any::request_ref::<Backtrace>(&error).is_some());
+ }
+}
+
+#[test]
+#[cfg_attr(not(thiserror_nightly_testing), ignore)]
+fn test_backtrace() {}
diff --git a/third_party/rust/thiserror/tests/test_deprecated.rs b/third_party/rust/thiserror/tests/test_deprecated.rs
new file mode 100644
index 0000000000..5524666abc
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_deprecated.rs
@@ -0,0 +1,10 @@
+#![deny(deprecated, clippy::all, clippy::pedantic)]
+
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum Error {
+ #[deprecated]
+ #[error("...")]
+ Deprecated,
+}
diff --git a/third_party/rust/thiserror/tests/test_display.rs b/third_party/rust/thiserror/tests/test_display.rs
new file mode 100644
index 0000000000..99ce2fdede
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_display.rs
@@ -0,0 +1,301 @@
+use std::fmt::{self, Display};
+use thiserror::Error;
+
+fn assert<T: Display>(expected: &str, value: T) {
+ assert_eq!(expected, value.to_string());
+}
+
+#[test]
+fn test_braced() {
+ #[derive(Error, Debug)]
+ #[error("braced error: {msg}")]
+ struct Error {
+ msg: String,
+ }
+
+ let msg = "T".to_owned();
+ assert("braced error: T", Error { msg });
+}
+
+#[test]
+fn test_braced_unused() {
+ #[derive(Error, Debug)]
+ #[error("braced error")]
+ struct Error {
+ extra: usize,
+ }
+
+ assert("braced error", Error { extra: 0 });
+}
+
+#[test]
+fn test_tuple() {
+ #[derive(Error, Debug)]
+ #[error("tuple error: {0}")]
+ struct Error(usize);
+
+ assert("tuple error: 0", Error(0));
+}
+
+#[test]
+fn test_unit() {
+ #[derive(Error, Debug)]
+ #[error("unit error")]
+ struct Error;
+
+ assert("unit error", Error);
+}
+
+#[test]
+fn test_enum() {
+ #[derive(Error, Debug)]
+ enum Error {
+ #[error("braced error: {id}")]
+ Braced { id: usize },
+ #[error("tuple error: {0}")]
+ Tuple(usize),
+ #[error("unit error")]
+ Unit,
+ }
+
+ assert("braced error: 0", Error::Braced { id: 0 });
+ assert("tuple error: 0", Error::Tuple(0));
+ assert("unit error", Error::Unit);
+}
+
+#[test]
+fn test_constants() {
+ #[derive(Error, Debug)]
+ #[error("{MSG}: {id:?} (code {CODE:?})")]
+ struct Error {
+ id: &'static str,
+ }
+
+ const MSG: &str = "failed to do";
+ const CODE: usize = 9;
+
+ assert("failed to do: \"\" (code 9)", Error { id: "" });
+}
+
+#[test]
+fn test_inherit() {
+ #[derive(Error, Debug)]
+ #[error("{0}")]
+ enum Error {
+ Some(&'static str),
+ #[error("other error")]
+ Other(&'static str),
+ }
+
+ assert("some error", Error::Some("some error"));
+ assert("other error", Error::Other("..."));
+}
+
+#[test]
+fn test_brace_escape() {
+ #[derive(Error, Debug)]
+ #[error("fn main() {{}}")]
+ struct Error;
+
+ assert("fn main() {}", Error);
+}
+
+#[test]
+fn test_expr() {
+ #[derive(Error, Debug)]
+ #[error("1 + 1 = {}", 1 + 1)]
+ struct Error;
+ assert("1 + 1 = 2", Error);
+}
+
+#[test]
+fn test_nested() {
+ #[derive(Error, Debug)]
+ #[error("!bool = {}", not(.0))]
+ struct Error(bool);
+
+ #[allow(clippy::trivially_copy_pass_by_ref)]
+ fn not(bool: &bool) -> bool {
+ !*bool
+ }
+
+ assert("!bool = false", Error(true));
+}
+
+#[test]
+fn test_match() {
+ #[derive(Error, Debug)]
+ #[error("{}: {0}", match .1 {
+ Some(n) => format!("error occurred with {}", n),
+ None => "there was an empty error".to_owned(),
+ })]
+ struct Error(String, Option<usize>);
+
+ assert(
+ "error occurred with 1: ...",
+ Error("...".to_owned(), Some(1)),
+ );
+ assert(
+ "there was an empty error: ...",
+ Error("...".to_owned(), None),
+ );
+}
+
+#[test]
+fn test_nested_display() {
+ // Same behavior as the one in `test_match`, but without String allocations.
+ #[derive(Error, Debug)]
+ #[error("{}", {
+ struct Msg<'a>(&'a String, &'a Option<usize>);
+ impl<'a> Display for Msg<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self.1 {
+ Some(n) => write!(formatter, "error occurred with {}", n),
+ None => write!(formatter, "there was an empty error"),
+ }?;
+ write!(formatter, ": {}", self.0)
+ }
+ }
+ Msg(.0, .1)
+ })]
+ struct Error(String, Option<usize>);
+
+ assert(
+ "error occurred with 1: ...",
+ Error("...".to_owned(), Some(1)),
+ );
+ assert(
+ "there was an empty error: ...",
+ Error("...".to_owned(), None),
+ );
+}
+
+#[test]
+fn test_void() {
+ #[allow(clippy::empty_enum)]
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub enum Error {}
+
+ let _: Error;
+}
+
+#[test]
+fn test_mixed() {
+ #[derive(Error, Debug)]
+ #[error("a={a} :: b={} :: c={c} :: d={d}", 1, c = 2, d = 3)]
+ struct Error {
+ a: usize,
+ d: usize,
+ }
+
+ assert("a=0 :: b=1 :: c=2 :: d=3", Error { a: 0, d: 0 });
+}
+
+#[test]
+fn test_ints() {
+ #[derive(Error, Debug)]
+ enum Error {
+ #[error("error {0}")]
+ Tuple(usize, usize),
+ #[error("error {0}", '?')]
+ Struct { v: usize },
+ }
+
+ assert("error 9", Error::Tuple(9, 0));
+ assert("error ?", Error::Struct { v: 0 });
+}
+
+#[test]
+fn test_trailing_comma() {
+ #[derive(Error, Debug)]
+ #[error(
+ "error {0}",
+ )]
+ #[rustfmt::skip]
+ struct Error(char);
+
+ assert("error ?", Error('?'));
+}
+
+#[test]
+fn test_field() {
+ #[derive(Debug)]
+ struct Inner {
+ data: usize,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("{}", .0.data)]
+ struct Error(Inner);
+
+ assert("0", Error(Inner { data: 0 }));
+}
+
+#[test]
+fn test_macro_rules() {
+ // Regression test for https://github.com/dtolnay/thiserror/issues/86
+
+ macro_rules! decl_error {
+ ($variant:ident($value:ident)) => {
+ #[derive(Debug, Error)]
+ pub enum Error0 {
+ #[error("{0:?}")]
+ $variant($value),
+ }
+
+ #[derive(Debug, Error)]
+ #[error("{0:?}")]
+ pub enum Error1 {
+ $variant($value),
+ }
+ };
+ }
+
+ decl_error!(Repro(u8));
+
+ assert("0", Error0::Repro(0));
+ assert("0", Error1::Repro(0));
+}
+
+#[test]
+fn test_raw() {
+ #[derive(Error, Debug)]
+ #[error("braced raw error: {r#fn}")]
+ struct Error {
+ r#fn: &'static str,
+ }
+
+ assert("braced raw error: T", Error { r#fn: "T" });
+}
+
+#[test]
+fn test_raw_enum() {
+ #[derive(Error, Debug)]
+ enum Error {
+ #[error("braced raw error: {r#fn}")]
+ Braced { r#fn: &'static str },
+ }
+
+ assert("braced raw error: T", Error::Braced { r#fn: "T" });
+}
+
+#[test]
+fn test_raw_conflict() {
+ #[derive(Error, Debug)]
+ enum Error {
+ #[error("braced raw error: {r#func}, {func}", func = "U")]
+ Braced { r#func: &'static str },
+ }
+
+ assert("braced raw error: T, U", Error::Braced { r#func: "T" });
+}
+
+#[test]
+fn test_keyword() {
+ #[derive(Error, Debug)]
+ #[error("error: {type}", type = 1)]
+ struct Error;
+
+ assert("error: 1", Error);
+}
diff --git a/third_party/rust/thiserror/tests/test_error.rs b/third_party/rust/thiserror/tests/test_error.rs
new file mode 100644
index 0000000000..fab934d789
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_error.rs
@@ -0,0 +1,56 @@
+#![allow(dead_code)]
+
+use std::fmt::{self, Display};
+use std::io;
+use thiserror::Error;
+
+macro_rules! unimplemented_display {
+ ($ty:ty) => {
+ impl Display for $ty {
+ fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
+ unimplemented!()
+ }
+ }
+ };
+}
+
+#[derive(Error, Debug)]
+struct BracedError {
+ msg: String,
+ pos: usize,
+}
+
+#[derive(Error, Debug)]
+struct TupleError(String, usize);
+
+#[derive(Error, Debug)]
+struct UnitError;
+
+#[derive(Error, Debug)]
+struct WithSource {
+ #[source]
+ cause: io::Error,
+}
+
+#[derive(Error, Debug)]
+struct WithAnyhow {
+ #[source]
+ cause: anyhow::Error,
+}
+
+#[derive(Error, Debug)]
+enum EnumError {
+ Braced {
+ #[source]
+ cause: io::Error,
+ },
+ Tuple(#[source] io::Error),
+ Unit,
+}
+
+unimplemented_display!(BracedError);
+unimplemented_display!(TupleError);
+unimplemented_display!(UnitError);
+unimplemented_display!(WithSource);
+unimplemented_display!(WithAnyhow);
+unimplemented_display!(EnumError);
diff --git a/third_party/rust/thiserror/tests/test_expr.rs b/third_party/rust/thiserror/tests/test_expr.rs
new file mode 100644
index 0000000000..34de56087b
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_expr.rs
@@ -0,0 +1,88 @@
+#![allow(clippy::iter_cloned_collect, clippy::option_if_let_else)]
+
+use std::fmt::Display;
+use thiserror::Error;
+
+// Some of the elaborate cases from the rcc codebase, which is a C compiler in
+// Rust. https://github.com/jyn514/rcc/blob/0.8.0/src/data/error.rs
+#[derive(Error, Debug)]
+pub enum CompilerError {
+ #[error("cannot shift {} by {maximum} or more bits (got {current})", if *.is_left { "left" } else { "right" })]
+ TooManyShiftBits {
+ is_left: bool,
+ maximum: u64,
+ current: u64,
+ },
+
+ #[error("#error {}", (.0).iter().copied().collect::<Vec<_>>().join(" "))]
+ User(Vec<&'static str>),
+
+ #[error("overflow while parsing {}integer literal",
+ if let Some(signed) = .is_signed {
+ if *signed { "signed "} else { "unsigned "}
+ } else {
+ ""
+ }
+ )]
+ IntegerOverflow { is_signed: Option<bool> },
+
+ #[error("overflow while parsing {}integer literal", match .is_signed {
+ Some(true) => "signed ",
+ Some(false) => "unsigned ",
+ None => "",
+ })]
+ IntegerOverflow2 { is_signed: Option<bool> },
+}
+
+// Examples drawn from Rustup.
+#[derive(Error, Debug)]
+pub enum RustupError {
+ #[error(
+ "toolchain '{name}' does not contain component {component}{}",
+ .suggestion
+ .as_ref()
+ .map_or_else(String::new, |s| format!("; did you mean '{}'?", s)),
+ )]
+ UnknownComponent {
+ name: String,
+ component: String,
+ suggestion: Option<String>,
+ },
+}
+
+fn assert<T: Display>(expected: &str, value: T) {
+ assert_eq!(expected, value.to_string());
+}
+
+#[test]
+fn test_rcc() {
+ assert(
+ "cannot shift left by 32 or more bits (got 50)",
+ CompilerError::TooManyShiftBits {
+ is_left: true,
+ maximum: 32,
+ current: 50,
+ },
+ );
+
+ assert("#error A B C", CompilerError::User(vec!["A", "B", "C"]));
+
+ assert(
+ "overflow while parsing signed integer literal",
+ CompilerError::IntegerOverflow {
+ is_signed: Some(true),
+ },
+ );
+}
+
+#[test]
+fn test_rustup() {
+ assert(
+ "toolchain 'nightly' does not contain component clipy; did you mean 'clippy'?",
+ RustupError::UnknownComponent {
+ name: "nightly".to_owned(),
+ component: "clipy".to_owned(),
+ suggestion: Some("clippy".to_owned()),
+ },
+ );
+}
diff --git a/third_party/rust/thiserror/tests/test_from.rs b/third_party/rust/thiserror/tests/test_from.rs
new file mode 100644
index 0000000000..1f387055f5
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_from.rs
@@ -0,0 +1,62 @@
+use std::io;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct ErrorStruct {
+ #[from]
+ source: io::Error,
+}
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct ErrorStructOptional {
+ #[from]
+ source: Option<io::Error>,
+}
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct ErrorTuple(#[from] io::Error);
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct ErrorTupleOptional(#[from] Option<io::Error>);
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub enum ErrorEnum {
+ Test {
+ #[from]
+ source: io::Error,
+ },
+}
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub enum ErrorEnumOptional {
+ Test {
+ #[from]
+ source: Option<io::Error>,
+ },
+}
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub enum Many {
+ Any(#[from] anyhow::Error),
+ Io(#[from] io::Error),
+}
+
+fn assert_impl<T: From<io::Error>>() {}
+
+#[test]
+fn test_from() {
+ assert_impl::<ErrorStruct>();
+ assert_impl::<ErrorStructOptional>();
+ assert_impl::<ErrorTuple>();
+ assert_impl::<ErrorTupleOptional>();
+ assert_impl::<ErrorEnum>();
+ assert_impl::<ErrorEnumOptional>();
+ assert_impl::<Many>();
+}
diff --git a/third_party/rust/thiserror/tests/test_generics.rs b/third_party/rust/thiserror/tests/test_generics.rs
new file mode 100644
index 0000000000..4ab9f37786
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_generics.rs
@@ -0,0 +1,161 @@
+#![allow(clippy::needless_late_init)]
+
+use std::fmt::{self, Debug, Display};
+use thiserror::Error;
+
+pub struct NoFormat;
+
+#[derive(Debug)]
+pub struct DebugOnly;
+
+pub struct DisplayOnly;
+
+impl Display for DisplayOnly {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("display only")
+ }
+}
+
+#[derive(Debug)]
+pub struct DebugAndDisplay;
+
+impl Display for DebugAndDisplay {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("debug and display")
+ }
+}
+
+// Should expand to:
+//
+// impl<E> Display for EnumDebugField<E>
+// where
+// E: Debug;
+//
+// impl<E> Error for EnumDebugField<E>
+// where
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub enum EnumDebugGeneric<E> {
+ #[error("{0:?}")]
+ FatalError(E),
+}
+
+// Should expand to:
+//
+// impl<E> Display for EnumFromGeneric<E>;
+//
+// impl<E> Error for EnumFromGeneric<E>
+// where
+// EnumDebugGeneric<E>: Error + 'static,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub enum EnumFromGeneric<E> {
+ #[error("enum from generic")]
+ Source(#[from] EnumDebugGeneric<E>),
+}
+
+// Should expand to:
+//
+// impl<HasDisplay, HasDebug, HasNeither> Display
+// for EnumCompound<HasDisplay, HasDebug, HasNeither>
+// where
+// HasDisplay: Display,
+// HasDebug: Debug;
+//
+// impl<HasDisplay, HasDebug, HasNeither> Error
+// for EnumCompound<HasDisplay, HasDebug, HasNeither>
+// where
+// Self: Debug + Display;
+//
+#[derive(Error)]
+pub enum EnumCompound<HasDisplay, HasDebug, HasNeither> {
+ #[error("{0} {1:?}")]
+ DisplayDebug(HasDisplay, HasDebug),
+ #[error("{0}")]
+ Display(HasDisplay, HasNeither),
+ #[error("{1:?}")]
+ Debug(HasNeither, HasDebug),
+}
+
+impl<HasDisplay, HasDebug, HasNeither> Debug for EnumCompound<HasDisplay, HasDebug, HasNeither> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("EnumCompound")
+ }
+}
+
+#[test]
+fn test_display_enum_compound() {
+ let mut instance: EnumCompound<DisplayOnly, DebugOnly, NoFormat>;
+
+ instance = EnumCompound::DisplayDebug(DisplayOnly, DebugOnly);
+ assert_eq!(format!("{}", instance), "display only DebugOnly");
+
+ instance = EnumCompound::Display(DisplayOnly, NoFormat);
+ assert_eq!(format!("{}", instance), "display only");
+
+ instance = EnumCompound::Debug(NoFormat, DebugOnly);
+ assert_eq!(format!("{}", instance), "DebugOnly");
+}
+
+// Should expand to:
+//
+// impl<E> Display for EnumTransparentGeneric<E>
+// where
+// E: Display;
+//
+// impl<E> Error for EnumTransparentGeneric<E>
+// where
+// E: Error,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub enum EnumTransparentGeneric<E> {
+ #[error(transparent)]
+ Other(E),
+}
+
+// Should expand to:
+//
+// impl<E> Display for StructDebugGeneric<E>
+// where
+// E: Debug;
+//
+// impl<E> Error for StructDebugGeneric<E>
+// where
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+#[error("{underlying:?}")]
+pub struct StructDebugGeneric<E> {
+ pub underlying: E,
+}
+
+// Should expand to:
+//
+// impl<E> Error for StructFromGeneric<E>
+// where
+// StructDebugGeneric<E>: Error + 'static,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub struct StructFromGeneric<E> {
+ #[from]
+ pub source: StructDebugGeneric<E>,
+}
+
+// Should expand to:
+//
+// impl<E> Display for StructTransparentGeneric<E>
+// where
+// E: Display;
+//
+// impl<E> Error for StructTransparentGeneric<E>
+// where
+// E: Error,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+#[error(transparent)]
+pub struct StructTransparentGeneric<E>(E);
diff --git a/third_party/rust/thiserror/tests/test_lints.rs b/third_party/rust/thiserror/tests/test_lints.rs
new file mode 100644
index 0000000000..59699a4a3f
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_lints.rs
@@ -0,0 +1,18 @@
+use thiserror::Error;
+
+pub use std::error::Error;
+
+#[test]
+fn test_unused_qualifications() {
+ #![deny(unused_qualifications)]
+
+ // Expansion of derive(Error) macro can't know whether something like
+ // std::error::Error is already imported in the caller's scope so it must
+ // suppress unused_qualifications.
+
+ #[derive(Debug, Error)]
+ #[error("...")]
+ pub struct MyError;
+
+ let _: MyError;
+}
diff --git a/third_party/rust/thiserror/tests/test_option.rs b/third_party/rust/thiserror/tests/test_option.rs
new file mode 100644
index 0000000000..ed5287dc92
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_option.rs
@@ -0,0 +1,108 @@
+#![cfg_attr(
+ thiserror_nightly_testing,
+ feature(error_generic_member_access, provide_any)
+)]
+
+#[cfg(thiserror_nightly_testing)]
+pub mod structs {
+ use std::backtrace::Backtrace;
+ use thiserror::Error;
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct OptSourceNoBacktrace {
+ #[source]
+ source: Option<anyhow::Error>,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct OptSourceAlwaysBacktrace {
+ #[source]
+ source: Option<anyhow::Error>,
+ backtrace: Backtrace,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct NoSourceOptBacktrace {
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct AlwaysSourceOptBacktrace {
+ source: anyhow::Error,
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
+ pub struct OptSourceOptBacktrace {
+ #[source]
+ source: Option<anyhow::Error>,
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ }
+}
+
+#[cfg(thiserror_nightly_testing)]
+pub mod enums {
+ use std::backtrace::Backtrace;
+ use thiserror::Error;
+
+ #[derive(Error, Debug)]
+ pub enum OptSourceNoBacktrace {
+ #[error("...")]
+ Test {
+ #[source]
+ source: Option<anyhow::Error>,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum OptSourceAlwaysBacktrace {
+ #[error("...")]
+ Test {
+ #[source]
+ source: Option<anyhow::Error>,
+ backtrace: Backtrace,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum NoSourceOptBacktrace {
+ #[error("...")]
+ Test {
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum AlwaysSourceOptBacktrace {
+ #[error("...")]
+ Test {
+ source: anyhow::Error,
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ },
+ }
+
+ #[derive(Error, Debug)]
+ pub enum OptSourceOptBacktrace {
+ #[error("...")]
+ Test {
+ #[source]
+ source: Option<anyhow::Error>,
+ #[backtrace]
+ backtrace: Option<Backtrace>,
+ },
+ }
+}
+
+#[test]
+#[cfg_attr(not(thiserror_nightly_testing), ignore)]
+fn test_option() {}
diff --git a/third_party/rust/thiserror/tests/test_path.rs b/third_party/rust/thiserror/tests/test_path.rs
new file mode 100644
index 0000000000..a34a3d74e9
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_path.rs
@@ -0,0 +1,37 @@
+use ref_cast::RefCast;
+use std::fmt::Display;
+use std::path::{Path, PathBuf};
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("failed to read '{file}'")]
+struct StructPathBuf {
+ file: PathBuf,
+}
+
+#[derive(Error, Debug, RefCast)]
+#[repr(C)]
+#[error("failed to read '{file}'")]
+struct StructPath {
+ file: Path,
+}
+
+#[derive(Error, Debug)]
+enum EnumPathBuf {
+ #[error("failed to read '{0}'")]
+ Read(PathBuf),
+}
+
+fn assert<T: Display>(expected: &str, value: T) {
+ assert_eq!(expected, value.to_string());
+}
+
+#[test]
+fn test_display() {
+ let path = Path::new("/thiserror");
+ let file = path.to_owned();
+ assert("failed to read '/thiserror'", StructPathBuf { file });
+ let file = path.to_owned();
+ assert("failed to read '/thiserror'", EnumPathBuf::Read(file));
+ assert("failed to read '/thiserror'", StructPath::ref_cast(path));
+}
diff --git a/third_party/rust/thiserror/tests/test_source.rs b/third_party/rust/thiserror/tests/test_source.rs
new file mode 100644
index 0000000000..637f4ac0a2
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_source.rs
@@ -0,0 +1,65 @@
+use std::error::Error as StdError;
+use std::io;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("implicit source")]
+pub struct ImplicitSource {
+ source: io::Error,
+}
+
+#[derive(Error, Debug)]
+#[error("explicit source")]
+pub struct ExplicitSource {
+ source: String,
+ #[source]
+ io: io::Error,
+}
+
+#[derive(Error, Debug)]
+#[error("boxed source")]
+pub struct BoxedSource {
+ #[source]
+ source: Box<dyn StdError + Send + 'static>,
+}
+
+#[test]
+fn test_implicit_source() {
+ let io = io::Error::new(io::ErrorKind::Other, "oh no!");
+ let error = ImplicitSource { source: io };
+ error.source().unwrap().downcast_ref::<io::Error>().unwrap();
+}
+
+#[test]
+fn test_explicit_source() {
+ let io = io::Error::new(io::ErrorKind::Other, "oh no!");
+ let error = ExplicitSource {
+ source: String::new(),
+ io,
+ };
+ error.source().unwrap().downcast_ref::<io::Error>().unwrap();
+}
+
+#[test]
+fn test_boxed_source() {
+ let source = Box::new(io::Error::new(io::ErrorKind::Other, "oh no!"));
+ let error = BoxedSource { source };
+ error.source().unwrap().downcast_ref::<io::Error>().unwrap();
+}
+
+macro_rules! error_from_macro {
+ ($($variants:tt)*) => {
+ #[derive(Error)]
+ #[derive(Debug)]
+ pub enum MacroSource {
+ $($variants)*
+ }
+ }
+}
+
+// Test that we generate impls with the proper hygiene
+#[rustfmt::skip]
+error_from_macro! {
+ #[error("Something")]
+ Variant(#[from] io::Error)
+}
diff --git a/third_party/rust/thiserror/tests/test_transparent.rs b/third_party/rust/thiserror/tests/test_transparent.rs
new file mode 100644
index 0000000000..6f3c03ec7a
--- /dev/null
+++ b/third_party/rust/thiserror/tests/test_transparent.rs
@@ -0,0 +1,78 @@
+use anyhow::anyhow;
+use std::error::Error as _;
+use std::io;
+use thiserror::Error;
+
+#[test]
+fn test_transparent_struct() {
+ #[derive(Error, Debug)]
+ #[error(transparent)]
+ struct Error(ErrorKind);
+
+ #[derive(Error, Debug)]
+ enum ErrorKind {
+ #[error("E0")]
+ E0,
+ #[error("E1")]
+ E1(#[from] io::Error),
+ }
+
+ let error = Error(ErrorKind::E0);
+ assert_eq!("E0", error.to_string());
+ assert!(error.source().is_none());
+
+ let io = io::Error::new(io::ErrorKind::Other, "oh no!");
+ let error = Error(ErrorKind::from(io));
+ assert_eq!("E1", error.to_string());
+ error.source().unwrap().downcast_ref::<io::Error>().unwrap();
+}
+
+#[test]
+fn test_transparent_enum() {
+ #[derive(Error, Debug)]
+ enum Error {
+ #[error("this failed")]
+ This,
+ #[error(transparent)]
+ Other(anyhow::Error),
+ }
+
+ let error = Error::This;
+ assert_eq!("this failed", error.to_string());
+
+ let error = Error::Other(anyhow!("inner").context("outer"));
+ assert_eq!("outer", error.to_string());
+ assert_eq!("inner", error.source().unwrap().to_string());
+}
+
+#[test]
+fn test_anyhow() {
+ #[derive(Error, Debug)]
+ #[error(transparent)]
+ struct Any(#[from] anyhow::Error);
+
+ let error = Any::from(anyhow!("inner").context("outer"));
+ assert_eq!("outer", error.to_string());
+ assert_eq!("inner", error.source().unwrap().to_string());
+}
+
+#[test]
+fn test_non_static() {
+ #[derive(Error, Debug)]
+ #[error(transparent)]
+ struct Error<'a> {
+ inner: ErrorKind<'a>,
+ }
+
+ #[derive(Error, Debug)]
+ enum ErrorKind<'a> {
+ #[error("unexpected token: {:?}", token)]
+ Unexpected { token: &'a str },
+ }
+
+ let error = Error {
+ inner: ErrorKind::Unexpected { token: "error" },
+ };
+ assert_eq!("unexpected token: \"error\"", error.to_string());
+ assert!(error.source().is_none());
+}
diff --git a/third_party/rust/thiserror/tests/ui/bad-field-attr.rs b/third_party/rust/thiserror/tests/ui/bad-field-attr.rs
new file mode 100644
index 0000000000..d5429b2b26
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/bad-field-attr.rs
@@ -0,0 +1,7 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error(transparent)]
+pub struct Error(#[error(transparent)] std::io::Error);
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/bad-field-attr.stderr b/third_party/rust/thiserror/tests/ui/bad-field-attr.stderr
new file mode 100644
index 0000000000..5fb5744156
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/bad-field-attr.stderr
@@ -0,0 +1,5 @@
+error: #[error(transparent)] needs to go outside the enum or struct, not on an individual field
+ --> tests/ui/bad-field-attr.rs:5:18
+ |
+5 | pub struct Error(#[error(transparent)] std::io::Error);
+ | ^^^^^^^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/concat-display.rs b/third_party/rust/thiserror/tests/ui/concat-display.rs
new file mode 100644
index 0000000000..8b53cc0cd9
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/concat-display.rs
@@ -0,0 +1,15 @@
+use thiserror::Error;
+
+macro_rules! error_type {
+ ($name:ident, $what:expr) => {
+ // Use #[error("invalid {}", $what)] instead.
+
+ #[derive(Error, Debug)]
+ #[error(concat!("invalid ", $what))]
+ pub struct $name;
+ };
+}
+
+error_type!(Error, "foo");
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/concat-display.stderr b/third_party/rust/thiserror/tests/ui/concat-display.stderr
new file mode 100644
index 0000000000..dbecd69f2b
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/concat-display.stderr
@@ -0,0 +1,10 @@
+error: expected string literal
+ --> tests/ui/concat-display.rs:8:17
+ |
+8 | #[error(concat!("invalid ", $what))]
+ | ^^^^^^
+...
+13 | error_type!(Error, "foo");
+ | ------------------------- in this macro invocation
+ |
+ = note: this error originates in the macro `error_type` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-enum-source.rs b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.rs
new file mode 100644
index 0000000000..15e579f8fa
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.rs
@@ -0,0 +1,13 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum ErrorEnum {
+ Confusing {
+ #[source]
+ a: std::io::Error,
+ #[source]
+ b: anyhow::Error,
+ },
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-enum-source.stderr b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.stderr
new file mode 100644
index 0000000000..4a4b2d3989
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.stderr
@@ -0,0 +1,5 @@
+error: duplicate #[source] attribute
+ --> tests/ui/duplicate-enum-source.rs:8:9
+ |
+8 | #[source]
+ | ^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-fmt.rs b/third_party/rust/thiserror/tests/ui/duplicate-fmt.rs
new file mode 100644
index 0000000000..cb3d67881f
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-fmt.rs
@@ -0,0 +1,8 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("...")]
+#[error("...")]
+pub struct Error;
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-fmt.stderr b/third_party/rust/thiserror/tests/ui/duplicate-fmt.stderr
new file mode 100644
index 0000000000..532b16bdb6
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-fmt.stderr
@@ -0,0 +1,5 @@
+error: only one #[error(...)] attribute is allowed
+ --> tests/ui/duplicate-fmt.rs:5:1
+ |
+5 | #[error("...")]
+ | ^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-struct-source.rs b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.rs
new file mode 100644
index 0000000000..569df8dd40
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.rs
@@ -0,0 +1,11 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub struct ErrorStruct {
+ #[source]
+ a: std::io::Error,
+ #[source]
+ b: anyhow::Error,
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-struct-source.stderr b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.stderr
new file mode 100644
index 0000000000..c8de5747df
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.stderr
@@ -0,0 +1,5 @@
+error: duplicate #[source] attribute
+ --> tests/ui/duplicate-struct-source.rs:7:5
+ |
+7 | #[source]
+ | ^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-transparent.rs b/third_party/rust/thiserror/tests/ui/duplicate-transparent.rs
new file mode 100644
index 0000000000..49c0e46679
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-transparent.rs
@@ -0,0 +1,8 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error(transparent)]
+#[error(transparent)]
+pub struct Error(anyhow::Error);
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/duplicate-transparent.stderr b/third_party/rust/thiserror/tests/ui/duplicate-transparent.stderr
new file mode 100644
index 0000000000..a8308790e0
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/duplicate-transparent.stderr
@@ -0,0 +1,5 @@
+error: duplicate #[error(transparent)] attribute
+ --> tests/ui/duplicate-transparent.rs:5:1
+ |
+5 | #[error(transparent)]
+ | ^^^^^^^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.rs b/third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.rs
new file mode 100644
index 0000000000..8f411bf5d8
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.rs
@@ -0,0 +1,10 @@
+// https://github.com/dtolnay/thiserror/issues/163
+
+use std::backtrace::Backtrace;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct Error(#[from] #[backtrace] std::io::Error, Backtrace);
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.stderr b/third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.stderr
new file mode 100644
index 0000000000..55d647b425
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/from-backtrace-backtrace.stderr
@@ -0,0 +1,5 @@
+error: deriving From requires no fields other than source and backtrace
+ --> tests/ui/from-backtrace-backtrace.rs:8:18
+ |
+8 | pub struct Error(#[from] #[backtrace] std::io::Error, Backtrace);
+ | ^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/from-not-source.rs b/third_party/rust/thiserror/tests/ui/from-not-source.rs
new file mode 100644
index 0000000000..d1855bec5c
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/from-not-source.rs
@@ -0,0 +1,11 @@
+use thiserror::Error;
+
+#[derive(Debug, Error)]
+pub struct Error {
+ #[source]
+ source: std::io::Error,
+ #[from]
+ other: anyhow::Error,
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/from-not-source.stderr b/third_party/rust/thiserror/tests/ui/from-not-source.stderr
new file mode 100644
index 0000000000..97136017df
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/from-not-source.stderr
@@ -0,0 +1,5 @@
+error: #[from] is only supported on the source field, not any other field
+ --> tests/ui/from-not-source.rs:7:5
+ |
+7 | #[from]
+ | ^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/lifetime.rs b/third_party/rust/thiserror/tests/ui/lifetime.rs
new file mode 100644
index 0000000000..698f8c4e8a
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/lifetime.rs
@@ -0,0 +1,24 @@
+use std::fmt::Debug;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("error")]
+struct Error<'a>(#[from] Inner<'a>);
+
+#[derive(Error, Debug)]
+#[error("{0}")]
+struct Inner<'a>(&'a str);
+
+#[derive(Error, Debug)]
+enum Enum<'a> {
+ #[error("error")]
+ Foo(#[from] Generic<&'a str>),
+}
+
+#[derive(Error, Debug)]
+#[error("{0:?}")]
+struct Generic<T: Debug>(T);
+
+fn main() -> Result<(), Error<'static>> {
+ Err(Error(Inner("some text")))
+}
diff --git a/third_party/rust/thiserror/tests/ui/lifetime.stderr b/third_party/rust/thiserror/tests/ui/lifetime.stderr
new file mode 100644
index 0000000000..8b58136e52
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/lifetime.stderr
@@ -0,0 +1,11 @@
+error: non-static lifetimes are not allowed in the source of an error, because std::error::Error requires the source is dyn Error + 'static
+ --> tests/ui/lifetime.rs:6:26
+ |
+6 | struct Error<'a>(#[from] Inner<'a>);
+ | ^^^^^^^^^
+
+error: non-static lifetimes are not allowed in the source of an error, because std::error::Error requires the source is dyn Error + 'static
+ --> tests/ui/lifetime.rs:15:17
+ |
+15 | Foo(#[from] Generic<&'a str>),
+ | ^^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/missing-fmt.rs b/third_party/rust/thiserror/tests/ui/missing-fmt.rs
new file mode 100644
index 0000000000..d52fbdf0d9
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/missing-fmt.rs
@@ -0,0 +1,10 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum Error {
+ #[error("...")]
+ A(usize),
+ B(usize),
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/missing-fmt.stderr b/third_party/rust/thiserror/tests/ui/missing-fmt.stderr
new file mode 100644
index 0000000000..c0be37357e
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/missing-fmt.stderr
@@ -0,0 +1,5 @@
+error: missing #[error("...")] display attribute
+ --> tests/ui/missing-fmt.rs:7:5
+ |
+7 | B(usize),
+ | ^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/no-display.rs b/third_party/rust/thiserror/tests/ui/no-display.rs
new file mode 100644
index 0000000000..181a66e02c
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/no-display.rs
@@ -0,0 +1,12 @@
+use thiserror::Error;
+
+#[derive(Debug)]
+struct NoDisplay;
+
+#[derive(Error, Debug)]
+#[error("thread: {thread}")]
+pub struct Error {
+ thread: NoDisplay,
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/no-display.stderr b/third_party/rust/thiserror/tests/ui/no-display.stderr
new file mode 100644
index 0000000000..76818e1e5e
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/no-display.stderr
@@ -0,0 +1,17 @@
+error[E0599]: the method `as_display` exists for reference `&NoDisplay`, but its trait bounds were not satisfied
+ --> tests/ui/no-display.rs:7:9
+ |
+4 | struct NoDisplay;
+ | ---------------- doesn't satisfy `NoDisplay: std::fmt::Display`
+...
+7 | #[error("thread: {thread}")]
+ | ^^^^^^^^^^^^^^^^^^ method cannot be called on `&NoDisplay` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `NoDisplay: std::fmt::Display`
+ which is required by `&NoDisplay: DisplayAsDisplay`
+note: the trait `std::fmt::Display` must be implemented
+ --> $RUST/core/src/fmt/mod.rs
+ |
+ | pub trait Display {
+ | ^^^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/source-enum-not-error.rs b/third_party/rust/thiserror/tests/ui/source-enum-not-error.rs
new file mode 100644
index 0000000000..3eb0d3e866
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/source-enum-not-error.rs
@@ -0,0 +1,14 @@
+use thiserror::Error;
+
+#[derive(Debug)]
+pub struct NotError;
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub enum ErrorEnum {
+ Broken {
+ source: NotError,
+ },
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/source-enum-not-error.stderr b/third_party/rust/thiserror/tests/ui/source-enum-not-error.stderr
new file mode 100644
index 0000000000..750c69eb3e
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/source-enum-not-error.stderr
@@ -0,0 +1,22 @@
+error[E0599]: the method `as_dyn_error` exists for reference `&NotError`, but its trait bounds were not satisfied
+ --> tests/ui/source-enum-not-error.rs:10:9
+ |
+4 | pub struct NotError;
+ | -------------------
+ | |
+ | doesn't satisfy `NotError: AsDynError<'_>`
+ | doesn't satisfy `NotError: std::error::Error`
+...
+10 | source: NotError,
+ | ^^^^^^ method cannot be called on `&NotError` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `NotError: std::error::Error`
+ which is required by `NotError: AsDynError<'_>`
+ `&NotError: std::error::Error`
+ which is required by `&NotError: AsDynError<'_>`
+note: the trait `std::error::Error` must be implemented
+ --> $RUST/core/src/error.rs
+ |
+ | pub trait Error: Debug + Display {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/source-struct-not-error.rs b/third_party/rust/thiserror/tests/ui/source-struct-not-error.rs
new file mode 100644
index 0000000000..d59df1eef8
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/source-struct-not-error.rs
@@ -0,0 +1,12 @@
+use thiserror::Error;
+
+#[derive(Debug)]
+struct NotError;
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct ErrorStruct {
+ source: NotError,
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/source-struct-not-error.stderr b/third_party/rust/thiserror/tests/ui/source-struct-not-error.stderr
new file mode 100644
index 0000000000..b98460fcbe
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/source-struct-not-error.stderr
@@ -0,0 +1,21 @@
+error[E0599]: the method `as_dyn_error` exists for struct `NotError`, but its trait bounds were not satisfied
+ --> tests/ui/source-struct-not-error.rs:9:5
+ |
+4 | struct NotError;
+ | ---------------
+ | |
+ | method `as_dyn_error` not found for this struct
+ | doesn't satisfy `NotError: AsDynError<'_>`
+ | doesn't satisfy `NotError: std::error::Error`
+...
+9 | source: NotError,
+ | ^^^^^^ method cannot be called on `NotError` due to unsatisfied trait bounds
+ |
+ = note: the following trait bounds were not satisfied:
+ `NotError: std::error::Error`
+ which is required by `NotError: AsDynError<'_>`
+note: the trait `std::error::Error` must be implemented
+ --> $RUST/core/src/error.rs
+ |
+ | pub trait Error: Debug + Display {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/transparent-display.rs b/third_party/rust/thiserror/tests/ui/transparent-display.rs
new file mode 100644
index 0000000000..2a59f183ba
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-display.rs
@@ -0,0 +1,8 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error(transparent)]
+#[error("...")]
+pub struct Error(anyhow::Error);
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/transparent-display.stderr b/third_party/rust/thiserror/tests/ui/transparent-display.stderr
new file mode 100644
index 0000000000..54d958b278
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-display.stderr
@@ -0,0 +1,5 @@
+error: cannot have both #[error(transparent)] and a display attribute
+ --> tests/ui/transparent-display.rs:5:1
+ |
+5 | #[error("...")]
+ | ^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-many.rs b/third_party/rust/thiserror/tests/ui/transparent-enum-many.rs
new file mode 100644
index 0000000000..e2a73a4700
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-enum-many.rs
@@ -0,0 +1,9 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum Error {
+ #[error(transparent)]
+ Other(anyhow::Error, String),
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-many.stderr b/third_party/rust/thiserror/tests/ui/transparent-enum-many.stderr
new file mode 100644
index 0000000000..a9adfa5a90
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-enum-many.stderr
@@ -0,0 +1,6 @@
+error: #[error(transparent)] requires exactly one field
+ --> tests/ui/transparent-enum-many.rs:5:5
+ |
+5 | / #[error(transparent)]
+6 | | Other(anyhow::Error, String),
+ | |________________________________^
diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-source.rs b/third_party/rust/thiserror/tests/ui/transparent-enum-source.rs
new file mode 100644
index 0000000000..3849f66e78
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-enum-source.rs
@@ -0,0 +1,9 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum Error {
+ #[error(transparent)]
+ Other(#[source] anyhow::Error),
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-source.stderr b/third_party/rust/thiserror/tests/ui/transparent-enum-source.stderr
new file mode 100644
index 0000000000..ccb9067762
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-enum-source.stderr
@@ -0,0 +1,5 @@
+error: transparent variant can't contain #[source]
+ --> tests/ui/transparent-enum-source.rs:6:11
+ |
+6 | Other(#[source] anyhow::Error),
+ | ^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-many.rs b/third_party/rust/thiserror/tests/ui/transparent-struct-many.rs
new file mode 100644
index 0000000000..18f2466450
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-struct-many.rs
@@ -0,0 +1,10 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error(transparent)]
+pub struct Error {
+ inner: anyhow::Error,
+ what: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-many.stderr b/third_party/rust/thiserror/tests/ui/transparent-struct-many.stderr
new file mode 100644
index 0000000000..c0e3806e7f
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-struct-many.stderr
@@ -0,0 +1,5 @@
+error: #[error(transparent)] requires exactly one field
+ --> tests/ui/transparent-struct-many.rs:4:1
+ |
+4 | #[error(transparent)]
+ | ^^^^^^^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-source.rs b/third_party/rust/thiserror/tests/ui/transparent-struct-source.rs
new file mode 100644
index 0000000000..d4512c288b
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-struct-source.rs
@@ -0,0 +1,7 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error(transparent)]
+pub struct Error(#[source] anyhow::Error);
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-source.stderr b/third_party/rust/thiserror/tests/ui/transparent-struct-source.stderr
new file mode 100644
index 0000000000..3012ca3119
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/transparent-struct-source.stderr
@@ -0,0 +1,5 @@
+error: transparent error struct can't contain #[source]
+ --> tests/ui/transparent-struct-source.rs:5:18
+ |
+5 | pub struct Error(#[source] anyhow::Error);
+ | ^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.rs b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.rs
new file mode 100644
index 0000000000..7c439d941f
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.rs
@@ -0,0 +1,11 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum Error {
+ What {
+ #[error("...")]
+ io: std::io::Error,
+ },
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.stderr b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.stderr
new file mode 100644
index 0000000000..bf3c24df29
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.stderr
@@ -0,0 +1,5 @@
+error: not expected here; the #[error(...)] attribute belongs on top of a struct or an enum variant
+ --> tests/ui/unexpected-field-fmt.rs:6:9
+ |
+6 | #[error("...")]
+ | ^^^^^^^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/unexpected-struct-source.rs b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.rs
new file mode 100644
index 0000000000..f39649424c
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.rs
@@ -0,0 +1,7 @@
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[source]
+pub struct Error;
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/unexpected-struct-source.stderr b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.stderr
new file mode 100644
index 0000000000..6f15841dc0
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.stderr
@@ -0,0 +1,5 @@
+error: not expected here; the #[source] attribute belongs on a specific field
+ --> tests/ui/unexpected-struct-source.rs:4:1
+ |
+4 | #[source]
+ | ^^^^^^^^^
diff --git a/third_party/rust/thiserror/tests/ui/union.rs b/third_party/rust/thiserror/tests/ui/union.rs
new file mode 100644
index 0000000000..cd6a9346d5
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/union.rs
@@ -0,0 +1,9 @@
+use thiserror::Error;
+
+#[derive(Error)]
+pub union U {
+ msg: &'static str,
+ num: usize,
+}
+
+fn main() {}
diff --git a/third_party/rust/thiserror/tests/ui/union.stderr b/third_party/rust/thiserror/tests/ui/union.stderr
new file mode 100644
index 0000000000..3ec4d71c0d
--- /dev/null
+++ b/third_party/rust/thiserror/tests/ui/union.stderr
@@ -0,0 +1,8 @@
+error: union as errors are not supported
+ --> tests/ui/union.rs:4:1
+ |
+4 | / pub union U {
+5 | | msg: &'static str,
+6 | | num: usize,
+7 | | }
+ | |_^