summaryrefslogtreecommitdiffstats
path: root/third_party/rust/derive_more
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/derive_more
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/derive_more')
-rw-r--r--third_party/rust/derive_more/.cargo-checksum.json1
-rw-r--r--third_party/rust/derive_more/CHANGELOG.md313
-rw-r--r--third_party/rust/derive_more/Cargo.lock238
-rw-r--r--third_party/rust/derive_more/Cargo.toml282
-rw-r--r--third_party/rust/derive_more/LICENSE21
-rw-r--r--third_party/rust/derive_more/README.md218
-rw-r--r--third_party/rust/derive_more/src/convert.rs47
-rw-r--r--third_party/rust/derive_more/src/fmt.rs189
-rw-r--r--third_party/rust/derive_more/src/lib.rs301
-rw-r--r--third_party/rust/derive_more/src/ops.rs92
-rw-r--r--third_party/rust/derive_more/src/str.rs25
-rw-r--r--third_party/rust/derive_more/src/try_unwrap.rs48
-rw-r--r--third_party/rust/derive_more/src/vendor/mod.rs2
-rw-r--r--third_party/rust/derive_more/src/vendor/thiserror/README.md6
-rw-r--r--third_party/rust/derive_more/src/vendor/thiserror/aserror.rs52
-rw-r--r--third_party/rust/derive_more/src/vendor/thiserror/mod.rs1
-rw-r--r--third_party/rust/derive_more/tests/add.rs24
-rw-r--r--third_party/rust/derive_more/tests/add_assign.rs13
-rw-r--r--third_party/rust/derive_more/tests/as_mut.rs117
-rw-r--r--third_party/rust/derive_more/tests/as_ref.rs117
-rw-r--r--third_party/rust/derive_more/tests/boats_display_derive.rs56
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/both_fmt_and_skip_on_field.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/extra_placeholder.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/legacy_bound_syntax.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/legacy_fmt_syntax.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/missing_placeholder.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/named_field_prefixed_with_dot.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/unclosed_brace.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/union.rs6
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/unknown_attribute.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/unnamed_field_prefixed_with_dot.rs4
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/wrong_formatting_argument.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/wrong_named_parameter.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/debug/wrong_unnamed_parameter.rs4
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/extra_placeholder.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/legacy_bound_syntax.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/legacy_fmt_syntax.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/missing_placeholder.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/mutlifield_enum_variant_without_attribute.rs6
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/mutlifield_struct_without_attribute.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/named_field_prefixed_with_dot.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/non_display_implicit_enum_unit_variant.rs6
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/unclosed_brace.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/unknown_attribute.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/unnamed_field_prefixed_with_dot.rs5
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/wrong_formatting_argument.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/wrong_named_parameter.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/display/wrong_unnamed_parameter.rs5
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/legacy_enum_attribute.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/legacy_struct_attribute.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/multiple_enum_attributes.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/multiple_struct_attributes.rs6
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_no_parens.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_long.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_short.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/from/union.rs6
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/enum.rs6
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/legacy_complex_attribute.rs5
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/legacy_types_attribute.rs5
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/mixed_regular_and_wrapped_types.rs7
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/tuple_no_parens.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/tuple_too_long.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/tuple_too_short.rs8
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/into/union.rs6
-rw-r--r--third_party/rust/derive_more/tests/compile_fail/mod.rs6
-rw-r--r--third_party/rust/derive_more/tests/constructor.rs32
-rw-r--r--third_party/rust/derive_more/tests/debug.rs1155
-rw-r--r--third_party/rust/derive_more/tests/deref.rs75
-rw-r--r--third_party/rust/derive_more/tests/deref_mut.rs131
-rw-r--r--third_party/rust/derive_more/tests/display.rs793
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs267
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs249
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs246
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs250
-rw-r--r--third_party/rust/derive_more/tests/error/mod.rs56
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs470
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs479
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs478
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs483
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/mod.rs93
-rw-r--r--third_party/rust/derive_more/tests/error_tests.rs5
-rw-r--r--third_party/rust/derive_more/tests/from.rs1791
-rw-r--r--third_party/rust/derive_more/tests/from_str.rs47
-rw-r--r--third_party/rust/derive_more/tests/generics.rs264
-rw-r--r--third_party/rust/derive_more/tests/index.rs20
-rw-r--r--third_party/rust/derive_more/tests/index_mut.rs36
-rw-r--r--third_party/rust/derive_more/tests/into.rs1045
-rw-r--r--third_party/rust/derive_more/tests/into_iterator.rs47
-rw-r--r--third_party/rust/derive_more/tests/is_variant.rs163
-rw-r--r--third_party/rust/derive_more/tests/lib.rs278
-rw-r--r--third_party/rust/derive_more/tests/mul.rs21
-rw-r--r--third_party/rust/derive_more/tests/mul_assign.rs33
-rw-r--r--third_party/rust/derive_more/tests/no_std.rs76
-rw-r--r--third_party/rust/derive_more/tests/not.rs29
-rw-r--r--third_party/rust/derive_more/tests/sum.rs32
-rw-r--r--third_party/rust/derive_more/tests/try_into.rs234
-rw-r--r--third_party/rust/derive_more/tests/try_unwrap.rs135
-rw-r--r--third_party/rust/derive_more/tests/unwrap.rs119
98 files changed, 12091 insertions, 0 deletions
diff --git a/third_party/rust/derive_more/.cargo-checksum.json b/third_party/rust/derive_more/.cargo-checksum.json
new file mode 100644
index 0000000000..3dd6cd1cdd
--- /dev/null
+++ b/third_party/rust/derive_more/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"bb43c76f6dbe248aae80f903907cd9fd7626682645f219f8348ca0fb56b1491c","Cargo.lock":"b8969b6d5e2d4db2d6d47f20e02bf94037ed2dad637f3e35de7738efd6915256","Cargo.toml":"031d3009bbc418c01acc40b3fdc4820bb2b3f0f81eddf98df5bcfe2a1d18c325","LICENSE":"8a35369f3ca263b3c62fbb5032947e53b6bfebc6c8a4d1bb982de1c069f6fba5","README.md":"59d833d42d1efece4688d7067502062fcbdeae93e2f6bef9c7e8de3d834c6713","src/convert.rs":"515fffddd0ef9eba8dff6596f28b4e353c46429dda8a7ab26fdeb4707a549dcb","src/fmt.rs":"553ddb07fc54595825037738c58fc43014df412f350d2b8d7c2482d0fb0a829f","src/lib.rs":"e80bd07ec63194fa254dbf87518d2d25ef203f20d61f2f288ab2c08a4e78a7ff","src/ops.rs":"592d0e25c69da0904dad17eb5983ba6f7a7558c379dbe52b5fbbce6ebf400629","src/str.rs":"5313afba961713a1b5b3c62d5f86ceffe6f888ea0fec588927b51a1affc58abd","src/try_unwrap.rs":"56ff6f9221c2321e459d111348db1d3fb6e6e279ad2173a0418373f019bff714","src/vendor/mod.rs":"ae320e006fe00b7872995392bf95c2929286d1327f1fb9c6d66a0271a9e7d32d","src/vendor/thiserror/README.md":"a8e01baaa2e23f9a890aac2d8f36fe7173abee8a46e17200ea00efc5c859a2f0","src/vendor/thiserror/aserror.rs":"65727d44030194d1585d4151d09df93d9dd26e39c02f80aca63962b061209d63","src/vendor/thiserror/mod.rs":"a74f6d33e03a3ad9bc7d3d57c73eaefaba53c4f7bed8c2dc16f0deb3ea13398d","tests/add.rs":"309fba9cbde39ff660ab778c0f8b9dfa20965648baa1efb3de61abfd46d84038","tests/add_assign.rs":"26c34a9bc012d85c4b39dc7274cfebce71fc1610f219a65f81ac73e70e6a698a","tests/as_mut.rs":"aac8faba264f6b294f3eaf9f63c89032b57ebc6a01f445ca7eae630bddf77e05","tests/as_ref.rs":"be3c46edef518ec7c7afdfa812f430e23bf3448cf7cdee30286a986cff3ebd88","tests/boats_display_derive.rs":"d0133b4330602da2c20827f5a05dc10c300f88b168e029f587a02da9a6d42792","tests/compile_fail/debug/both_fmt_and_skip_on_field.rs":"cb9ef525aa0725c78c3711df665a22a1f25562fa4032911674b4d22b5c561ba4","tests/compile_fail/debug/extra_placeholder.rs":"a70536bcc898e71f0cfbcfe18e13f0a229e25f4f5ddb02b09f0135276cd19ce0","tests/compile_fail/debug/legacy_bound_syntax.rs":"1b0d0a2efe2e3b2388f447553f95c38d22892e85001b3f2af5c5edb604905161","tests/compile_fail/debug/legacy_fmt_syntax.rs":"b7b8b72507d272f3853bfde5b566e30cb121963b620a731018b39418f2a66db2","tests/compile_fail/debug/missing_placeholder.rs":"78091dd3c6130ff64cfaeb14491f302b1ab28551e7320b31e722811718f984a4","tests/compile_fail/debug/named_field_prefixed_with_dot.rs":"d21ed1360c22f8ec755b7f11d0d13d80ecb5051f3aa3e8f0fa26012dfac00a69","tests/compile_fail/debug/unclosed_brace.rs":"fc99b1e681e6d44e503d36af84aa345871bb1ec5d643d8df49b7432060cd7d4a","tests/compile_fail/debug/union.rs":"d6836944095a82a402a13b18c879e7fd90e2e8d891114dfd092eaa63141f378d","tests/compile_fail/debug/unknown_attribute.rs":"4ff13fe7a86fd3a5778f4aa577261eb572872b52fb2fe64b5434b6c6a0be956d","tests/compile_fail/debug/unnamed_field_prefixed_with_dot.rs":"7c591adccf841cf2d0b3679272c991ded5c0997da846348a7b6ea6a8071205af","tests/compile_fail/debug/wrong_formatting_argument.rs":"90a71793f5ff1a5ce05e95e6fca43f20a09f8a9b241c791e6498db9457091081","tests/compile_fail/debug/wrong_named_parameter.rs":"011d63a4edd60514b15247efd3fbda3c6036b7060d0ad280ff94e6a5b2f0fa28","tests/compile_fail/debug/wrong_unnamed_parameter.rs":"f3c3b635a91ed9c82a004091142ddda22f96405f015f46ea47e1af913a7201a0","tests/compile_fail/display/extra_placeholder.rs":"76a46086e1b300dcf64f13b9dbd323f4566e27cbd6894bb42d0e62c56818e7f2","tests/compile_fail/display/legacy_bound_syntax.rs":"f0d874a748f9e4d80f8e6e9683a1067669c4830da48c0d4b646268ee7d747f45","tests/compile_fail/display/legacy_fmt_syntax.rs":"3d0766594d6b68f14de0ff9f3ae1f99ec6870a6c1054dec5202ee8e648343105","tests/compile_fail/display/missing_placeholder.rs":"cce061baeb84e830aa1cd992ce1228497a76ab83fa6fb1b47e0703efb9ffaa29","tests/compile_fail/display/mutlifield_enum_variant_without_attribute.rs":"6a77cf098d7a46bc09f40edad73a90371d20bf3b492f94a3671e09c4ac1497f1","tests/compile_fail/display/mutlifield_struct_without_attribute.rs":"5509f6298ed94dd90d2839a5b6b43d31c279adcbd3ef90a5f104a08e7c52346d","tests/compile_fail/display/named_field_prefixed_with_dot.rs":"5cfe20e60c14e3bc2b57d227cd1674b0c897e43fdb352a2f09603e84a4f8e1ac","tests/compile_fail/display/non_display_implicit_enum_unit_variant.rs":"2541e3fb70fe489a0387bec8f5f68486b8a2a63ea08ddad7f7bd2333621a3632","tests/compile_fail/display/unclosed_brace.rs":"b99edf224e5814339e5e3e4a86b5f5e7f8910593d769fc30180d1c28bec6939e","tests/compile_fail/display/unknown_attribute.rs":"2ff4b1d08c746df29857130eeeccf6ae4c8d3742cb31112c415c13a058ba7344","tests/compile_fail/display/unnamed_field_prefixed_with_dot.rs":"2aa52a4192280e37901668a862a080e99d363b6b11bd66b9065153c10ff42fa4","tests/compile_fail/display/wrong_formatting_argument.rs":"bce4e69f127c1cadba8a86c6a6813e7a87de7b10a0ebc1cc9e27f70ddac87848","tests/compile_fail/display/wrong_named_parameter.rs":"cdc6cd0013cca3ecfdfdc61f0f1c942ce8c4a8022d8aaa9ac595dcf10fdbbfa0","tests/compile_fail/display/wrong_unnamed_parameter.rs":"77204f1249616cd821b20f6961799ae1f76c2fd4f87c191a4c22968f754dafb4","tests/compile_fail/from/legacy_enum_attribute.rs":"ceabb771ce99c4dedd5748b7c41ad5d1361a384c59066ed46441d73305573e1d","tests/compile_fail/from/legacy_struct_attribute.rs":"cb587c838b9e3832136520cfd229b65b59bc6486927c1e154010f5e1646fafdc","tests/compile_fail/from/multiple_enum_attributes.rs":"b7271d4de0bef34b7146617c72485a5cedf1efcfb2123ab8c50315ab2cf04ed5","tests/compile_fail/from/multiple_struct_attributes.rs":"e1be2f5d0dcacdcefaa657321144174ec2fda4d63c3deff3481c976fd34c9857","tests/compile_fail/from/struct_tuple_no_parens.rs":"ad2452ac4cb1109c84983ab51cb3efb22ae3466a682cfefc2dfefe55b67dc39c","tests/compile_fail/from/struct_tuple_too_long.rs":"3993f3f1fdf585ca132a93652ade18e726b2b52471c4684ad5995be71e504b15","tests/compile_fail/from/struct_tuple_too_short.rs":"4ed8f16395c193832b9881041f408035b1d038ee66d068b6a743a8e63d851807","tests/compile_fail/from/union.rs":"4199be83518583b1d3173d619ceb8159e976b1db0fc3e76331b07163b2a0aff1","tests/compile_fail/into/enum.rs":"b64765573e84f703161b86512ec2cf2a9df50081cf50992c78e5a1e350984549","tests/compile_fail/into/legacy_complex_attribute.rs":"c371be38a08e81f8c2dcb4e02eea74da6deb73aeebc601964f6820c836c6a536","tests/compile_fail/into/legacy_types_attribute.rs":"25fcf30a902768dab50c70ce84765a0937b37d298b4bec76a4239c19270f67ae","tests/compile_fail/into/mixed_regular_and_wrapped_types.rs":"f6a8a91103682b193c1087bb0462e1b7a4f32b8512edf692b5fad36670f37a5c","tests/compile_fail/into/tuple_no_parens.rs":"7bcd4c0bc210caf4b5fc894b8f9cadc74a2a93ce34e15694334c6585305a661b","tests/compile_fail/into/tuple_too_long.rs":"28feff5a9e88fa0db53ba947c2676e9f699c107b15925f9dc3c9bd3836cd5384","tests/compile_fail/into/tuple_too_short.rs":"6ca84f306412d402391a6afba378edf62f77425e1df98474f25aecea803e731c","tests/compile_fail/into/union.rs":"a961fb3d741612c561b398b2316c8f092fb418ee1942259ea97d0779727282f7","tests/compile_fail/mod.rs":"d849ecbfa0aa66907c228ef3297ff77cadf459a20cfa5eb988fd4cfd12dc1d6f","tests/constructor.rs":"a30fd8558628941c23cf0e4e9f69262510284b611f5a251c516c3c1474b0dea5","tests/debug.rs":"7988f206fde0c1874147fdec1864bb9ef93317ce0e6e1c910df43ded037d9f39","tests/deref.rs":"83139db87b84bd8fefb25e4a4f83bb41f4d2f0eb27ab7e25f16e5f2d1c119b57","tests/deref_mut.rs":"cba7cc972c77124b21099a0adeafa7476def8c9e3565b4763c9d60d43c3bdeb8","tests/display.rs":"a93bddc3580a23d115f7c87e37a1491fdbcff7fe939b86fac77166d071fa0b37","tests/error/derives_for_enums_with_source.rs":"0ee1feed18da2d740c89d2bda43b6c224b205955e2177c103f31ed28e58e96a3","tests/error/derives_for_generic_enums_with_source.rs":"7df9897e53fffde0157a9117251dc7c759f0ee93704e46a95e1ea2aea0da6374","tests/error/derives_for_generic_structs_with_source.rs":"4a60577551b8dd3c73b18be04025c236acffa870b4e73c1dc5cedc0bd7eb9076","tests/error/derives_for_structs_with_source.rs":"129432439cf5fc744ddf642e18e7be81c9e165fa5e85c816af3f9c634ec1cd23","tests/error/mod.rs":"4ab226fb7c86834926dc482d57bf3b348f66a3ea4d49752445c22eb2bd0af709","tests/error/nightly/derives_for_enums_with_backtrace.rs":"f410ab07358a9ff94b7ba23c1e901983e25a2955303e24760ce604b5d12ec78e","tests/error/nightly/derives_for_generic_enums_with_backtrace.rs":"a98feb1934b1b8cd87d70c7e74ad1680be9bca02a7c2fa3c960ee72d6a60becc","tests/error/nightly/derives_for_generic_structs_with_backtrace.rs":"5eb96ccbc1b40b5389dc08902fec4470e2fd2c5747771c3039bfcc15c913b498","tests/error/nightly/derives_for_structs_with_backtrace.rs":"97e322d50f0fa6bfb0a48b61a32a0e6cc6fdeb9242ee51ab27a5f64bd725ce7c","tests/error/nightly/mod.rs":"74b7d3e45a6974bd96ea964465e9ca87370226c9557fe565e6351aee3f6b8eb4","tests/error_tests.rs":"26ee4192a8eb3f2a47c522bec8a6ed9253ac1cbfa0d8103e5aa046bbfd89e642","tests/from.rs":"b579634209130f2989ac5d2477ad1a7eebf182f52fe8ced26a8e114abf4ed997","tests/from_str.rs":"1d2c32c7a29123e4f78d90122bd9992676ff77236c426fd83a418416fa1e87f2","tests/generics.rs":"75ef7f021e17c2c7b87619ee19b8afc28a3e96689a2882c2c815ae2c05674827","tests/index.rs":"9202ea8460bb0c205a7fd26e8f5ea2b27cd7e36d26148ffe82f44f87c287443e","tests/index_mut.rs":"200333833e8c1e716064da07a077e145895c2f4c774d77c7fe8cba47423efa76","tests/into.rs":"009901f64419c3e59862277d17a53bd24bd9ef1351113cc862439b94eda5e3a4","tests/into_iterator.rs":"ce51284c5cceee037e926ab22084d9eea3a34d2ffcc6e01b5373555850d8f5bd","tests/is_variant.rs":"39cb1e730315883e28a0ba3fac9b6f13607c00e2c3b638579411f80b2686842c","tests/lib.rs":"bc73bf023203f1bcc726b11b1c6e87c48d61271ee7ae0f94bc4649276e26249d","tests/mul.rs":"dbfc2a88ee76ca40562d1b7c9772015fc33e99723314470adeaf7e3862037ce7","tests/mul_assign.rs":"38c484f73fe495c52f12306983ea75181fe233ab9c12e9d6ae78f92d80a6209f","tests/no_std.rs":"918d14c9d73550a3af464be073175bcfe505b2be9a0064d810e0e15ebe0c9d40","tests/not.rs":"6c922736e9fbcaf5eb441a70df5fdc4f54db82838b5795d3cc180c176be61de3","tests/sum.rs":"5927876ed3c20765441be15c3289e723af4bcafabd055a24b0f10fe26e6e7e83","tests/try_into.rs":"ebeeb1d36ab98879bae2eed62da8bc9788416fba771e4892ba7b88d423710aae","tests/try_unwrap.rs":"bfc64c17908cc51f73b419be88c18567470164a84eb4f11b50c58405d6b2989a","tests/unwrap.rs":"91b758a80da492f4d5b7d4844895ca084df3f0a1b22ef79552a99f733bc99a26"},"package":"d79dfbcc1f34f3b3a0ce7574276f6f198acb811d70dd19d9dcbfe6263a83d983"} \ No newline at end of file
diff --git a/third_party/rust/derive_more/CHANGELOG.md b/third_party/rust/derive_more/CHANGELOG.md
new file mode 100644
index 0000000000..2cf78f3077
--- /dev/null
+++ b/third_party/rust/derive_more/CHANGELOG.md
@@ -0,0 +1,313 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+
+## 1.0.0 - Unreleased
+
+### Breaking changes
+
+- The minimum supported Rust version (MSRV) is now Rust 1.65.
+- Add the `std` feature which should be disabled in `no_std` environments.
+- All Cargo features, except `std`, are now disabled by default. The `full`
+ feature can be used to get the old behavior of supporting all possible
+ derives.
+- The `TryFrom`, `Add`, `Sub`, `BitAnd`, `BitOr`, `BitXor`, `Not` and `Neg`
+ derives now return a dedicated error type instead of a `&'static str` on
+ error.
+- The `FromStr` derive now uses a dedicated `FromStrError` error type instead
+ of generating unique one each time.
+- The `Display` derive (and other `fmt`-like ones) now uses
+ `#[display("...", (<expr>),*)]` syntax instead of
+ `#[display(fmt = "...", ("<expr>"),*)]`, and `#[display(bound(<bound>))]`
+ instead of `#[display(bound = "<bound>")]`. So without the double quotes
+ around the expressions and bounds.
+- The `DebugCustom` derive is renamed to just `Debug` (gated now under a separate
+ `debug` feature), and its semantics were changed to be a superset of `std` variant
+ of `Debug`.
+- The `From` derive doesn't derive `From<()>` for enum variants without any
+ fields anymore. This feature was removed because it was considered useless in
+ practice.
+- The `From` derive now uses `#[from(<types>)]` instead of `#[from(types(<types>))]`
+ and ignores field type itself.
+- The `Into` derive now uses `#[into(<types>)]` instead of `#[into(types(<types>))]`
+ and ignores field type itself.
+- Importing a derive macro now also import its corresponding trait.
+
+### Added
+
+- Add support captured identifiers in `Display` derives. So now you can use:
+ `#[display(fmt = "Prefix: {field}")]` instead of needing to use
+ `#[display(fmt = "Prefix: {}", field)]`
+- Add `FromStr` derive support for enums that contain variants without fields.
+ If you pass the name of the variant to `from_str` it will create the matching
+ variant.
+- Add `#[unwrap(owned, ref, ref_mut)]` attribute for the `Unwrap` derive.
+ By using them, it is possible to derive implementations for the reference types as well.
+ ([#206](https://github.com/JelteF/derive_more/pull/206))
+- Add `TryUnwrap` derive similar to the `Unwrap` derive. This one returns a `Result` and does not panic.
+ ([#206](https://github.com/JelteF/derive_more/pull/206))
+
+### Changed
+
+- The `Constructor` and `IsVariant` derives now generate `const fn` functions.
+- The `Unwrap` and `IsVariant` derives now generate doc comments.
+- `#[automatically_derived]` is now emitted from all macro expansions. This
+ should prevent code style linters from attempting to modify the generated
+ code.
+- Upgrade to `syn` 2.0.
+- The `Error` derive now works in nightly `no_std` environments when enabling
+ `#![feature(error_in_core)]`.
+
+### Fixed
+
+- Use a deterministic `HashSet` in all derives, this is needed for rust analyzer
+ to work correctly.
+- Use `Provider` API for backtraces in `Error` derive.
+- Fix `Error` derive not working with `const` generics.
+- Support trait objects for source in Error, e.g.
+ `Box<dyn Error + Send + 'static>`
+
+## 0.99.10 - 2020-09-11
+
+### Added
+
+- `From` supports additional types for conversion: `#[from(types(u8, u16))]`.
+
+
+## 0.99.7 - 2020-05-16
+
+### Changed
+
+- When specifying specific features of the crate to only enable specific
+ derives, the `extra-traits` feature of `syn` is not always enabled
+ when those the specified features do not require it. This should speed up
+ compile time of `syn` when this feature is not needed.
+
+### Fixed
+
+- Fix generic derives for `MulAssign`
+
+## 0.99.6 - 2020-05-13
+
+### Changed
+
+- Make sure output of derives is deterministic, for better support in
+ rust-analyzer
+
+
+## 0.99.5 - 2020-03-28
+
+### Added
+
+- Support for deriving `Error`!!! (many thanks to @ffuugoo and @tyranron)
+
+### Fixed
+
+- Fix generic bounds for `Deref` and `DerefMut` with `forward`, i.e. put `Deref`
+ bound on whole type, so on `where Box<T>: Deref` instead of on `T: Deref`.
+ ([#107](https://github.com/JelteF/derive_more/issues/114))
+
+- The `tests` directory is now correctly included in the crate (requested by
+ Debian package maintainers)
+
+## 0.99.4 - 2020-03-28 [YANKED]
+
+Note: This version is yanked, because quickly after release it was found out
+tests did not run in CI.
+
+## 0.99.3 - 2020-02-19
+
+### Fixed
+
+- Fix generic bounds for `Deref` and `DerefMut` with no `forward`, i.e. no bounds
+ are necessary. ([#107](https://github.com/JelteF/derive_more/issues/114))
+
+
+## 0.99.2 - 2019-11-17
+
+### Fixed
+
+- Hotfix for a regression in allowed `Display` derives using `#` flag, such as
+ `{:#b}` ([#107](https://github.com/JelteF/derive_more/issues/107))
+
+## 0.99.1 - 2019-11-12
+
+### Fixed
+
+- Hotfix for a regression in allowed `From` derives
+ ([#105](https://github.com/JelteF/derive_more/issues/105))
+
+## 0.99.0 - 2019-11-11
+
+This release is a huge milestone for this library.
+Lot's of new derives are implemented and a ton of attributes are added for
+configuration purposes.
+These attributes will allow future releases to add features/options without
+breaking backwards compatibility.
+This is why the next release with breaking changes is planned to be 1.0.0.
+
+### Breaking changes
+- The minimum supported rust version (MSRV) is now Rust 1.36.
+- When using in a Rust 2015 crate, you should add `extern crate core` to your
+ code.
+- `no_std` feature is removed, the library now supports `no_std` without having
+ to configure any features.
+
+
+### Added
+
+- `Deref` derives now dereference to the type in the newtype. So if you have
+ `MyBox(Box<i32>)`, dereferencing it will result in a `Box<i32>` not an `i32`.
+ To get the old behaviour of forwarding the dereference you can add the
+ `#[deref(forward)]` attribute on the struct or field.
+- Derives for `AsRef`, `AsMut`, `Sum`, `Product`, `IntoIterator`.
+- Choosing the field of a struct for which to derive the newtype derive.
+- Ignoring variants of enums when deriving `From`, by using `#[from(ignore)]`.
+- Add `#[from(forward)]` attribute for `From` derives. This forwards the `from`
+ calls to the fields themselves. So if your field is an `i64` you can call from
+ on an `i32` and it will work.
+- Add `#[mul(forward)]` and `#[mul_assign(forward)]`, which implement `Mul` and
+ `MulAssign` with the semantics as if they were `Add`/`AddAssign`.
+- You can use features to cut down compile time of the crate by only compiling
+ the code needed for the derives that you use. (see Cargo.toml for the
+ features, by default they are all on)
+- Add `#[into(owned, ref, ref_mut)]` and `#[try_into(owned, ref, ref_mut)]`
+ attributes. These cause the `Into` and `TryInto` derives to also implement
+ derives that return references to the inner fields.
+- Allow `#[display(fmt="some shared display text for all enum variants {}")]`
+ attribute on enum.
+- Better bounds inference of `Display` trait.
+
+### Changed
+
+- Remove dependency on `regex` to cut down compile time.
+- Use `syn` 1.0
+
+## 0.15.0 - 2019-06-08
+
+### Fixed
+
+- Automatic detection of traits needed for `Display` format strings
+
+## 0.14.0 - 2019-02-02
+
+### Added
+
+- Added `no_std` support
+
+### Changed
+
+- Suppress `unused_variables` warnings in derives
+
+## 0.13.0 - 2018-10-19
+
+### Added
+
+- Extended Display-like derives to support custom formats
+
+### Changed
+
+- Updated to `syn` v0.15
+
+## 0.12.0 - 2018-09-19
+
+### Changed
+
+- Updated to `syn` v0.14, `quote` v0.6 and `proc-macro2` v0.4
+
+## 0.11.0 - 2018-05-12
+
+### Changed
+
+- Updated to latest version of `syn` and `quote`
+
+### Fixed
+
+- Changed some URLs in the docs so they were correct on crates.io and docs.rs
+- The `Result` type is now referenced in the derives using its absolute path
+ (`::std::result::Result`) to make sure that the derives don't accidentally use
+ another `Result` type that is in scope.
+
+## 0.10.0 - 2018-03-29
+
+### Added
+
+- Allow deriving of `TryInto`
+- Allow deriving of `Deref`
+- Allow deriving of `DerefMut`
+
+## 0.9.0 - 2018-03-18
+
+### Added
+
+- Allow deriving of `Display`, `Binary`, `Octal`, `LowerHex`, `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
+- Allow deriving of `Index`
+- Allow deriving of `IndexMut`
+
+### Fixed
+
+- Allow cross crate inlining of derived methods
+
+## 0.8.0 - 2018-03-10
+
+### Added
+
+- Allow deriving of `FromStr`
+
+### Changed
+
+- Updated to latest version of `syn` and `quote`
+
+## 0.7.1 - 2018-01-25
+
+### Fixed
+
+- Add `#[allow(missing_docs)]` to the Constructor definition
+
+## 0.7.0 - 2017-07-25
+
+### Changed
+
+- Changed code to work with newer version of the `syn` library.
+
+## 0.6.2 - 2017-04-23
+
+### Changed
+
+- Deriving `From`, `Into` and `Constructor` now works for empty structs.
+
+## 0.6.1 - 2017-03-08
+
+### Changed
+
+- The `new()` method that is created when deriving `Constructor` is now public.
+ This makes it a lot more useful.
+
+## 0.6.0 - 2017-02-20
+
+### Added
+
+- Derives for `Into`, `Constructor` and `MulAssign`-like
+
+### Changed
+
+- `From` is now derived for enum variants with multiple fields.
+
+### Fixed
+
+- Derivations now support generics.
+
+## 0.5.0 - 2017-02-02
+
+### Added
+
+- Lots of docs.
+- Derives for `Neg`-like and `AddAssign`-like.
+
+### Changed
+
+- `From` can now be derived for structs with multiple fields.
diff --git a/third_party/rust/derive_more/Cargo.lock b/third_party/rust/derive_more/Cargo.lock
new file mode 100644
index 0000000000..ad65ea38e3
--- /dev/null
+++ b/third_party/rust/derive_more/Cargo.lock
@@ -0,0 +1,238 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "convert_case"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "derive_more"
+version = "1.0.0-beta.2"
+dependencies = [
+ "derive_more-impl",
+ "rustc_version",
+ "rustversion",
+ "static_assertions",
+ "trybuild",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "1.0.0-beta.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "395aee42a456ecfd4c7034be5011e1a98edcbab2611867c8988a0f40d0bb242a"
+dependencies = [
+ "convert_case",
+ "proc-macro2",
+ "quote",
+ "rustc_version",
+ "syn 2.0.23",
+ "unicode-xid",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "itoa"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+
+[[package]]
+name = "once_cell"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.63"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
+
+[[package]]
+name = "ryu"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+
+[[package]]
+name = "semver"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
+
+[[package]]
+name = "serde"
+version = "1.0.147"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.147"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.103",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "syn"
+version = "1.0.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "trybuild"
+version = "1.0.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea496675d71016e9bc76aa42d87f16aefd95447cc5818e671e12b2d7e269075d"
+dependencies = [
+ "glob",
+ "once_cell",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "termcolor",
+ "toml",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/third_party/rust/derive_more/Cargo.toml b/third_party/rust/derive_more/Cargo.toml
new file mode 100644
index 0000000000..8c2d573a4b
--- /dev/null
+++ b/third_party/rust/derive_more/Cargo.toml
@@ -0,0 +1,282 @@
+# 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 = "2021"
+rust-version = "1.65.0"
+name = "derive_more"
+version = "1.0.0-beta.2"
+authors = ["Jelte Fennema <github-tech@jeltef.nl>"]
+include = [
+ "src/**/*.rs",
+ "Cargo.toml",
+ "LICENSE",
+ "README.md",
+ "CHANGELOG.md",
+ "tests/**/*.rs",
+]
+description = "Adds #[derive(x)] macros for more traits"
+documentation = "https://docs.rs/derive_more"
+readme = "README.md"
+keywords = [
+ "derive",
+ "Add",
+ "From",
+ "Display",
+ "IntoIterator",
+]
+categories = [
+ "development-tools",
+ "development-tools::procedural-macro-helpers",
+ "no-std",
+]
+license = "MIT"
+repository = "https://github.com/JelteF/derive_more"
+
+[package.metadata.docs.rs]
+features = ["full"]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[[example]]
+name = "deny_missing_docs"
+path = "examples/deny_missing_docs.rs"
+required-features = ["full"]
+
+[[test]]
+name = "add_assign"
+path = "tests/add_assign.rs"
+required-features = ["add_assign"]
+
+[[test]]
+name = "add"
+path = "tests/add.rs"
+required-features = ["add"]
+
+[[test]]
+name = "as_mut"
+path = "tests/as_mut.rs"
+required-features = ["as_mut"]
+
+[[test]]
+name = "as_ref"
+path = "tests/as_ref.rs"
+required-features = ["as_ref"]
+
+[[test]]
+name = "boats_display_derive"
+path = "tests/boats_display_derive.rs"
+required-features = ["display"]
+
+[[test]]
+name = "constructor"
+path = "tests/constructor.rs"
+required-features = ["constructor"]
+
+[[test]]
+name = "debug"
+path = "tests/debug.rs"
+required-features = ["debug"]
+
+[[test]]
+name = "deref"
+path = "tests/deref.rs"
+required-features = ["deref"]
+
+[[test]]
+name = "deref_mut"
+path = "tests/deref_mut.rs"
+required-features = ["deref_mut"]
+
+[[test]]
+name = "display"
+path = "tests/display.rs"
+required-features = ["display"]
+
+[[test]]
+name = "error"
+path = "tests/error_tests.rs"
+required-features = ["error"]
+
+[[test]]
+name = "from"
+path = "tests/from.rs"
+required-features = ["from"]
+
+[[test]]
+name = "from_str"
+path = "tests/from_str.rs"
+required-features = ["from_str"]
+
+[[test]]
+name = "index_mut"
+path = "tests/index_mut.rs"
+required-features = ["index_mut"]
+
+[[test]]
+name = "index"
+path = "tests/index.rs"
+required-features = ["index"]
+
+[[test]]
+name = "into"
+path = "tests/into.rs"
+required-features = ["into"]
+
+[[test]]
+name = "into_iterator"
+path = "tests/into_iterator.rs"
+required-features = ["into_iterator"]
+
+[[test]]
+name = "mul_assign"
+path = "tests/mul_assign.rs"
+required-features = ["mul_assign"]
+
+[[test]]
+name = "mul"
+path = "tests/mul.rs"
+required-features = ["mul"]
+
+[[test]]
+name = "not"
+path = "tests/not.rs"
+required-features = ["not"]
+
+[[test]]
+name = "sum"
+path = "tests/sum.rs"
+required-features = ["sum"]
+
+[[test]]
+name = "try_into"
+path = "tests/try_into.rs"
+required-features = ["try_into"]
+
+[[test]]
+name = "is_variant"
+path = "tests/is_variant.rs"
+required-features = ["is_variant"]
+
+[[test]]
+name = "unwrap"
+path = "tests/unwrap.rs"
+required-features = ["unwrap"]
+
+[[test]]
+name = "try_unwrap"
+path = "tests/try_unwrap.rs"
+required-features = ["try_unwrap"]
+
+[[test]]
+name = "compile_fail"
+path = "tests/compile_fail/mod.rs"
+required-features = [
+ "debug",
+ "display",
+ "from",
+ "into",
+]
+
+[[test]]
+name = "no_std"
+path = "tests/no_std.rs"
+required-features = ["full"]
+
+[[test]]
+name = "generics"
+path = "tests/generics.rs"
+required-features = ["full"]
+
+[[test]]
+name = "lib"
+path = "tests/lib.rs"
+required-features = ["full"]
+
+[dependencies.derive_more-impl]
+version = "=1.0.0-beta.2"
+
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.static_assertions]
+version = "1.1"
+
+[dev-dependencies.trybuild]
+version = "1.0.56"
+
+[build-dependencies.rustc_version]
+version = "0.4"
+optional = true
+
+[features]
+add = ["derive_more-impl/add"]
+add_assign = ["derive_more-impl/add_assign"]
+as_mut = ["derive_more-impl/as_mut"]
+as_ref = ["derive_more-impl/as_ref"]
+constructor = ["derive_more-impl/constructor"]
+debug = ["derive_more-impl/debug"]
+default = ["std"]
+deref = ["derive_more-impl/deref"]
+deref_mut = ["derive_more-impl/deref_mut"]
+display = ["derive_more-impl/display"]
+error = ["derive_more-impl/error"]
+from = ["derive_more-impl/from"]
+from_str = ["derive_more-impl/from_str"]
+full = [
+ "add",
+ "add_assign",
+ "as_mut",
+ "as_ref",
+ "constructor",
+ "debug",
+ "deref",
+ "deref_mut",
+ "display",
+ "error",
+ "from",
+ "from_str",
+ "index",
+ "index_mut",
+ "into",
+ "into_iterator",
+ "is_variant",
+ "mul",
+ "mul_assign",
+ "not",
+ "sum",
+ "try_into",
+ "try_unwrap",
+ "unwrap",
+]
+index = ["derive_more-impl/index"]
+index_mut = ["derive_more-impl/index_mut"]
+into = ["derive_more-impl/into"]
+into_iterator = ["derive_more-impl/into_iterator"]
+is_variant = ["derive_more-impl/is_variant"]
+mul = ["derive_more-impl/mul"]
+mul_assign = ["derive_more-impl/mul_assign"]
+not = ["derive_more-impl/not"]
+std = []
+sum = ["derive_more-impl/sum"]
+testing-helpers = [
+ "derive_more-impl/testing-helpers",
+ "dep:rustc_version",
+]
+try_into = ["derive_more-impl/try_into"]
+try_unwrap = ["derive_more-impl/try_unwrap"]
+unwrap = ["derive_more-impl/unwrap"]
+
+[badges.github]
+repository = "JelteF/derive_more"
+workflow = "CI"
diff --git a/third_party/rust/derive_more/LICENSE b/third_party/rust/derive_more/LICENSE
new file mode 100644
index 0000000000..602cf050e2
--- /dev/null
+++ b/third_party/rust/derive_more/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Jelte Fennema
+
+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/derive_more/README.md b/third_party/rust/derive_more/README.md
new file mode 100644
index 0000000000..c8e80e9b3b
--- /dev/null
+++ b/third_party/rust/derive_more/README.md
@@ -0,0 +1,218 @@
+# `derive_more`
+
+[![Build Status](https://github.com/JelteF/derive_more/workflows/CI/badge.svg)](https://github.com/JelteF/derive_more/actions)
+[![Latest Version](https://img.shields.io/crates/v/derive_more.svg)](https://crates.io/crates/derive_more)
+[![Rust Documentation](https://docs.rs/derive_more/badge.svg)](https://docs.rs/derive_more)
+[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/JelteF/derive_more/master/LICENSE)
+[![Rust 1.65+](https://img.shields.io/badge/rustc-1.65+-lightgray.svg)](https://blog.rust-lang.org/2021/10/21/Rust-1.65.0.html)
+[![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance)
+
+Rust has lots of builtin traits that are implemented for its basic types, such
+as `Add`, `Not`, `From` or `Display`.
+However, when wrapping these types inside your own structs or enums you lose the
+implementations of these traits and are required to recreate them.
+This is especially annoying when your own structures are very simple, such as
+when using the commonly advised newtype pattern (e.g. `MyInt(i32)`).
+
+This library tries to remove these annoyances and the corresponding boilerplate code.
+It does this by allowing you to derive lots of commonly used traits for both structs and enums.
+
+
+
+
+## Example code
+
+By using this library the following code just works:
+
+```rust
+use derive_more::{Add, Display, From, Into};
+
+#[derive(PartialEq, From, Add)]
+struct MyInt(i32);
+
+#[derive(PartialEq, From, Into)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
+
+#[derive(PartialEq, From, Add, Display)]
+enum MyEnum {
+ #[display("int: {_0}")]
+ Int(i32),
+ Uint(u32),
+ #[display("nothing")]
+ Nothing,
+}
+
+assert!(MyInt(11) == MyInt(5) + 6.into());
+assert!((5, 6) == Point2D { x: 5, y: 6 }.into());
+assert!(MyEnum::Int(15) == (MyEnum::Int(8) + 7.into()).unwrap());
+assert!(MyEnum::Int(15).to_string() == "int: 15");
+assert!(MyEnum::Uint(42).to_string() == "42");
+assert!(MyEnum::Nothing.to_string() == "nothing");
+```
+
+
+
+
+## The derivable traits
+
+Below are all the traits that you can derive using this library.
+Some trait derivations are so similar that the further documentation will only show a single one
+of them.
+You can recognize these by the "-like" suffix in their name.
+The trait name before that will be the only one that is used throughout the further
+documentation.
+
+It is important to understand what code gets generated when using one of the
+derives from this crate.
+That is why the links below explain what code gets generated for a trait for
+each group from before.
+
+You can use the [`cargo-expand`] utility to see the exact code that is generated
+for your specific type.
+This will show you your code with all macros and derives expanded.
+
+**NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
+automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
+
+
+### Conversion traits
+
+These are traits that are used to convert automatically between types.
+
+1. [`From`]
+2. [`Into`]
+3. [`FromStr`]
+4. [`TryInto`]
+5. [`IntoIterator`]
+6. [`AsRef`]
+7. [`AsMut`]
+
+
+### Formatting traits
+
+These traits are used for converting a struct to a string in different ways.
+
+1. [`Debug`]
+2. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`,
+ `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
+
+
+### Error-handling traits
+
+These traits are used to define error-types.
+
+1. [`Error`]
+
+
+### Operators
+
+These are traits that can be used for operator overloading.
+
+1. [`Index`]
+2. [`Deref`]
+3. [`Not`-like], contains `Not` and `Neg`
+4. [`Add`-like], contains `Add`, `Sub`, `BitAnd`, `BitOr`, `BitXor`
+5. [`Mul`-like], contains `Mul`, `Div`, `Rem`, `Shr` and `Shl`
+6. [`Sum`-like], contains `Sum` and `Product`
+7. [`IndexMut`]
+8. [`DerefMut`]
+9. [`AddAssign`-like], contains `AddAssign`, `SubAssign`, `BitAndAssign`,
+ `BitOrAssign` and `BitXorAssign`
+10. [`MulAssign`-like], contains `MulAssign`, `DivAssign`, `RemAssign`,
+ `ShrAssign` and `ShlAssign`
+
+
+### Static methods
+
+These don't derive traits, but derive static methods instead.
+
+1. [`Constructor`], this derives a `new` method that can be used as a constructor.
+ This is very basic if you need more customization for your constructor, check
+ out the [`derive-new`] crate.
+2. [`IsVariant`], for each variant `foo` of an enum type, derives a `is_foo` method.
+3. [`Unwrap`], for each variant `foo` of an enum type, derives an `unwrap_foo` method.
+4. [`TryUnwrap`], for each variant `foo` of an enum type, derives an `try_unwrap_foo` method.
+
+
+
+
+## Installation
+
+This library requires Rust 1.65 or higher. To avoid redundant compilation times, by
+default no derives are supported. You have to enable each type of derive as a feature
+in `Cargo.toml`:
+
+```toml
+[dependencies]
+derive_more = "0.99.0"
+# You can specify the types of derives that you need for less time spent
+# compiling. For the full list of features see this crate its `Cargo.toml`.
+features = ["from", "add", "iterator"]
+
+# If you don't care much about compilation times and simply want to have
+# support for all the possible derives, you can use the "full" feature.
+features = ["full"]
+
+# If you run in a `no_std` environment you should disable the default features,
+# because the only default feature is the "std" feature.
+# NOTE: You can combine this with "full" feature to get support for all the
+# possible derives in a `no_std` environment.
+default-features = false
+```
+
+And this to the top of your Rust file:
+```rust
+// use the derives that you want in the file
+use derive_more::{Add, Display, From};
+```
+If you're still using Rust 2015, add this instead:
+```rust,edition2015
+extern crate core;
+#[macro_use]
+extern crate derive_more;
+# fn main() {} // omit wrapping statements above into `main()` in tests
+```
+
+## Re-exports
+
+This crate also re-exports all of the standard library traits that it adds
+derives for. So both the `Display` derive and the `Display` trait will be in
+scope when you add the following code:
+```rust
+use derive_more::Display;
+```
+
+[`cargo-expand`]: https://github.com/dtolnay/cargo-expand
+[`derive-new`]: https://github.com/nrc/derive-new
+
+[`From`]: https://jeltef.github.io/derive_more/derive_more/from.html
+[`Into`]: https://jeltef.github.io/derive_more/derive_more/into.html
+[`FromStr`]: https://jeltef.github.io/derive_more/derive_more/from_str.html
+[`TryInto`]: https://jeltef.github.io/derive_more/derive_more/try_into.html
+[`IntoIterator`]: https://jeltef.github.io/derive_more/derive_more/into_iterator.html
+[`AsRef`]: https://jeltef.github.io/derive_more/derive_more/as_ref.html
+[`AsMut`]: https://jeltef.github.io/derive_more/derive_more/as_mut.html
+
+[`Debug`]: https://github.com/JelteF/derive_more/blob/master/impl/doc/debug.md
+[`Display`-like]: https://jeltef.github.io/derive_more/derive_more/display.html
+
+[`Error`]: https://jeltef.github.io/derive_more/derive_more/error.html
+
+[`Index`]: https://jeltef.github.io/derive_more/derive_more/index_op.html
+[`Deref`]: https://jeltef.github.io/derive_more/derive_more/deref.html
+[`Not`-like]: https://jeltef.github.io/derive_more/derive_more/not.html
+[`Add`-like]: https://jeltef.github.io/derive_more/derive_more/add.html
+[`Mul`-like]: https://jeltef.github.io/derive_more/derive_more/mul.html
+[`Sum`-like]: https://jeltef.github.io/derive_more/derive_more/sum.html
+[`IndexMut`]: https://jeltef.github.io/derive_more/derive_more/index_mut.html
+[`DerefMut`]: https://jeltef.github.io/derive_more/derive_more/deref_mut.html
+[`AddAssign`-like]: https://jeltef.github.io/derive_more/derive_more/add_assign.html
+[`MulAssign`-like]: https://jeltef.github.io/derive_more/derive_more/mul_assign.html
+
+[`Constructor`]: https://jeltef.github.io/derive_more/derive_more/constructor.html
+[`IsVariant`]: https://jeltef.github.io/derive_more/derive_more/is_variant.html
+[`Unwrap`]: https://jeltef.github.io/derive_more/derive_more/unwrap.html
+[`TryUnwrap`]: https://jeltef.github.io/derive_more/derive_more/try_unwrap.html
diff --git a/third_party/rust/derive_more/src/convert.rs b/third_party/rust/derive_more/src/convert.rs
new file mode 100644
index 0000000000..4885ace22b
--- /dev/null
+++ b/third_party/rust/derive_more/src/convert.rs
@@ -0,0 +1,47 @@
+//! Definitions used in derived implementations of [`core::convert`] traits.
+
+use core::fmt;
+
+/// Error returned by the derived [`TryInto`] implementation.
+///
+/// [`TryInto`]: macro@crate::TryInto
+#[derive(Clone, Copy, Debug)]
+pub struct TryIntoError<T> {
+ /// Original input value which failed to convert via the derived
+ /// [`TryInto`] implementation.
+ ///
+ /// [`TryInto`]: macro@crate::TryInto
+ pub input: T,
+ variant_names: &'static str,
+ output_type: &'static str,
+}
+
+impl<T> TryIntoError<T> {
+ #[doc(hidden)]
+ #[must_use]
+ #[inline]
+ pub const fn new(
+ input: T,
+ variant_names: &'static str,
+ output_type: &'static str,
+ ) -> Self {
+ Self {
+ input,
+ variant_names,
+ output_type,
+ }
+ }
+}
+
+impl<T> fmt::Display for TryIntoError<T> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "Only {} can be converted to {}",
+ self.variant_names, self.output_type,
+ )
+ }
+}
+
+#[cfg(feature = "std")]
+impl<T: fmt::Debug> std::error::Error for TryIntoError<T> {}
diff --git a/third_party/rust/derive_more/src/fmt.rs b/third_party/rust/derive_more/src/fmt.rs
new file mode 100644
index 0000000000..0acd4ca22c
--- /dev/null
+++ b/third_party/rust/derive_more/src/fmt.rs
@@ -0,0 +1,189 @@
+//! [`core::fmt::DebugTuple`] reimplementation with
+//! [`DebugTuple::finish_non_exhaustive()`] method.
+
+use ::core;
+use core::fmt::{Debug, Formatter, Result, Write};
+use core::prelude::v1::*;
+
+/// Same as [`core::fmt::DebugTuple`], but with
+/// [`DebugTuple::finish_non_exhaustive()`] method.
+#[must_use = "must eventually call `finish()` or `finish_non_exhaustive()` on \
+ Debug builders"]
+pub struct DebugTuple<'a, 'b: 'a> {
+ fmt: &'a mut Formatter<'b>,
+ result: Result,
+ fields: usize,
+ empty_name: bool,
+}
+
+/// Creates a new [`DebugTuple`].
+pub fn debug_tuple<'a, 'b>(
+ fmt: &'a mut Formatter<'b>,
+ name: &str,
+) -> DebugTuple<'a, 'b> {
+ let result = fmt.write_str(name);
+ DebugTuple {
+ fmt,
+ result,
+ fields: 0,
+ empty_name: name.is_empty(),
+ }
+}
+
+impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
+ /// Adds a new field to the generated tuple struct output.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use core::fmt;
+ /// use derive_more::__private::debug_tuple;
+ ///
+ /// struct Foo(i32, String);
+ ///
+ /// impl fmt::Debug for Foo {
+ /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// debug_tuple(fmt, "Foo")
+ /// .field(&self.0) // We add the first field.
+ /// .field(&self.1) // We add the second field.
+ /// .finish() // We're good to go!
+ /// }
+ /// }
+ ///
+ /// assert_eq!(
+ /// format!("{:?}", Foo(10, "Hello World".to_string())),
+ /// "Foo(10, \"Hello World\")",
+ /// );
+ /// ```
+ pub fn field(&mut self, value: &dyn Debug) -> &mut Self {
+ self.result = self.result.and_then(|_| {
+ if self.is_pretty() {
+ if self.fields == 0 {
+ self.fmt.write_str("(\n")?;
+ }
+
+ let mut padded_formatter = Padded::new(self.fmt);
+ padded_formatter.write_fmt(format_args!("{value:#?}"))?;
+ padded_formatter.write_str(",\n")
+ } else {
+ let prefix = if self.fields == 0 { "(" } else { ", " };
+ self.fmt.write_str(prefix)?;
+ value.fmt(self.fmt)
+ }
+ });
+
+ self.fields += 1;
+ self
+ }
+
+ /// Finishes output and returns any error encountered.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use core::fmt;
+ /// use derive_more::__private::debug_tuple;
+ ///
+ /// struct Foo(i32, String);
+ ///
+ /// impl fmt::Debug for Foo {
+ /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// debug_tuple(fmt, "Foo")
+ /// .field(&self.0)
+ /// .field(&self.1)
+ /// .finish() // You need to call it to "finish" the
+ /// // tuple formatting.
+ /// }
+ /// }
+ ///
+ /// assert_eq!(
+ /// format!("{:?}", Foo(10, "Hello World".to_string())),
+ /// "Foo(10, \"Hello World\")",
+ /// );
+ /// ```
+ pub fn finish(&mut self) -> Result {
+ if self.fields > 0 {
+ self.result = self.result.and_then(|_| {
+ if self.fields == 1 && self.empty_name && !self.is_pretty() {
+ self.fmt.write_str(",")?;
+ }
+ self.fmt.write_str(")")
+ });
+ }
+ self.result
+ }
+
+ /// Marks the struct as non-exhaustive, indicating to the reader that there are some other
+ /// fields that are not shown in the debug representation, and finishes output, returning any
+ /// error encountered.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use core::fmt;
+ /// use derive_more::__private::debug_tuple;
+ ///
+ /// struct Bar(i32, f32);
+ ///
+ /// impl fmt::Debug for Bar {
+ /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ /// debug_tuple(fmt, "Bar")
+ /// .field(&self.0)
+ /// .finish_non_exhaustive() // Show that some other field(s) exist.
+ /// }
+ /// }
+ ///
+ /// assert_eq!(format!("{:?}", Bar(10, 1.0)), "Bar(10, ..)");
+ /// ```
+ pub fn finish_non_exhaustive(&mut self) -> Result {
+ self.result = self.result.and_then(|_| {
+ if self.fields > 0 {
+ if self.is_pretty() {
+ let mut padded_formatter = Padded::new(self.fmt);
+ padded_formatter.write_str("..\n")?;
+ self.fmt.write_str(")")
+ } else {
+ self.fmt.write_str(", ..)")
+ }
+ } else {
+ self.fmt.write_str("(..)")
+ }
+ });
+ self.result
+ }
+
+ fn is_pretty(&self) -> bool {
+ self.fmt.alternate()
+ }
+}
+
+/// Wrapper for a [`Formatter`] adding 4 spaces on newlines for inner pretty
+/// printed [`Debug`] values.
+struct Padded<'a, 'b> {
+ formatter: &'a mut Formatter<'b>,
+ on_newline: bool,
+}
+
+impl<'a, 'b> Padded<'a, 'b> {
+ fn new(formatter: &'a mut Formatter<'b>) -> Self {
+ Self {
+ formatter,
+ on_newline: true,
+ }
+ }
+}
+
+impl<'a, 'b> Write for Padded<'a, 'b> {
+ fn write_str(&mut self, s: &str) -> Result {
+ for s in s.split_inclusive('\n') {
+ if self.on_newline {
+ self.formatter.write_str(" ")?;
+ }
+
+ self.on_newline = s.ends_with('\n');
+ self.formatter.write_str(s)?;
+ }
+
+ Ok(())
+ }
+}
diff --git a/third_party/rust/derive_more/src/lib.rs b/third_party/rust/derive_more/src/lib.rs
new file mode 100644
index 0000000000..5219c2af76
--- /dev/null
+++ b/third_party/rust/derive_more/src/lib.rs
@@ -0,0 +1,301 @@
+// These links overwrite the ones in `README.md`
+// to become proper intra-doc links in Rust docs.
+//! [`From`]: crate::From
+//! [`Into`]: crate::Into
+//! [`FromStr`]: crate::FromStr
+//! [`TryInto`]: crate::TryInto
+//! [`IntoIterator`]: crate::IntoIterator
+//! [`AsRef`]: crate::AsRef
+//!
+//! [`Debug`]: crate::Debug
+//! [`Display`-like]: crate::Display
+//!
+//! [`Error`]: crate::Error
+//!
+//! [`Index`]: crate::Index
+//! [`Deref`]: crate::Deref
+//! [`Not`-like]: crate::Not
+//! [`Add`-like]: crate::Add
+//! [`Mul`-like]: crate::Mul
+//! [`Sum`-like]: crate::Sum
+//! [`IndexMut`]: crate::IndexMut
+//! [`DerefMut`]: crate::DerefMut
+//! [`AddAssign`-like]: crate::AddAssign
+//! [`MulAssign`-like]: crate::MulAssign
+//!
+//! [`Constructor`]: crate::Constructor
+//! [`IsVariant`]: crate::IsVariant
+//! [`Unwrap`]: crate::Unwrap
+//! [`TryUnwrap`]: crate::TryUnwrap
+
+// The README includes doctests requiring these features. To make sure that
+// tests pass when not all features are provided we exclude it when the
+// required features are not available.
+#![cfg_attr(
+ all(
+ feature = "add",
+ feature = "display",
+ feature = "from",
+ feature = "into"
+ ),
+ doc = include_str!("../README.md")
+)]
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(all(not(feature = "std"), feature = "error"), feature(error_in_core))]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#![cfg_attr(any(not(docsrs), ci), deny(rustdoc::all))]
+#![forbid(non_ascii_idents, unsafe_code)]
+#![warn(clippy::nonstandard_macro_braces)]
+
+// Not public, but exported API. For macro expansion internals only.
+#[doc(hidden)]
+pub mod __private {
+ #[cfg(feature = "debug")]
+ pub use crate::fmt::{debug_tuple, DebugTuple};
+
+ #[cfg(feature = "error")]
+ pub use crate::vendor::thiserror::aserror::AsDynError;
+}
+
+// The modules containing error types and other helpers
+#[cfg(any(feature = "add", feature = "not"))]
+pub mod ops;
+
+#[cfg(feature = "debug")]
+mod fmt;
+
+#[cfg(feature = "error")]
+mod vendor;
+
+#[cfg(feature = "from_str")]
+mod r#str;
+#[cfg(feature = "from_str")]
+#[doc(inline)]
+pub use crate::r#str::FromStrError;
+
+#[cfg(feature = "try_into")]
+mod convert;
+#[cfg(feature = "try_into")]
+#[doc(inline)]
+pub use crate::convert::TryIntoError;
+
+#[cfg(feature = "try_unwrap")]
+mod try_unwrap;
+#[cfg(feature = "try_unwrap")]
+#[doc(inline)]
+pub use self::try_unwrap::TryUnwrapError;
+
+// When re-exporting traits from std we need to do a pretty crazy trick, because we ONLY want
+// to re-export the traits and not derives that are called the same in the std module,
+// because those would conflict with our own. The way we do this is by first importing both
+// the trait and possible derive into a separate module and re-export them. Then we wildcard import
+// all the things from that module into the main module, but we also import our own derive by its
+// exact name. Due to the way wildcard imports work in rust, that results in our own derive taking
+// precedence over any derive from std. For some reason the named re-export of our own derive
+// cannot be in in this (or really any) macro too. It will somehow still consider it a wildcard
+// then and will result in this warning ambiguous_glob_reexports, and not actually exporting of our
+// derive.
+macro_rules! re_export_traits((
+ $feature:literal, $new_module_name:ident, $module:path $(, $traits:ident)* $(,)?) => {
+ #[cfg(feature = $feature)]
+ mod $new_module_name {
+ pub use $module::{$($traits),*};
+ }
+
+ #[cfg(feature = $feature)]
+ #[doc(hidden)]
+ pub use crate::$new_module_name::*;
+
+ }
+);
+
+re_export_traits!(
+ "add",
+ add_traits,
+ core::ops,
+ Add,
+ BitAnd,
+ BitOr,
+ BitXor,
+ Sub,
+);
+re_export_traits!(
+ "add_assign",
+ add_assign_traits,
+ core::ops,
+ AddAssign,
+ BitAndAssign,
+ BitOrAssign,
+ BitXorAssign,
+ SubAssign,
+);
+re_export_traits!("as_mut", as_mut_traits, core::convert, AsMut);
+re_export_traits!("as_ref", as_ref_traits, core::convert, AsRef);
+re_export_traits!("debug", debug_traits, core::fmt, Debug);
+re_export_traits!("deref", deref_traits, core::ops, Deref);
+re_export_traits!("deref_mut", deref_mut_traits, core::ops, DerefMut);
+re_export_traits!(
+ "display",
+ display_traits,
+ core::fmt,
+ Binary,
+ Display,
+ LowerExp,
+ LowerHex,
+ Octal,
+ Pointer,
+ UpperExp,
+ UpperHex,
+);
+
+#[cfg(not(feature = "std"))]
+re_export_traits!("error", error_traits, core::error, Error);
+#[cfg(feature = "std")]
+re_export_traits!("error", error_traits, std::error, Error);
+
+re_export_traits!("from", from_traits, core::convert, From);
+
+re_export_traits!("from_str", from_str_traits, core::str, FromStr);
+
+re_export_traits!("index", index_traits, core::ops, Index);
+
+re_export_traits!("index_mut", index_mut_traits, core::ops, IndexMut);
+
+re_export_traits!("into", into_traits, core::convert, Into);
+
+re_export_traits!(
+ "into_iterator",
+ into_iterator_traits,
+ core::iter,
+ IntoIterator,
+);
+
+re_export_traits!("mul", mul_traits, core::ops, Div, Mul, Rem, Shl, Shr);
+
+#[cfg(feature = "mul_assign")]
+re_export_traits!(
+ "mul_assign",
+ mul_assign_traits,
+ core::ops,
+ DivAssign,
+ MulAssign,
+ RemAssign,
+ ShlAssign,
+ ShrAssign,
+);
+
+re_export_traits!("not", not_traits, core::ops, Neg, Not);
+
+re_export_traits!("sum", sum_traits, core::iter, Product, Sum);
+
+re_export_traits!("try_into", try_into_traits, core::convert, TryInto);
+
+// Now re-export our own derives by their exact name to overwrite any derives that the trait
+// re-exporting might inadvertently pull into scope.
+#[cfg(feature = "add")]
+pub use derive_more_impl::{Add, BitAnd, BitOr, BitXor, Sub};
+
+#[cfg(feature = "add_assign")]
+pub use derive_more_impl::{
+ AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign,
+};
+
+#[cfg(feature = "as_mut")]
+pub use derive_more_impl::AsMut;
+
+#[cfg(feature = "as_ref")]
+pub use derive_more_impl::AsRef;
+
+#[cfg(feature = "constructor")]
+pub use derive_more_impl::Constructor;
+
+#[cfg(feature = "debug")]
+pub use derive_more_impl::Debug;
+
+#[cfg(feature = "deref")]
+pub use derive_more_impl::Deref;
+
+#[cfg(feature = "deref_mut")]
+pub use derive_more_impl::DerefMut;
+
+#[cfg(feature = "display")]
+pub use derive_more_impl::{
+ Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex,
+};
+
+#[cfg(feature = "error")]
+pub use derive_more_impl::Error;
+
+#[cfg(feature = "from")]
+pub use derive_more_impl::From;
+
+#[cfg(feature = "from_str")]
+pub use derive_more_impl::FromStr;
+
+#[cfg(feature = "index")]
+pub use derive_more_impl::Index;
+
+#[cfg(feature = "index_mut")]
+pub use derive_more_impl::IndexMut;
+
+#[cfg(feature = "into")]
+pub use derive_more_impl::Into;
+
+#[cfg(feature = "into_iterator")]
+pub use derive_more_impl::IntoIterator;
+
+#[cfg(feature = "is_variant")]
+pub use derive_more_impl::IsVariant;
+
+#[cfg(feature = "mul")]
+pub use derive_more_impl::{Div, Mul, Rem, Shl, Shr};
+
+#[cfg(feature = "mul_assign")]
+pub use derive_more_impl::{DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign};
+
+#[cfg(feature = "not")]
+pub use derive_more_impl::{Neg, Not};
+
+#[cfg(feature = "sum")]
+pub use derive_more_impl::{Product, Sum};
+
+#[cfg(feature = "try_into")]
+pub use derive_more_impl::TryInto;
+
+#[cfg(feature = "try_unwrap")]
+pub use derive_more_impl::TryUnwrap;
+
+#[cfg(feature = "unwrap")]
+pub use derive_more_impl::Unwrap;
+
+// Check if any feature is enabled
+#[cfg(not(any(
+ feature = "full",
+ feature = "add",
+ feature = "add_assign",
+ feature = "as_mut",
+ feature = "as_ref",
+ feature = "constructor",
+ feature = "debug",
+ feature = "deref",
+ feature = "deref_mut",
+ feature = "display",
+ feature = "error",
+ feature = "from",
+ feature = "from_str",
+ feature = "index",
+ feature = "index_mut",
+ feature = "into",
+ feature = "into_iterator",
+ feature = "is_variant",
+ feature = "mul",
+ feature = "mul_assign",
+ feature = "not",
+ feature = "sum",
+ feature = "try_into",
+ feature = "try_unwrap",
+ feature = "unwrap",
+)))]
+compile_error!(
+ "at least one derive feature must be enabled (or the \"full\" one enabling all the derives)"
+);
diff --git a/third_party/rust/derive_more/src/ops.rs b/third_party/rust/derive_more/src/ops.rs
new file mode 100644
index 0000000000..fbac0e61a0
--- /dev/null
+++ b/third_party/rust/derive_more/src/ops.rs
@@ -0,0 +1,92 @@
+//! Definitions used in derived implementations of [`core::ops`] traits.
+
+use core::fmt;
+
+/// Error returned by the derived implementations when an arithmetic or logic
+/// operation is invoked on a unit-like variant of an enum.
+#[derive(Clone, Copy, Debug)]
+pub struct UnitError {
+ operation_name: &'static str,
+}
+
+impl UnitError {
+ #[doc(hidden)]
+ #[must_use]
+ #[inline]
+ pub const fn new(operation_name: &'static str) -> Self {
+ Self { operation_name }
+ }
+}
+
+impl fmt::Display for UnitError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Cannot {}() unit variants", self.operation_name)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for UnitError {}
+
+#[cfg(feature = "add")]
+/// Error returned by the derived implementations when an arithmetic or logic
+/// operation is invoked on mismatched enum variants.
+#[derive(Clone, Copy, Debug)]
+pub struct WrongVariantError {
+ operation_name: &'static str,
+}
+
+#[cfg(feature = "add")]
+impl WrongVariantError {
+ #[doc(hidden)]
+ #[must_use]
+ #[inline]
+ pub const fn new(operation_name: &'static str) -> Self {
+ Self { operation_name }
+ }
+}
+
+#[cfg(feature = "add")]
+impl fmt::Display for WrongVariantError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "Trying to {}() mismatched enum variants",
+ self.operation_name
+ )
+ }
+}
+
+#[cfg(all(feature = "add", feature = "std"))]
+impl std::error::Error for WrongVariantError {}
+
+#[cfg(feature = "add")]
+/// Possible errors returned by the derived implementations of binary
+/// arithmetic or logic operations.
+#[derive(Clone, Copy, Debug)]
+pub enum BinaryError {
+ /// Operation is attempted between mismatched enum variants.
+ Mismatch(WrongVariantError),
+
+ /// Operation is attempted on unit-like enum variants.
+ Unit(UnitError),
+}
+
+#[cfg(feature = "add")]
+impl fmt::Display for BinaryError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::Mismatch(e) => write!(f, "{e}"),
+ Self::Unit(e) => write!(f, "{e}"),
+ }
+ }
+}
+
+#[cfg(all(feature = "add", feature = "std"))]
+impl std::error::Error for BinaryError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::Mismatch(e) => e.source(),
+ Self::Unit(e) => e.source(),
+ }
+ }
+}
diff --git a/third_party/rust/derive_more/src/str.rs b/third_party/rust/derive_more/src/str.rs
new file mode 100644
index 0000000000..990281c8db
--- /dev/null
+++ b/third_party/rust/derive_more/src/str.rs
@@ -0,0 +1,25 @@
+use core::fmt;
+
+/// Error of parsing an enum value its string representation.
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
+pub struct FromStrError {
+ type_name: &'static str,
+}
+
+impl FromStrError {
+ #[doc(hidden)]
+ #[must_use]
+ #[inline]
+ pub const fn new(type_name: &'static str) -> Self {
+ Self { type_name }
+ }
+}
+
+impl fmt::Display for FromStrError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "Invalid `{}` string representation", self.type_name)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for FromStrError {}
diff --git a/third_party/rust/derive_more/src/try_unwrap.rs b/third_party/rust/derive_more/src/try_unwrap.rs
new file mode 100644
index 0000000000..7761025ee5
--- /dev/null
+++ b/third_party/rust/derive_more/src/try_unwrap.rs
@@ -0,0 +1,48 @@
+/// Error returned by the derived [`TryUnwrap`] implementation.
+///
+/// [`TryUnwrap`]: macro@crate::TryUnwrap
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct TryUnwrapError<T> {
+ /// Original input value which failed to convert via the derived
+ /// [`TryUnwrap`] implementation.
+ ///
+ /// [`TryUnwrap`]: macro@crate::TryUnwrap
+ pub input: T,
+ enum_name: &'static str,
+ variant_name: &'static str,
+ func_name: &'static str,
+}
+
+impl<T> TryUnwrapError<T> {
+ #[doc(hidden)]
+ #[must_use]
+ #[inline]
+ pub const fn new(
+ input: T,
+ enum_name: &'static str,
+ variant_name: &'static str,
+ func_name: &'static str,
+ ) -> Self {
+ Self {
+ input,
+ enum_name,
+ variant_name,
+ func_name,
+ }
+ }
+}
+
+impl<T> core::fmt::Display for TryUnwrapError<T> {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ write!(
+ f,
+ "Attempt to call `{enum_name}::{func_name}()` on a `{enum_name}::{variant_name}` value",
+ enum_name = self.enum_name,
+ variant_name = self.variant_name,
+ func_name = self.func_name,
+ )
+ }
+}
+
+#[cfg(feature = "std")]
+impl<T: core::fmt::Debug> std::error::Error for TryUnwrapError<T> {}
diff --git a/third_party/rust/derive_more/src/vendor/mod.rs b/third_party/rust/derive_more/src/vendor/mod.rs
new file mode 100644
index 0000000000..a174757d38
--- /dev/null
+++ b/third_party/rust/derive_more/src/vendor/mod.rs
@@ -0,0 +1,2 @@
+#[cfg(feature = "error")]
+pub mod thiserror;
diff --git a/third_party/rust/derive_more/src/vendor/thiserror/README.md b/third_party/rust/derive_more/src/vendor/thiserror/README.md
new file mode 100644
index 0000000000..0c7f1247b4
--- /dev/null
+++ b/third_party/rust/derive_more/src/vendor/thiserror/README.md
@@ -0,0 +1,6 @@
+# Vendored files from `thiserror`
+
+These are vendored files from the [`thiserror`] crate. The license files in this
+directory only apply to the files in this subdirectory of `derive_more`.
+
+[`thiserror`]: https://github.com/dtolnay/thiserror
diff --git a/third_party/rust/derive_more/src/vendor/thiserror/aserror.rs b/third_party/rust/derive_more/src/vendor/thiserror/aserror.rs
new file mode 100644
index 0000000000..c3e086f0b0
--- /dev/null
+++ b/third_party/rust/derive_more/src/vendor/thiserror/aserror.rs
@@ -0,0 +1,52 @@
+#[cfg(not(feature = "std"))]
+use core::error::Error;
+#[cfg(feature = "std")]
+use std::error::Error;
+
+use core::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/derive_more/src/vendor/thiserror/mod.rs b/third_party/rust/derive_more/src/vendor/thiserror/mod.rs
new file mode 100644
index 0000000000..a6add8b82e
--- /dev/null
+++ b/third_party/rust/derive_more/src/vendor/thiserror/mod.rs
@@ -0,0 +1 @@
+pub mod aserror;
diff --git a/third_party/rust/derive_more/tests/add.rs b/third_party/rust/derive_more/tests/add.rs
new file mode 100644
index 0000000000..4c38fdae31
--- /dev/null
+++ b/third_party/rust/derive_more/tests/add.rs
@@ -0,0 +1,24 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use derive_more::Add;
+
+#[derive(Add)]
+struct MyInts(i32, i32);
+
+#[derive(Add)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
+
+#[derive(Add)]
+enum MixedInts {
+ SmallInt(i32),
+ BigInt(i64),
+ TwoSmallInts(i32, i32),
+ NamedSmallInts { x: i32, y: i32 },
+ UnsignedOne(u32),
+ UnsignedTwo(u32),
+ Unit,
+}
diff --git a/third_party/rust/derive_more/tests/add_assign.rs b/third_party/rust/derive_more/tests/add_assign.rs
new file mode 100644
index 0000000000..4879585171
--- /dev/null
+++ b/third_party/rust/derive_more/tests/add_assign.rs
@@ -0,0 +1,13 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use derive_more::AddAssign;
+
+#[derive(AddAssign)]
+struct MyInts(i32, i32);
+
+#[derive(AddAssign)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
diff --git a/third_party/rust/derive_more/tests/as_mut.rs b/third_party/rust/derive_more/tests/as_mut.rs
new file mode 100644
index 0000000000..2a973d450c
--- /dev/null
+++ b/third_party/rust/derive_more/tests/as_mut.rs
@@ -0,0 +1,117 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::{string::String, vec, vec::Vec};
+use core::ptr;
+
+use derive_more::AsMut;
+
+#[derive(AsMut)]
+struct SingleFieldTuple(String);
+
+#[test]
+fn single_field_tuple() {
+ let mut item = SingleFieldTuple("test".into());
+
+ assert!(ptr::eq(&mut item.0, item.as_mut()));
+}
+
+#[derive(AsMut)]
+#[as_mut(forward)]
+struct SingleFieldForward(Vec<i32>);
+
+#[test]
+fn single_field_forward() {
+ let mut item = SingleFieldForward(vec![]);
+ let _: &mut [i32] = (&mut item).as_mut();
+}
+
+#[derive(AsMut)]
+struct SingleFieldStruct {
+ first: String,
+}
+
+#[test]
+fn single_field_struct() {
+ let mut item = SingleFieldStruct {
+ first: "test".into(),
+ };
+
+ assert!(ptr::eq(&mut item.first, item.as_mut()));
+}
+
+#[cfg(feature = "std")]
+mod pathbuf {
+ use std::path::PathBuf;
+
+ use super::*;
+
+ #[derive(AsMut)]
+ struct MultiFieldTuple(#[as_mut] String, #[as_mut] PathBuf, Vec<usize>);
+
+ #[test]
+ fn multi_field_tuple() {
+ let mut item = MultiFieldTuple("test".into(), PathBuf::new(), vec![]);
+
+ assert!(ptr::eq(&mut item.0, item.as_mut()));
+ assert!(ptr::eq(&mut item.1, item.as_mut()));
+ }
+
+ #[derive(AsMut)]
+ struct MultiFieldStruct {
+ #[as_mut]
+ first: String,
+ #[as_mut]
+ second: PathBuf,
+ third: Vec<usize>,
+ }
+
+ #[test]
+ fn multi_field_struct() {
+ let mut item = MultiFieldStruct {
+ first: "test".into(),
+ second: PathBuf::new(),
+ third: vec![],
+ };
+
+ assert!(ptr::eq(&mut item.first, item.as_mut()));
+ assert!(ptr::eq(&mut item.second, item.as_mut()));
+ }
+
+ #[derive(AsMut)]
+ struct MultiFieldGenericStruct<T> {
+ #[as_mut]
+ first: Vec<T>,
+ #[as_mut]
+ second: PathBuf,
+ third: Vec<usize>,
+ }
+
+ #[test]
+ fn multi_field_generic_struct() {
+ let mut item = MultiFieldGenericStruct {
+ first: b"test".to_vec(),
+ second: PathBuf::new(),
+ third: vec![],
+ };
+
+ assert!(ptr::eq(&mut item.first, item.as_mut()));
+ assert!(ptr::eq(&mut item.second, item.as_mut()));
+ }
+}
+
+#[derive(AsMut)]
+struct SingleFieldGenericStruct<T> {
+ first: T,
+}
+
+#[test]
+fn single_field_generic_struct() {
+ let mut item = SingleFieldGenericStruct { first: "test" };
+
+ assert!(ptr::eq(&mut item.first, item.as_mut()));
+}
diff --git a/third_party/rust/derive_more/tests/as_ref.rs b/third_party/rust/derive_more/tests/as_ref.rs
new file mode 100644
index 0000000000..d28f9343c2
--- /dev/null
+++ b/third_party/rust/derive_more/tests/as_ref.rs
@@ -0,0 +1,117 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::{string::String, vec, vec::Vec};
+use core::ptr;
+
+use derive_more::AsRef;
+
+#[derive(AsRef)]
+struct SingleFieldTuple(String);
+
+#[test]
+fn single_field_tuple() {
+ let item = SingleFieldTuple("test".into());
+
+ assert!(ptr::eq(&item.0, item.as_ref()));
+}
+
+#[derive(AsRef)]
+#[as_ref(forward)]
+struct SingleFieldForward(Vec<i32>);
+
+#[test]
+fn single_field_forward() {
+ let item = SingleFieldForward(vec![]);
+ let _: &[i32] = (&item).as_ref();
+}
+
+#[derive(AsRef)]
+struct SingleFieldStruct {
+ first: String,
+}
+
+#[test]
+fn single_field_struct() {
+ let item = SingleFieldStruct {
+ first: "test".into(),
+ };
+
+ assert!(ptr::eq(&item.first, item.as_ref()));
+}
+
+#[cfg(feature = "std")]
+mod pathbuf {
+ use std::path::PathBuf;
+
+ use super::*;
+
+ #[derive(AsRef)]
+ struct MultiFieldTuple(#[as_ref] String, #[as_ref] PathBuf, Vec<usize>);
+
+ #[test]
+ fn multi_field_tuple() {
+ let item = MultiFieldTuple("test".into(), PathBuf::new(), vec![]);
+
+ assert!(ptr::eq(&item.0, item.as_ref()));
+ assert!(ptr::eq(&item.1, item.as_ref()));
+ }
+
+ #[derive(AsRef)]
+ struct MultiFieldStruct {
+ #[as_ref]
+ first: String,
+ #[as_ref]
+ second: PathBuf,
+ third: Vec<usize>,
+ }
+
+ #[test]
+ fn multi_field_struct() {
+ let item = MultiFieldStruct {
+ first: "test".into(),
+ second: PathBuf::new(),
+ third: vec![],
+ };
+
+ assert!(ptr::eq(&item.first, item.as_ref()));
+ assert!(ptr::eq(&item.second, item.as_ref()));
+ }
+}
+
+#[derive(AsRef)]
+struct SingleFieldGenericStruct<T> {
+ first: T,
+}
+
+#[test]
+fn single_field_generic_struct() {
+ let item = SingleFieldGenericStruct { first: "test" };
+
+ assert!(ptr::eq(&item.first, item.as_ref()));
+}
+
+#[derive(AsRef)]
+struct MultiFieldGenericStruct<T, U> {
+ #[as_ref]
+ first: Vec<T>,
+ #[as_ref]
+ second: [U; 2],
+ third: Vec<usize>,
+}
+
+#[test]
+fn multi_field_generic_struct() {
+ let item = MultiFieldGenericStruct {
+ first: b"test".to_vec(),
+ second: [0i32, 1i32],
+ third: vec![],
+ };
+
+ assert!(ptr::eq(&item.first, item.as_ref()));
+ assert!(ptr::eq(&item.second, item.as_ref()));
+}
diff --git a/third_party/rust/derive_more/tests/boats_display_derive.rs b/third_party/rust/derive_more/tests/boats_display_derive.rs
new file mode 100644
index 0000000000..8f86519f73
--- /dev/null
+++ b/third_party/rust/derive_more/tests/boats_display_derive.rs
@@ -0,0 +1,56 @@
+// The following code is from https://github.com/withoutboats/display_derive/blob/232a32ee19e262aacbd2c93be5b4ce9e89a5fc30/tests/tests.rs
+// Written by without boats originally
+
+use derive_more::Display;
+
+#[derive(Display)]
+#[display("An error has occurred.")]
+struct UnitError;
+
+#[test]
+fn unit_struct() {
+ let s = UnitError.to_string();
+ assert_eq!(s, "An error has occurred.");
+}
+
+#[derive(Display)]
+#[display("Error code: {}", code)]
+struct RecordError {
+ code: u32,
+}
+
+#[test]
+fn record_struct() {
+ let s = RecordError { code: 0 }.to_string();
+ assert_eq!(s, "Error code: 0");
+}
+
+#[derive(Display)]
+#[display("Error code: {}", _0)]
+struct TupleError(i32);
+
+#[test]
+fn tuple_struct() {
+ let s = TupleError(2).to_string();
+ assert_eq!(s, "Error code: 2");
+}
+
+#[derive(Display)]
+enum EnumError {
+ #[display("Error code: {}", code)]
+ StructVariant { code: i32 },
+ #[display("Error: {}", _0)]
+ TupleVariant(&'static str),
+ #[display("An error has occurred.")]
+ UnitVariant,
+}
+
+#[test]
+fn enum_error() {
+ let s = EnumError::StructVariant { code: 2 }.to_string();
+ assert_eq!(s, "Error code: 2");
+ let s = EnumError::TupleVariant("foobar").to_string();
+ assert_eq!(s, "Error: foobar");
+ let s = EnumError::UnitVariant.to_string();
+ assert_eq!(s, "An error has occurred.");
+}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/both_fmt_and_skip_on_field.rs b/third_party/rust/derive_more/tests/compile_fail/debug/both_fmt_and_skip_on_field.rs
new file mode 100644
index 0000000000..24227909ab
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/both_fmt_and_skip_on_field.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug("Stuff({}): {}", bar)]
+ #[debug(skip)]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/extra_placeholder.rs b/third_party/rust/derive_more/tests/compile_fail/debug/extra_placeholder.rs
new file mode 100644
index 0000000000..b318701640
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/extra_placeholder.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug("Stuff({}): {}", bar)]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/legacy_bound_syntax.rs b/third_party/rust/derive_more/tests/compile_fail/debug/legacy_bound_syntax.rs
new file mode 100644
index 0000000000..72d1e0a924
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/legacy_bound_syntax.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+#[debug(bound = "String: std::fmt::Display")]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/legacy_fmt_syntax.rs b/third_party/rust/derive_more/tests/compile_fail/debug/legacy_fmt_syntax.rs
new file mode 100644
index 0000000000..ff49445bfa
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/legacy_fmt_syntax.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug(fmt = "Stuff({}): {}", "bar")]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/missing_placeholder.rs b/third_party/rust/derive_more/tests/compile_fail/debug/missing_placeholder.rs
new file mode 100644
index 0000000000..1a27e9e2cc
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/missing_placeholder.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug("Stuff()", bar)]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/named_field_prefixed_with_dot.rs b/third_party/rust/derive_more/tests/compile_fail/debug/named_field_prefixed_with_dot.rs
new file mode 100644
index 0000000000..0c2284ab65
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/named_field_prefixed_with_dot.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug("Stuff({})", .bar)]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/unclosed_brace.rs b/third_party/rust/derive_more/tests/compile_fail/debug/unclosed_brace.rs
new file mode 100644
index 0000000000..47414f50de
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/unclosed_brace.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug("Stuff({)", bar)]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/union.rs b/third_party/rust/derive_more/tests/compile_fail/debug/union.rs
new file mode 100644
index 0000000000..235f46ad3e
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/union.rs
@@ -0,0 +1,6 @@
+#[derive(derive_more::Debug)]
+pub union Foo {
+ bar: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/unknown_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/debug/unknown_attribute.rs
new file mode 100644
index 0000000000..d9c8f881e9
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/unknown_attribute.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+#[debug(unknown = "unknown")]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/unnamed_field_prefixed_with_dot.rs b/third_party/rust/derive_more/tests/compile_fail/debug/unnamed_field_prefixed_with_dot.rs
new file mode 100644
index 0000000000..2bff1e972b
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/unnamed_field_prefixed_with_dot.rs
@@ -0,0 +1,4 @@
+#[derive(derive_more::Debug)]
+pub struct Foo(#[debug("Stuff({})", .0)] String);
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/wrong_formatting_argument.rs b/third_party/rust/derive_more/tests/compile_fail/debug/wrong_formatting_argument.rs
new file mode 100644
index 0000000000..c280decc00
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/wrong_formatting_argument.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug("Stuff({bar:M})")]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/wrong_named_parameter.rs b/third_party/rust/derive_more/tests/compile_fail/debug/wrong_named_parameter.rs
new file mode 100644
index 0000000000..292b8abb62
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/wrong_named_parameter.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Debug)]
+pub struct Foo {
+ #[debug("Stuff({bars})")]
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/debug/wrong_unnamed_parameter.rs b/third_party/rust/derive_more/tests/compile_fail/debug/wrong_unnamed_parameter.rs
new file mode 100644
index 0000000000..84892e38fb
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/debug/wrong_unnamed_parameter.rs
@@ -0,0 +1,4 @@
+#[derive(derive_more::Debug)]
+pub struct Foo(#[debug("Stuff({_1})")] String);
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/extra_placeholder.rs b/third_party/rust/derive_more/tests/compile_fail/display/extra_placeholder.rs
new file mode 100644
index 0000000000..307e869a39
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/extra_placeholder.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({}): {}", bar)]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/legacy_bound_syntax.rs b/third_party/rust/derive_more/tests/compile_fail/display/legacy_bound_syntax.rs
new file mode 100644
index 0000000000..fcfdfee427
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/legacy_bound_syntax.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display(bound = "String: std::fmt::Display")]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/legacy_fmt_syntax.rs b/third_party/rust/derive_more/tests/compile_fail/display/legacy_fmt_syntax.rs
new file mode 100644
index 0000000000..7db9837536
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/legacy_fmt_syntax.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display(fmt = "Stuff({}): {}", "bar")]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/missing_placeholder.rs b/third_party/rust/derive_more/tests/compile_fail/display/missing_placeholder.rs
new file mode 100644
index 0000000000..bb99d9f312
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/missing_placeholder.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display("Stuff()", bar)]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/mutlifield_enum_variant_without_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/display/mutlifield_enum_variant_without_attribute.rs
new file mode 100644
index 0000000000..4deec36fea
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/mutlifield_enum_variant_without_attribute.rs
@@ -0,0 +1,6 @@
+#[derive(derive_more::Display)]
+enum Enum {
+ Variant { foo: String, bar: String },
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/mutlifield_struct_without_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/display/mutlifield_struct_without_attribute.rs
new file mode 100644
index 0000000000..a9df0d4b83
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/mutlifield_struct_without_attribute.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+pub struct Foo {
+ foo: String,
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/named_field_prefixed_with_dot.rs b/third_party/rust/derive_more/tests/compile_fail/display/named_field_prefixed_with_dot.rs
new file mode 100644
index 0000000000..37c8829b6d
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/named_field_prefixed_with_dot.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({})", .bar)]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/non_display_implicit_enum_unit_variant.rs b/third_party/rust/derive_more/tests/compile_fail/display/non_display_implicit_enum_unit_variant.rs
new file mode 100644
index 0000000000..9b8969212b
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/non_display_implicit_enum_unit_variant.rs
@@ -0,0 +1,6 @@
+#[derive(derive_more::Display, derive_more::UpperHex)]
+enum Enum {
+ UnitVariant,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/unclosed_brace.rs b/third_party/rust/derive_more/tests/compile_fail/display/unclosed_brace.rs
new file mode 100644
index 0000000000..c002b582b2
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/unclosed_brace.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({)", bar)]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/unknown_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/display/unknown_attribute.rs
new file mode 100644
index 0000000000..24135017f5
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/unknown_attribute.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({})", bar)]
+#[display(unknown = "unknown")]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/unnamed_field_prefixed_with_dot.rs b/third_party/rust/derive_more/tests/compile_fail/display/unnamed_field_prefixed_with_dot.rs
new file mode 100644
index 0000000000..711f5aa573
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/unnamed_field_prefixed_with_dot.rs
@@ -0,0 +1,5 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({})", .0)]
+pub struct Foo(String);
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/wrong_formatting_argument.rs b/third_party/rust/derive_more/tests/compile_fail/display/wrong_formatting_argument.rs
new file mode 100644
index 0000000000..19199c0ac7
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/wrong_formatting_argument.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({:M})", bar)]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/wrong_named_parameter.rs b/third_party/rust/derive_more/tests/compile_fail/display/wrong_named_parameter.rs
new file mode 100644
index 0000000000..d286ac7635
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/wrong_named_parameter.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({bars})")]
+pub struct Foo {
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/display/wrong_unnamed_parameter.rs b/third_party/rust/derive_more/tests/compile_fail/display/wrong_unnamed_parameter.rs
new file mode 100644
index 0000000000..ab8c2b6ee5
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/display/wrong_unnamed_parameter.rs
@@ -0,0 +1,5 @@
+#[derive(derive_more::Display)]
+#[display("Stuff({_1})")]
+pub struct Foo(String);
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/legacy_enum_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/from/legacy_enum_attribute.rs
new file mode 100644
index 0000000000..26551a75db
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/legacy_enum_attribute.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::From)]
+enum Foo {
+ #[from(types(i32, "&str"))]
+ Bar(String),
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/legacy_struct_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/from/legacy_struct_attribute.rs
new file mode 100644
index 0000000000..1c7d9c5c46
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/legacy_struct_attribute.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::From)]
+#[from(types(i32, "&str"))]
+struct Foo {
+ foo: String,
+ bar: String,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/multiple_enum_attributes.rs b/third_party/rust/derive_more/tests/compile_fail/from/multiple_enum_attributes.rs
new file mode 100644
index 0000000000..6fc73eedb8
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/multiple_enum_attributes.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::From)]
+enum Foo {
+ #[from(i32)]
+ #[from(forward)]
+ Bar(i32),
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/multiple_struct_attributes.rs b/third_party/rust/derive_more/tests/compile_fail/from/multiple_struct_attributes.rs
new file mode 100644
index 0000000000..4fa2a84c32
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/multiple_struct_attributes.rs
@@ -0,0 +1,6 @@
+#[derive(derive_more::From)]
+#[from(i32)]
+#[from(forward)]
+struct Foo(i32);
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_no_parens.rs b/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_no_parens.rs
new file mode 100644
index 0000000000..8dd4462d1c
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_no_parens.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::From)]
+#[from(i16, i16)]
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_long.rs b/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_long.rs
new file mode 100644
index 0000000000..ed56c0a53b
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_long.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::From)]
+#[from((i16, i16, i16))]
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_short.rs b/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_short.rs
new file mode 100644
index 0000000000..2f51473124
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/struct_tuple_too_short.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::From)]
+#[from((i16,))]
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/from/union.rs b/third_party/rust/derive_more/tests/compile_fail/from/union.rs
new file mode 100644
index 0000000000..d0e78f144c
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/from/union.rs
@@ -0,0 +1,6 @@
+#[derive(derive_more::From)]
+pub union Foo {
+ bar: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/enum.rs b/third_party/rust/derive_more/tests/compile_fail/into/enum.rs
new file mode 100644
index 0000000000..33edf28744
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/enum.rs
@@ -0,0 +1,6 @@
+#[derive(derive_more::Into)]
+enum Foo {
+ Foo(i32),
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/legacy_complex_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/into/legacy_complex_attribute.rs
new file mode 100644
index 0000000000..f58e77269c
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/legacy_complex_attribute.rs
@@ -0,0 +1,5 @@
+#[derive(derive_more::Into)]
+#[into(owned(types("Cow<'_ str>")), ref, ref_mut, types(i32, "&str"))]
+struct Foo(String);
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/legacy_types_attribute.rs b/third_party/rust/derive_more/tests/compile_fail/into/legacy_types_attribute.rs
new file mode 100644
index 0000000000..5b8a1ba8b1
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/legacy_types_attribute.rs
@@ -0,0 +1,5 @@
+#[derive(derive_more::Into)]
+#[into(types(i32, "&str"))]
+struct Foo(String);
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/mixed_regular_and_wrapped_types.rs b/third_party/rust/derive_more/tests/compile_fail/into/mixed_regular_and_wrapped_types.rs
new file mode 100644
index 0000000000..43f81fb016
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/mixed_regular_and_wrapped_types.rs
@@ -0,0 +1,7 @@
+#[derive(derive_more::Into)]
+#[into(owned, ref(i32), i32)]
+struct Foo {
+ bar: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/tuple_no_parens.rs b/third_party/rust/derive_more/tests/compile_fail/into/tuple_no_parens.rs
new file mode 100644
index 0000000000..7491e38da5
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/tuple_no_parens.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::Into)]
+#[into(i16, i16)]
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/tuple_too_long.rs b/third_party/rust/derive_more/tests/compile_fail/into/tuple_too_long.rs
new file mode 100644
index 0000000000..cef55931f3
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/tuple_too_long.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::Into)]
+#[into((i16, i16, i16))]
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/tuple_too_short.rs b/third_party/rust/derive_more/tests/compile_fail/into/tuple_too_short.rs
new file mode 100644
index 0000000000..89ee92468a
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/tuple_too_short.rs
@@ -0,0 +1,8 @@
+#[derive(derive_more::Into)]
+#[into((i16,))]
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/into/union.rs b/third_party/rust/derive_more/tests/compile_fail/into/union.rs
new file mode 100644
index 0000000000..623989c037
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/into/union.rs
@@ -0,0 +1,6 @@
+#[derive(derive_more::Into)]
+pub union Foo {
+ bar: i32,
+}
+
+fn main() {}
diff --git a/third_party/rust/derive_more/tests/compile_fail/mod.rs b/third_party/rust/derive_more/tests/compile_fail/mod.rs
new file mode 100644
index 0000000000..3ed2e6e839
--- /dev/null
+++ b/third_party/rust/derive_more/tests/compile_fail/mod.rs
@@ -0,0 +1,6 @@
+#[rustversion::stable]
+#[test]
+fn compile_fail() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/compile_fail/*/*.rs");
+}
diff --git a/third_party/rust/derive_more/tests/constructor.rs b/third_party/rust/derive_more/tests/constructor.rs
new file mode 100644
index 0000000000..6199d1d14d
--- /dev/null
+++ b/third_party/rust/derive_more/tests/constructor.rs
@@ -0,0 +1,32 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use derive_more::Constructor;
+
+#[derive(Constructor)]
+struct EmptyTuple();
+
+const EMPTY_TUPLE: EmptyTuple = EmptyTuple::new();
+
+#[derive(Constructor)]
+struct EmptyStruct {}
+
+const EMPTY_STRUCT: EmptyStruct = EmptyStruct::new();
+
+#[derive(Constructor)]
+struct EmptyUnit;
+
+const EMPTY_UNIT: EmptyUnit = EmptyUnit::new();
+
+#[derive(Constructor)]
+struct MyInts(i32, i32);
+
+const MY_INTS: MyInts = MyInts::new(1, 2);
+
+#[derive(Constructor)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
+
+const POINT_2D: Point2D = Point2D::new(-4, 7);
diff --git a/third_party/rust/derive_more/tests/debug.rs b/third_party/rust/derive_more/tests/debug.rs
new file mode 100644
index 0000000000..de9ff611bd
--- /dev/null
+++ b/third_party/rust/derive_more/tests/debug.rs
@@ -0,0 +1,1155 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+mod structs {
+ mod unit {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Unit;
+
+ #[derive(Debug)]
+ struct Tuple();
+
+ #[derive(Debug)]
+ struct Struct {}
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Unit), "Unit");
+ assert_eq!(format!("{:#?}", Unit), "Unit");
+ assert_eq!(format!("{:?}", Tuple()), "Tuple");
+ assert_eq!(format!("{:#?}", Tuple()), "Tuple");
+ assert_eq!(format!("{:?}", Struct {}), "Struct");
+ assert_eq!(format!("{:#?}", Struct {}), "Struct");
+ }
+ }
+
+ mod single_field {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(0)), "Tuple(0)");
+ assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(\n 0,\n)");
+ assert_eq!(format!("{:?}", Struct { field: 0 }), "Struct { field: 0 }");
+ assert_eq!(
+ format!("{:#?}", Struct { field: 0 }),
+ "Struct {\n field: 0,\n}",
+ );
+ }
+
+ mod str_field {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(#[debug("i32")] i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ #[debug("i32")]
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(0)), "Tuple(i32)");
+ assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(\n i32,\n)");
+ assert_eq!(
+ format!("{:?}", Struct { field: 0 }),
+ "Struct { field: i32 }",
+ );
+ assert_eq!(
+ format!("{:#?}", Struct { field: 0 }),
+ "Struct {\n field: i32,\n}",
+ );
+ }
+ }
+
+ mod interpolated_field {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(#[debug("{_0}.{}", _0)] i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ #[debug("{field}.{}", field)]
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(0)), "Tuple(0.0)");
+ assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(\n 0.0,\n)");
+ assert_eq!(
+ format!("{:?}", Struct { field: 0 }),
+ "Struct { field: 0.0 }",
+ );
+ assert_eq!(
+ format!("{:#?}", Struct { field: 0 }),
+ "Struct {\n field: 0.0,\n}",
+ );
+ }
+ }
+
+ mod ignore {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(#[debug(ignore)] i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ #[debug(skip)]
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(0)), "Tuple(..)");
+ assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(..)");
+ assert_eq!(format!("{:?}", Struct { field: 0 }), "Struct { .. }");
+ assert_eq!(format!("{:#?}", Struct { field: 0 }), "Struct { .. }");
+ }
+ }
+ }
+
+ mod multi_field {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(i32, i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ field1: i32,
+ field2: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(1, 2)");
+ assert_eq!(format!("{:#?}", Tuple(1, 2)), "Tuple(\n 1,\n 2,\n)");
+ assert_eq!(
+ format!(
+ "{:?}",
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "Struct { field1: 1, field2: 2 }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "Struct {\n field1: 1,\n field2: 2,\n}",
+ );
+ }
+
+ mod str_field {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(i32, #[debug("i32")] i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ #[debug("i32")]
+ field1: i32,
+ field2: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(1, i32)");
+ assert_eq!(
+ format!("{:#?}", Tuple(1, 2)),
+ "Tuple(\n 1,\n i32,\n)",
+ );
+ assert_eq!(
+ format!(
+ "{:?}",
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "Struct { field1: i32, field2: 2 }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "Struct {\n field1: i32,\n field2: 2,\n}",
+ );
+ }
+ }
+
+ mod interpolated_field {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(i32, #[debug("{_0}.{}", _1)] i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ #[debug("{field1}.{}", field2)]
+ field1: i32,
+ field2: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(1, 1.2)");
+ assert_eq!(
+ format!("{:#?}", Tuple(1, 2)),
+ "Tuple(\n 1,\n 1.2,\n)",
+ );
+ assert_eq!(
+ format!(
+ "{:?}",
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "Struct { field1: 1.2, field2: 2 }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "Struct {\n field1: 1.2,\n field2: 2,\n}",
+ );
+ }
+ }
+
+ mod ignore {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Tuple(#[debug(ignore)] i32, i32);
+
+ #[derive(Debug)]
+ struct Struct {
+ field1: i32,
+ #[debug(skip)]
+ field2: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(2, ..)");
+ assert_eq!(format!("{:#?}", Tuple(1, 2)), "Tuple(\n 2,\n ..\n)",);
+ assert_eq!(
+ format!(
+ "{:?}",
+ Struct {
+ field1: 1,
+ field2: 2
+ }
+ ),
+ "Struct { field1: 1, .. }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ Struct {
+ field1: 1,
+ field2: 2
+ }
+ ),
+ "Struct {\n field1: 1,\n ..\n}",
+ );
+ }
+ }
+ }
+}
+
+mod enums {
+ mod no_variants {
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ enum Void {}
+
+ const fn assert<T: core::fmt::Debug>() {}
+ const _: () = assert::<Void>();
+ }
+
+ mod unit_variant {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ enum Enum {
+ Unit,
+ Unnamed(),
+ Named {},
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Enum::Unit), "Unit");
+ assert_eq!(format!("{:#?}", Enum::Unit), "Unit");
+ assert_eq!(format!("{:?}", Enum::Unnamed()), "Unnamed");
+ assert_eq!(format!("{:#?}", Enum::Unnamed()), "Unnamed");
+ assert_eq!(format!("{:?}", Enum::Named {}), "Named");
+ assert_eq!(format!("{:#?}", Enum::Named {}), "Named");
+ }
+ }
+
+ mod single_field_variant {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ enum Enum {
+ Unnamed(i32),
+ Named {
+ field: i32,
+ },
+ StrUnnamed(#[debug("i32")] i32),
+ StrNamed {
+ #[debug("i32")]
+ field: i32,
+ },
+ InterpolatedUnnamed(#[debug("{_0}.{}", _0)] i32),
+ InterpolatedNamed {
+ #[debug("{field}.{}", field)]
+ field: i32,
+ },
+ SkippedUnnamed(#[debug(skip)] i32),
+ SkippedNamed {
+ #[debug(skip)]
+ field: i32,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Enum::Unnamed(1)), "Unnamed(1)");
+ assert_eq!(format!("{:#?}", Enum::Unnamed(1)), "Unnamed(\n 1,\n)");
+ assert_eq!(
+ format!("{:?}", Enum::Named { field: 1 }),
+ "Named { field: 1 }",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::Named { field: 1 }),
+ "Named {\n field: 1,\n}",
+ );
+ assert_eq!(format!("{:?}", Enum::StrUnnamed(1)), "StrUnnamed(i32)");
+ assert_eq!(
+ format!("{:#?}", Enum::StrUnnamed(1)),
+ "StrUnnamed(\n i32,\n)",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::StrNamed { field: 1 }),
+ "StrNamed { field: i32 }",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::StrNamed { field: 1 }),
+ "StrNamed {\n field: i32,\n}",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::InterpolatedUnnamed(1)),
+ "InterpolatedUnnamed(1.1)",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::InterpolatedUnnamed(1)),
+ "InterpolatedUnnamed(\n 1.1,\n)",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::InterpolatedNamed { field: 1 }),
+ "InterpolatedNamed { field: 1.1 }",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::InterpolatedNamed { field: 1 }),
+ "InterpolatedNamed {\n field: 1.1,\n}",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::SkippedUnnamed(1)),
+ "SkippedUnnamed(..)",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::SkippedUnnamed(1)),
+ "SkippedUnnamed(..)",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::SkippedNamed { field: 1 }),
+ "SkippedNamed { .. }",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::SkippedNamed { field: 1 }),
+ "SkippedNamed { .. }",
+ );
+ }
+ }
+
+ mod multi_field_variant {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ enum Enum {
+ Unnamed(i32, i32),
+ Named {
+ field1: i32,
+ field2: i32,
+ },
+ StrUnnamed(#[debug("i32")] i32, i32),
+ StrNamed {
+ field1: i32,
+ #[debug("i32")]
+ field2: i32,
+ },
+ InterpolatedUnnamed(i32, #[debug("{_0}.{}", _1)] i32),
+ InterpolatedNamed {
+ #[debug("{field1}.{}", field2)]
+ field1: i32,
+ field2: i32,
+ },
+ SkippedUnnamed(i32, #[debug(skip)] i32),
+ SkippedNamed {
+ #[debug(skip)]
+ field1: i32,
+ field2: i32,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(format!("{:?}", Enum::Unnamed(1, 2)), "Unnamed(1, 2)");
+ assert_eq!(
+ format!("{:#?}", Enum::Unnamed(1, 2)),
+ "Unnamed(\n 1,\n 2,\n)",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::StrUnnamed(1, 2)),
+ "StrUnnamed(i32, 2)",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::StrUnnamed(1, 2)),
+ "StrUnnamed(\n i32,\n 2,\n)",
+ );
+ assert_eq!(
+ format!(
+ "{:?}",
+ Enum::StrNamed {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "StrNamed { field1: 1, field2: i32 }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ Enum::StrNamed {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "StrNamed {\n field1: 1,\n field2: i32,\n}",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::InterpolatedUnnamed(1, 2)),
+ "InterpolatedUnnamed(1, 1.2)",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::InterpolatedUnnamed(1, 2)),
+ "InterpolatedUnnamed(\n 1,\n 1.2,\n)",
+ );
+ assert_eq!(
+ format!(
+ "{:?}",
+ Enum::InterpolatedNamed {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "InterpolatedNamed { field1: 1.2, field2: 2 }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ Enum::InterpolatedNamed {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "InterpolatedNamed {\n field1: 1.2,\n field2: 2,\n}",
+ );
+ assert_eq!(
+ format!("{:?}", Enum::SkippedUnnamed(1, 2)),
+ "SkippedUnnamed(1, ..)",
+ );
+ assert_eq!(
+ format!("{:#?}", Enum::SkippedUnnamed(1, 2)),
+ "SkippedUnnamed(\n 1,\n ..\n)",
+ );
+ assert_eq!(
+ format!(
+ "{:?}",
+ Enum::SkippedNamed {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "SkippedNamed { field2: 2, .. }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ Enum::SkippedNamed {
+ field1: 1,
+ field2: 2,
+ }
+ ),
+ "SkippedNamed {\n field2: 2,\n ..\n}",
+ );
+ }
+ }
+}
+
+mod generic {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ struct NotDebug;
+
+ trait Bound {}
+
+ impl Bound for () {}
+
+ fn display_bound<T: Bound>(_: &T) -> &'static str {
+ "()"
+ }
+
+ #[derive(Debug)]
+ struct NamedGenericStruct<T> {
+ field: T,
+ }
+ #[test]
+ fn named_generic_struct() {
+ assert_eq!(
+ format!("{:?}", NamedGenericStruct { field: 1 }),
+ "NamedGenericStruct { field: 1 }",
+ );
+ assert_eq!(
+ format!("{:#?}", NamedGenericStruct { field: 1 }),
+ "NamedGenericStruct {\n field: 1,\n}",
+ );
+ }
+
+ #[derive(Debug)]
+ struct InterpolatedNamedGenericStruct<T> {
+ #[debug("{field}.{}", field)]
+ field: T,
+ }
+ #[test]
+ fn interpolated_named_generic_struct() {
+ assert_eq!(
+ format!("{:?}", InterpolatedNamedGenericStruct { field: 1 }),
+ "InterpolatedNamedGenericStruct { field: 1.1 }",
+ );
+ assert_eq!(
+ format!("{:#?}", InterpolatedNamedGenericStruct { field: 1 }),
+ "InterpolatedNamedGenericStruct {\n field: 1.1,\n}",
+ );
+ }
+
+ #[derive(Debug)]
+ struct InterpolatedNamedGenericStructWidthPrecision<T> {
+ #[debug("{field:<>width$.prec$}.{field}")]
+ field: T,
+ width: usize,
+ prec: usize,
+ }
+ #[test]
+ fn interpolated_named_generic_struct_width_precision() {
+ assert_eq!(
+ format!(
+ "{:?}",
+ InterpolatedNamedGenericStructWidthPrecision {
+ field: 1.2345,
+ width: 9,
+ prec: 2,
+ }
+ ),
+ "InterpolatedNamedGenericStructWidthPrecision { \
+ field: <<<<<1.23.1.2345, \
+ width: 9, \
+ prec: 2 \
+ }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ InterpolatedNamedGenericStructWidthPrecision {
+ field: 1.2345,
+ width: 9,
+ prec: 2,
+ }
+ ),
+ "InterpolatedNamedGenericStructWidthPrecision {\n \
+ field: <<<<<1.23.1.2345,\n \
+ width: 9,\n \
+ prec: 2,\n\
+ }",
+ );
+ }
+
+ #[derive(Debug)]
+ struct AliasedNamedGenericStruct<T> {
+ #[debug("{alias}", alias = field)]
+ field: T,
+ }
+ #[test]
+ fn aliased_named_generic_struct() {
+ assert_eq!(
+ format!("{:?}", AliasedNamedGenericStruct { field: 1 }),
+ "AliasedNamedGenericStruct { field: 1 }",
+ );
+ assert_eq!(
+ format!("{:#?}", AliasedNamedGenericStruct { field: 1 }),
+ "AliasedNamedGenericStruct {\n field: 1,\n}",
+ );
+ }
+
+ #[derive(Debug)]
+ struct AliasedFieldNamedGenericStruct<T> {
+ #[debug("{field1}", field1 = field2)]
+ field1: T,
+ field2: i32,
+ }
+ #[test]
+ fn aliased_field_named_generic_struct() {
+ assert_eq!(
+ format!(
+ "{:?}",
+ AliasedFieldNamedGenericStruct {
+ field1: NotDebug,
+ field2: 1,
+ },
+ ),
+ "AliasedFieldNamedGenericStruct { field1: 1, field2: 1 }",
+ );
+ assert_eq!(
+ format!(
+ "{:#?}",
+ AliasedFieldNamedGenericStruct {
+ field1: NotDebug,
+ field2: 1,
+ },
+ ),
+ "AliasedFieldNamedGenericStruct {\n field1: 1,\n field2: 1,\n}",
+ );
+ }
+
+ #[derive(Debug)]
+ struct UnnamedGenericStruct<T>(T);
+ #[test]
+ fn unnamed_generic_struct() {
+ assert_eq!(
+ format!("{:?}", UnnamedGenericStruct(2)),
+ "UnnamedGenericStruct(2)",
+ );
+ assert_eq!(
+ format!("{:#?}", UnnamedGenericStruct(2)),
+ "UnnamedGenericStruct(\n 2,\n)",
+ );
+ }
+
+ #[derive(Debug)]
+ struct InterpolatedUnnamedGenericStruct<T>(#[debug("{}.{_0}", _0)] T);
+ #[test]
+ fn interpolated_unnamed_generic_struct() {
+ assert_eq!(
+ format!("{:?}", InterpolatedUnnamedGenericStruct(2)),
+ "InterpolatedUnnamedGenericStruct(2.2)",
+ );
+ assert_eq!(
+ format!("{:#?}", InterpolatedUnnamedGenericStruct(2)),
+ "InterpolatedUnnamedGenericStruct(\n 2.2,\n)",
+ );
+ }
+
+ #[derive(Debug)]
+ struct AliasedUnnamedGenericStruct<T>(#[debug("{alias}", alias = _0)] T);
+ #[test]
+ fn aliased_unnamed_generic_struct() {
+ assert_eq!(
+ format!("{:?}", AliasedUnnamedGenericStruct(2)),
+ "AliasedUnnamedGenericStruct(2)",
+ );
+ assert_eq!(
+ format!("{:#?}", AliasedUnnamedGenericStruct(2)),
+ "AliasedUnnamedGenericStruct(\n 2,\n)",
+ );
+ }
+
+ #[derive(Debug)]
+ struct AliasedFieldUnnamedGenericStruct<T>(#[debug("{_0}", _0 = _1)] T, i32);
+ #[test]
+ fn aliased_field_unnamed_generic_struct() {
+ assert_eq!(
+ format!("{:?}", AliasedFieldUnnamedGenericStruct(NotDebug, 2)),
+ "AliasedFieldUnnamedGenericStruct(2, 2)",
+ );
+ assert_eq!(
+ format!("{:#?}", AliasedFieldUnnamedGenericStruct(NotDebug, 2)),
+ "AliasedFieldUnnamedGenericStruct(\n 2,\n 2,\n)",
+ );
+ }
+
+ #[derive(Debug)]
+ enum GenericEnum<A, B> {
+ A { field: A },
+ B(B),
+ }
+ #[test]
+ fn generic_enum() {
+ assert_eq!(
+ format!("{:?}", GenericEnum::A::<_, u8> { field: 1 }),
+ "A { field: 1 }"
+ );
+ assert_eq!(
+ format!("{:#?}", GenericEnum::A::<_, u8> { field: 1 }),
+ "A {\n field: 1,\n}"
+ );
+ assert_eq!(format!("{:?}", GenericEnum::B::<u8, _>(2)), "B(2)");
+ assert_eq!(
+ format!("{:#?}", GenericEnum::B::<u8, _>(2)),
+ "B(\n 2,\n)",
+ );
+ }
+
+ #[derive(Debug)]
+ enum InterpolatedGenericEnum<A, B> {
+ A {
+ #[debug("{}.{field}", field)]
+ field: A,
+ },
+ B(#[debug("{}.{_0}", _0)] B),
+ }
+ #[test]
+ fn interpolated_generic_enum() {
+ assert_eq!(
+ format!("{:?}", InterpolatedGenericEnum::A::<_, u8> { field: 1 }),
+ "A { field: 1.1 }",
+ );
+ assert_eq!(
+ format!("{:#?}", InterpolatedGenericEnum::A::<_, u8> { field: 1 }),
+ "A {\n field: 1.1,\n}",
+ );
+ assert_eq!(
+ format!("{:?}", InterpolatedGenericEnum::B::<u8, _>(2)),
+ "B(2.2)",
+ );
+ assert_eq!(
+ format!("{:#?}", InterpolatedGenericEnum::B::<u8, _>(2)),
+ "B(\n 2.2,\n)",
+ );
+ }
+
+ #[derive(Debug)]
+ struct MultiTraitNamedGenericStruct<A, B> {
+ #[debug("{}.{}<->{0:o}.{1:#x}<->{0:?}.{1:X?}", a, b)]
+ a: A,
+ b: B,
+ }
+ #[test]
+ fn multi_trait_named_generic_struct() {
+ let s = MultiTraitNamedGenericStruct { a: 8u8, b: 255 };
+ assert_eq!(
+ format!("{s:?}"),
+ "MultiTraitNamedGenericStruct { a: 8.255<->10.0xff<->8.FF, b: 255 }",
+ );
+ assert_eq!(
+ format!("{s:#?}"),
+ "MultiTraitNamedGenericStruct {\n a: 8.255<->10.0xff<->8.FF,\n b: 255,\n}",
+ );
+ }
+
+ #[derive(Debug)]
+ struct MultiTraitUnnamedGenericStruct<A, B>(
+ #[debug("{}.{}.{{}}.{0:o}.{1:#x}-{0:>4?}.{1:^4X?}", _0, _1)] A,
+ B,
+ );
+ #[test]
+ fn multi_trait_unnamed_generic_struct() {
+ let s = MultiTraitUnnamedGenericStruct(8u8, 255);
+ assert_eq!(
+ format!("{s:?}"),
+ "MultiTraitUnnamedGenericStruct(8.255.{}.10.0xff- 8. FF , 255)",
+ );
+ assert_eq!(
+ format!("{s:#?}"),
+ "MultiTraitUnnamedGenericStruct(\n 8.255.{}.10.0xff- 8. FF ,\n 255,\n)",
+ );
+ }
+
+ #[derive(Debug)]
+ struct UnusedGenericStruct<T>(#[debug("{}", 3 * 4)] T);
+ #[test]
+ fn unused_generic_struct() {
+ let s = UnusedGenericStruct(NotDebug);
+ assert_eq!(format!("{s:?}"), "UnusedGenericStruct(12)");
+ assert_eq!(format!("{s:#?}"), "UnusedGenericStruct(\n 12,\n)");
+ }
+
+ mod associated_type_field_enumerator {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ trait Trait {
+ type Type;
+ }
+
+ struct Struct;
+
+ impl Trait for Struct {
+ type Type = i32;
+ }
+
+ #[test]
+ fn auto_generic_named_struct_associated() {
+ #[derive(Debug)]
+ struct AutoGenericNamedStructAssociated<T: Trait> {
+ field: <T as Trait>::Type,
+ }
+
+ let s = AutoGenericNamedStructAssociated::<Struct> { field: 10 };
+ assert_eq!(
+ format!("{s:?}"),
+ "AutoGenericNamedStructAssociated { field: 10 }",
+ );
+ assert_eq!(
+ format!("{s:#?}"),
+ "AutoGenericNamedStructAssociated {\n field: 10,\n}",
+ );
+ }
+
+ #[test]
+ fn auto_generic_unnamed_struct_associated() {
+ #[derive(Debug)]
+ struct AutoGenericUnnamedStructAssociated<T: Trait>(<T as Trait>::Type);
+
+ let s = AutoGenericUnnamedStructAssociated::<Struct>(10);
+ assert_eq!(format!("{s:?}"), "AutoGenericUnnamedStructAssociated(10)",);
+ assert_eq!(
+ format!("{s:#?}"),
+ "AutoGenericUnnamedStructAssociated(\n 10,\n)",
+ );
+ }
+
+ #[test]
+ fn auto_generic_enum_associated() {
+ #[derive(Debug)]
+ enum AutoGenericEnumAssociated<T: Trait> {
+ Enumerator(<T as Trait>::Type),
+ }
+
+ let e = AutoGenericEnumAssociated::<Struct>::Enumerator(10);
+ assert_eq!(format!("{:?}", e), "Enumerator(10)");
+ assert_eq!(format!("{:#?}", e), "Enumerator(\n 10,\n)");
+ }
+ }
+
+ mod complex_type_field_enumerator {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Struct<T>(T);
+
+ #[test]
+ fn auto_generic_named_struct_complex() {
+ #[derive(Debug)]
+ struct AutoGenericNamedStructComplex<T> {
+ field: Struct<T>,
+ }
+
+ let s = AutoGenericNamedStructComplex { field: Struct(10) };
+ assert_eq!(
+ format!("{s:?}"),
+ "AutoGenericNamedStructComplex { field: Struct(10) }",
+ );
+ assert_eq!(
+ format!("{s:#?}"),
+ "AutoGenericNamedStructComplex {\n field: Struct(\n 10,\n ),\n}",
+ );
+ }
+
+ #[test]
+ fn auto_generic_unnamed_struct_complex() {
+ #[derive(Debug)]
+ struct AutoGenericUnnamedStructComplex<T>(Struct<T>);
+
+ let s = AutoGenericUnnamedStructComplex(Struct(10));
+ assert_eq!(
+ format!("{s:?}"),
+ "AutoGenericUnnamedStructComplex(Struct(10))",
+ );
+ assert_eq!(
+ format!("{s:#?}"),
+ "AutoGenericUnnamedStructComplex(\n Struct(\n 10,\n ),\n)",
+ );
+ }
+
+ #[test]
+ fn auto_generic_enum_complex() {
+ #[derive(Debug)]
+ enum AutoGenericEnumComplex<T> {
+ Enumerator(Struct<T>),
+ }
+
+ let e = AutoGenericEnumComplex::Enumerator(Struct(10));
+ assert_eq!(format!("{:?}", e), "Enumerator(Struct(10))");
+ assert_eq!(
+ format!("{:#?}", e),
+ "Enumerator(\n Struct(\n 10,\n ),\n)",
+ )
+ }
+ }
+
+ mod reference {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[test]
+ fn auto_generic_reference() {
+ #[derive(Debug)]
+ struct AutoGenericReference<'a, T>(&'a T);
+
+ let s = AutoGenericReference(&10);
+ assert_eq!(format!("{s:?}"), "AutoGenericReference(10)");
+ assert_eq!(format!("{s:#?}"), "AutoGenericReference(\n 10,\n)");
+ }
+
+ #[test]
+ fn auto_generic_static_reference() {
+ #[derive(Debug)]
+ struct AutoGenericStaticReference<T: 'static>(&'static T);
+
+ let s = AutoGenericStaticReference(&10);
+ assert_eq!(format!("{s:?}"), "AutoGenericStaticReference(10)");
+ assert_eq!(format!("{s:#?}"), "AutoGenericStaticReference(\n 10,\n)",);
+ }
+ }
+
+ mod indirect {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[derive(Debug)]
+ struct Struct<T>(T);
+
+ #[test]
+ fn auto_generic_indirect() {
+ #[derive(Debug)]
+ struct AutoGenericIndirect<T: 'static>(Struct<&'static T>);
+
+ const V: i32 = 10;
+ let s = AutoGenericIndirect(Struct(&V));
+ assert_eq!(format!("{s:?}"), "AutoGenericIndirect(Struct(10))");
+ assert_eq!(
+ format!("{s:#?}"),
+ "AutoGenericIndirect(\n Struct(\n 10,\n ),\n)",
+ );
+ }
+ }
+
+ mod bound {
+ #[cfg(not(feature = "std"))]
+ use alloc::format;
+
+ use derive_more::Debug;
+
+ #[test]
+ fn simple() {
+ #[derive(Debug)]
+ struct Struct<T1, T2>(#[debug("{}.{}", _0, _1)] T1, #[debug(skip)] T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(format!("{s:?}"), "Struct(10.20, ..)");
+ assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)");
+ }
+
+ #[test]
+ fn underscored_simple() {
+ #[derive(Debug)]
+ struct Struct<T1, T2>(#[debug("{_0}.{_1}")] T1, #[debug(skip)] T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(format!("{s:?}"), "Struct(10.20, ..)");
+ assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)");
+ }
+
+ #[test]
+ fn redundant() {
+ #[derive(Debug)]
+ #[debug(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Display))]
+ struct Struct<T1, T2>(#[debug("{}.{}", _0, _1)] T1, #[debug(skip)] T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(format!("{s:?}"), "Struct(10.20, ..)");
+ assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)");
+ }
+
+ #[test]
+ fn underscored_redundant() {
+ #[derive(Debug)]
+ #[debug(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Display))]
+ struct Struct<T1, T2>(#[debug("{_0}.{_1}")] T1, #[debug(ignore)] T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(format!("{s:?}"), "Struct(10.20, ..)");
+ assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)");
+ }
+
+ #[test]
+ fn complex() {
+ trait Trait1 {
+ fn function1(&self) -> &'static str;
+ }
+
+ trait Trait2 {
+ fn function2(&self) -> &'static str;
+ }
+
+ impl Trait1 for i32 {
+ fn function1(&self) -> &'static str {
+ "WHAT"
+ }
+ }
+
+ impl Trait2 for i32 {
+ fn function2(&self) -> &'static str {
+ "EVER"
+ }
+ }
+
+ #[derive(Debug)]
+ #[debug(bound(T1: Trait1 + Trait2, T2: Trait1 + Trait2))]
+ struct Struct<T1, T2>(
+ #[debug("{}_{}_{}_{}", _0.function1(), _0, _1.function2(), _1)] T1,
+ T2,
+ );
+
+ let s = Struct(10, 20);
+ assert_eq!(format!("{s:?}"), "Struct(WHAT_10_EVER_20, 20)");
+ assert_eq!(
+ format!("{s:#?}"),
+ "Struct(\n WHAT_10_EVER_20,\n 20,\n)",
+ );
+ }
+
+ #[test]
+ fn underscored_complex() {
+ trait Trait1 {
+ fn function1(&self) -> &'static str;
+ }
+
+ trait Trait2 {
+ fn function2(&self) -> &'static str;
+ }
+
+ impl Trait1 for i32 {
+ fn function1(&self) -> &'static str {
+ "WHAT"
+ }
+ }
+
+ impl Trait2 for i32 {
+ fn function2(&self) -> &'static str {
+ "EVER"
+ }
+ }
+
+ #[derive(Debug)]
+ #[debug(bound(T1: Trait1 + Trait2, T2: Trait1 + Trait2))]
+ struct Struct<T1, T2>(
+ #[debug("{}_{_0}_{}_{_1}", _0.function1(), _1.function2())] T1,
+ T2,
+ );
+
+ let s = Struct(10, 20);
+ assert_eq!(format!("{s:?}"), "Struct(WHAT_10_EVER_20, 20)");
+ assert_eq!(
+ format!("{s:#?}"),
+ "Struct(\n WHAT_10_EVER_20,\n 20,\n)",
+ );
+ }
+ }
+}
diff --git a/third_party/rust/derive_more/tests/deref.rs b/third_party/rust/derive_more/tests/deref.rs
new file mode 100644
index 0000000000..9c6263eac7
--- /dev/null
+++ b/third_party/rust/derive_more/tests/deref.rs
@@ -0,0 +1,75 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code, unused_imports)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use ::alloc::{boxed::Box, vec::Vec};
+
+use derive_more::Deref;
+
+#[derive(Deref)]
+#[deref(forward)]
+struct MyBoxedInt(Box<i32>);
+
+#[derive(Deref)]
+#[deref(forward)]
+struct NumRef<'a> {
+ num: &'a i32,
+}
+
+#[derive(Deref)]
+struct NumRef2<'a> {
+ #[deref(forward)]
+ num: &'a i32,
+ useless: bool,
+}
+
+#[derive(Deref)]
+#[deref(forward)]
+struct NumRef3<'a> {
+ num: &'a i32,
+ #[deref(ignore)]
+ useless: bool,
+}
+
+#[derive(Deref)]
+struct MyInt(i32);
+
+#[derive(Deref)]
+struct Point1D {
+ x: i32,
+}
+
+#[derive(Deref)]
+struct Point1D2 {
+ x: i32,
+ #[deref(ignore)]
+ useless: bool,
+}
+
+#[derive(Deref)]
+struct CoolVec {
+ cool: bool,
+ #[deref]
+ vec: Vec<i32>,
+}
+
+#[derive(Deref)]
+struct GenericVec<T>(Vec<T>);
+
+#[test]
+fn deref_generic() {
+ let gv = GenericVec(Vec::<i32>::new());
+ assert!(gv.is_empty())
+}
+
+#[derive(Deref)]
+struct GenericBox<T>(#[deref(forward)] Box<T>);
+
+#[test]
+fn deref_generic_forward() {
+ let boxed = GenericBox(Box::new(1i32));
+ assert_eq!(*boxed, 1i32);
+}
diff --git a/third_party/rust/derive_more/tests/deref_mut.rs b/third_party/rust/derive_more/tests/deref_mut.rs
new file mode 100644
index 0000000000..fb1fe87e30
--- /dev/null
+++ b/third_party/rust/derive_more/tests/deref_mut.rs
@@ -0,0 +1,131 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code, unused_imports)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::{boxed::Box, format, vec, vec::Vec};
+
+use derive_more::DerefMut;
+
+#[derive(DerefMut)]
+#[deref_mut(forward)]
+struct MyBoxedInt(Box<i32>);
+// Deref implementation is needed for DerefMut
+impl ::core::ops::Deref for MyBoxedInt {
+ type Target = <Box<i32> as ::core::ops::Deref>::Target;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ <Box<i32> as ::core::ops::Deref>::deref(&self.0)
+ }
+}
+
+#[derive(DerefMut)]
+struct NumRef<'a> {
+ #[deref_mut(forward)]
+ num: &'a mut i32,
+}
+// Deref implementation is needed for DerefMut
+impl<'a> ::core::ops::Deref for NumRef<'a> {
+ type Target = <&'a mut i32 as ::core::ops::Deref>::Target;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ <&'a mut i32 as ::core::ops::Deref>::deref(&self.num)
+ }
+}
+
+#[derive(DerefMut)]
+#[deref_mut(forward)]
+struct NumRef2<'a> {
+ num: &'a mut i32,
+ #[deref_mut(ignore)]
+ useless: bool,
+}
+
+// Deref implementation is needed for DerefMut
+impl<'a> ::core::ops::Deref for NumRef2<'a> {
+ type Target = <&'a mut i32 as ::core::ops::Deref>::Target;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ <&'a mut i32 as ::core::ops::Deref>::deref(&self.num)
+ }
+}
+
+#[derive(DerefMut)]
+struct MyInt(i32);
+
+// Deref implementation is needed for DerefMutToInner
+impl ::core::ops::Deref for MyInt {
+ type Target = i32;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+#[derive(DerefMut)]
+struct Point1D {
+ x: i32,
+}
+
+// Deref implementation is needed for DerefMutToInner
+impl ::core::ops::Deref for Point1D {
+ type Target = i32;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.x
+ }
+}
+
+#[derive(DerefMut)]
+struct CoolVec {
+ cool: bool,
+ #[deref_mut]
+ vec: Vec<i32>,
+}
+impl ::core::ops::Deref for CoolVec {
+ type Target = Vec<i32>;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.vec
+ }
+}
+
+#[derive(DerefMut)]
+struct GenericVec<T>(Vec<T>);
+
+impl<T> ::core::ops::Deref for GenericVec<T> {
+ type Target = Vec<T>;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+#[test]
+fn deref_mut_generic() {
+ let mut gv = GenericVec::<i32>(vec![42]);
+ assert!(gv.get_mut(0).is_some());
+}
+
+#[derive(DerefMut)]
+struct GenericBox<T>(#[deref_mut(forward)] Box<T>);
+
+impl<T> ::core::ops::Deref for GenericBox<T>
+where
+ Box<T>: ::core::ops::Deref,
+{
+ type Target = <Box<T> as ::core::ops::Deref>::Target;
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ <Box<T> as ::core::ops::Deref>::deref(&self.0)
+ }
+}
+
+#[test]
+fn deref_mut_generic_forward() {
+ let mut boxed = GenericBox(Box::new(1i32));
+ *boxed = 3;
+ assert_eq!(*boxed, 3i32);
+}
diff --git a/third_party/rust/derive_more/tests/display.rs b/third_party/rust/derive_more/tests/display.rs
new file mode 100644
index 0000000000..cab2c04796
--- /dev/null
+++ b/third_party/rust/derive_more/tests/display.rs
@@ -0,0 +1,793 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code, unused_imports)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::{
+ boxed::Box,
+ format,
+ string::{String, ToString},
+ vec::Vec,
+};
+
+use derive_more::{Binary, Display, Octal, UpperHex};
+
+mod structs {
+ use super::*;
+
+ mod unit {
+ use super::*;
+
+ #[derive(Display)]
+ struct Unit;
+
+ #[derive(Display)]
+ struct Tuple();
+
+ #[derive(Display)]
+ struct Struct {}
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unit.to_string(), "Unit");
+ assert_eq!(Tuple().to_string(), "Tuple");
+ assert_eq!(Struct {}.to_string(), "Struct");
+ }
+
+ mod str {
+ use super::*;
+
+ #[derive(Display)]
+ #[display("unit")]
+ pub struct Unit;
+
+ #[derive(Display)]
+ #[display("tuple")]
+ pub struct Tuple();
+
+ #[derive(Display)]
+ #[display("struct")]
+ pub struct Struct {}
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unit.to_string(), "unit");
+ assert_eq!(Tuple().to_string(), "tuple");
+ assert_eq!(Struct {}.to_string(), "struct");
+ }
+ }
+
+ mod interpolated {
+ use super::*;
+
+ #[derive(Display)]
+ #[display("unit: {}", 0)]
+ pub struct Unit;
+
+ #[derive(Display)]
+ #[display("tuple: {}", 0)]
+ pub struct Tuple();
+
+ #[derive(Display)]
+ #[display("struct: {}", 0)]
+ pub struct Struct {}
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unit.to_string(), "unit: 0");
+ assert_eq!(Tuple().to_string(), "tuple: 0");
+ assert_eq!(Struct {}.to_string(), "struct: 0");
+ }
+ }
+ }
+
+ mod single_field {
+ use super::*;
+
+ #[derive(Display)]
+ struct Tuple(i32);
+
+ #[derive(Binary)]
+ struct Binary(i32);
+
+ #[derive(Display)]
+ struct Struct {
+ field: i32,
+ }
+
+ #[derive(Octal)]
+ struct Octal {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(0).to_string(), "0");
+ assert_eq!(format!("{:b}", Binary(10)), "1010");
+ assert_eq!(Struct { field: 0 }.to_string(), "0");
+ assert_eq!(format!("{:o}", Octal { field: 10 }).to_string(), "12");
+ }
+
+ mod str {
+ use super::*;
+
+ #[derive(Display)]
+ #[display("tuple")]
+ struct Tuple(i32);
+
+ #[derive(Display)]
+ #[display("struct")]
+ struct Struct {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(0).to_string(), "tuple");
+ assert_eq!(Struct { field: 0 }.to_string(), "struct");
+ }
+ }
+
+ mod interpolated {
+ use super::*;
+
+ #[derive(Display)]
+ #[display("tuple: {_0} {}", _0)]
+ struct Tuple(i32);
+
+ #[derive(Display)]
+ #[display("struct: {field} {}", field)]
+ struct Struct {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(0).to_string(), "tuple: 0 0");
+ assert_eq!(Struct { field: 0 }.to_string(), "struct: 0 0");
+ }
+ }
+ }
+
+ mod multi_field {
+ use super::*;
+
+ mod str {
+ use super::*;
+
+ #[derive(Display)]
+ #[display("tuple")]
+ struct Tuple(i32, i32);
+
+ #[derive(Display)]
+ #[display("struct")]
+ struct Struct {
+ field1: i32,
+ field2: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(1, 2).to_string(), "tuple");
+ assert_eq!(
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ .to_string(),
+ "struct",
+ );
+ }
+ }
+
+ mod interpolated {
+ use super::*;
+
+ #[derive(Display)]
+ #[display(
+ "{_0} {ident} {_1} {} {}",
+ _1, _0 + _1, ident = 123, _1 = _0,
+ )]
+ struct Tuple(i32, i32);
+
+ #[derive(Display)]
+ #[display(
+ "{field1} {ident} {field2} {} {}",
+ field2, field1 + field2, ident = 123, field2 = field1,
+ )]
+ struct Struct {
+ field1: i32,
+ field2: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(1, 2).to_string(), "1 123 1 2 3");
+ assert_eq!(
+ Struct {
+ field1: 1,
+ field2: 2,
+ }
+ .to_string(),
+ "1 123 1 2 3",
+ );
+ }
+ }
+ }
+}
+
+mod enums {
+ use super::*;
+
+ mod no_variants {
+ use super::*;
+
+ #[derive(Display)]
+ enum Void {}
+
+ const fn assert<T: Display>() {}
+ const _: () = assert::<Void>();
+ }
+
+ mod unit_variant {
+ use super::*;
+
+ #[derive(Display)]
+ enum Enum {
+ Unit,
+ Unnamed(),
+ Named {},
+ #[display("STR_UNIT")]
+ StrUnit,
+ #[display("STR_UNNAMED")]
+ StrUnnamed(),
+ #[display("STR_NAMED")]
+ StrNamed {},
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::Unit.to_string(), "Unit");
+ assert_eq!(Enum::Unnamed().to_string(), "Unnamed");
+ assert_eq!(Enum::Named {}.to_string(), "Named");
+ assert_eq!(Enum::StrUnit.to_string(), "STR_UNIT");
+ assert_eq!(Enum::StrUnnamed().to_string(), "STR_UNNAMED");
+ assert_eq!(Enum::StrNamed {}.to_string(), "STR_NAMED");
+ }
+ }
+
+ mod single_field_variant {
+ use super::*;
+
+ #[derive(Display)]
+ enum Enum {
+ Unnamed(i32),
+ Named {
+ field: i32,
+ },
+ #[display("unnamed")]
+ StrUnnamed(i32),
+ #[display("named")]
+ StrNamed {
+ field: i32,
+ },
+ #[display("{_0} {}", _0)]
+ InterpolatedUnnamed(i32),
+ #[display("{field} {}", field)]
+ InterpolatedNamed {
+ field: i32,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::Unnamed(1).to_string(), "1");
+ assert_eq!(Enum::Named { field: 1 }.to_string(), "1");
+ assert_eq!(Enum::StrUnnamed(1).to_string(), "unnamed");
+ assert_eq!(Enum::StrNamed { field: 1 }.to_string(), "named");
+ assert_eq!(Enum::InterpolatedUnnamed(1).to_string(), "1 1");
+ assert_eq!(Enum::InterpolatedNamed { field: 1 }.to_string(), "1 1");
+ }
+ }
+
+ mod multi_field_variant {
+ use super::*;
+
+ #[derive(Display)]
+ enum Enum {
+ #[display("unnamed")]
+ StrUnnamed(i32, i32),
+ #[display("named")]
+ StrNamed { field1: i32, field2: i32 },
+ #[display(
+ "{_0} {ident} {_1} {} {}",
+ _1, _0 + _1, ident = 123, _1 = _0,
+ )]
+ InterpolatedUnnamed(i32, i32),
+ #[display(
+ "{field1} {ident} {field2} {} {}",
+ field2, field1 + field2, ident = 123, field2 = field1,
+ )]
+ InterpolatedNamed { field1: i32, field2: i32 },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::StrUnnamed(1, 2).to_string(), "unnamed");
+ assert_eq!(
+ Enum::StrNamed {
+ field1: 1,
+ field2: 2,
+ }
+ .to_string(),
+ "named",
+ );
+ assert_eq!(Enum::InterpolatedUnnamed(1, 2).to_string(), "1 123 1 2 3");
+ assert_eq!(
+ Enum::InterpolatedNamed {
+ field1: 1,
+ field2: 2,
+ }
+ .to_string(),
+ "1 123 1 2 3",
+ );
+ }
+ }
+}
+
+mod generic {
+ use super::*;
+
+ trait Bound {}
+
+ impl Bound for () {}
+
+ fn display_bound<T: Bound>(_: &T) -> &'static str {
+ "()"
+ }
+
+ #[derive(Display)]
+ #[display("Generic {}", field)]
+ struct NamedGenericStruct<T> {
+ field: T,
+ }
+ #[test]
+ fn named_generic_struct() {
+ assert_eq!(NamedGenericStruct { field: 1 }.to_string(), "Generic 1");
+ }
+
+ #[derive(Display)]
+ #[display("Generic {field}")]
+ struct InterpolatedNamedGenericStruct<T> {
+ field: T,
+ }
+ #[test]
+ fn interpolated_named_generic_struct() {
+ assert_eq!(
+ InterpolatedNamedGenericStruct { field: 1 }.to_string(),
+ "Generic 1",
+ );
+ }
+
+ #[derive(Display)]
+ #[display("Generic {field:<>width$.prec$} {field}")]
+ struct InterpolatedNamedGenericStructWidthPrecision<T> {
+ field: T,
+ width: usize,
+ prec: usize,
+ }
+ #[test]
+ fn interpolated_named_generic_struct_width_precision() {
+ assert_eq!(
+ InterpolatedNamedGenericStructWidthPrecision {
+ field: 1.2345,
+ width: 9,
+ prec: 2,
+ }
+ .to_string(),
+ "Generic <<<<<1.23 1.2345",
+ );
+ }
+
+ #[derive(Display)]
+ struct AutoNamedGenericStruct<T> {
+ field: T,
+ }
+ #[test]
+ fn auto_named_generic_struct() {
+ assert_eq!(AutoNamedGenericStruct { field: 1 }.to_string(), "1");
+ }
+
+ #[derive(Display)]
+ #[display("{alias}", alias = field)]
+ struct AliasedNamedGenericStruct<T> {
+ field: T,
+ }
+ #[test]
+ fn aliased_named_generic_struct() {
+ assert_eq!(AliasedNamedGenericStruct { field: 1 }.to_string(), "1");
+ }
+
+ #[derive(Display)]
+ #[display("{field1}", field1 = field2)]
+ struct AliasedFieldNamedGenericStruct<T> {
+ field1: T,
+ field2: i32,
+ }
+ #[test]
+ fn aliased_field_named_generic_struct() {
+ assert_eq!(
+ AliasedFieldNamedGenericStruct {
+ field1: (),
+ field2: 1,
+ }
+ .to_string(),
+ "1",
+ );
+ }
+
+ #[derive(Display)]
+ #[display("Generic {}", _0)]
+ struct UnnamedGenericStruct<T>(T);
+ #[test]
+ fn unnamed_generic_struct() {
+ assert_eq!(UnnamedGenericStruct(2).to_string(), "Generic 2");
+ }
+
+ #[derive(Display)]
+ #[display("Generic {_0}")]
+ struct InterpolatedUnnamedGenericStruct<T>(T);
+ #[test]
+ fn interpolated_unnamed_generic_struct() {
+ assert_eq!(InterpolatedUnnamedGenericStruct(2).to_string(), "Generic 2");
+ }
+
+ #[derive(Display)]
+ struct AutoUnnamedGenericStruct<T>(T);
+ #[test]
+ fn auto_unnamed_generic_struct() {
+ assert_eq!(AutoUnnamedGenericStruct(2).to_string(), "2");
+ }
+
+ #[derive(Display)]
+ #[display("{alias}", alias = _0)]
+ struct AliasedUnnamedGenericStruct<T>(T);
+ #[test]
+ fn aliased_unnamed_generic_struct() {
+ assert_eq!(AliasedUnnamedGenericStruct(2).to_string(), "2");
+ }
+
+ #[derive(Display)]
+ #[display("{_0}", _0 = _1)]
+ struct AliasedFieldUnnamedGenericStruct<T>(T, i32);
+ #[test]
+ fn aliased_field_unnamed_generic_struct() {
+ assert_eq!(AliasedFieldUnnamedGenericStruct((), 2).to_string(), "2");
+ }
+
+ #[derive(Display)]
+ enum GenericEnum<A, B> {
+ #[display("Gen::A {}", field)]
+ A { field: A },
+ #[display("Gen::B {}", _0)]
+ B(B),
+ }
+ #[test]
+ fn generic_enum() {
+ assert_eq!(GenericEnum::A::<_, u8> { field: 1 }.to_string(), "Gen::A 1");
+ assert_eq!(GenericEnum::B::<u8, _>(2).to_string(), "Gen::B 2");
+ }
+
+ #[derive(Display)]
+ enum InterpolatedGenericEnum<A, B> {
+ #[display("Gen::A {field}")]
+ A { field: A },
+ #[display("Gen::B {_0}")]
+ B(B),
+ }
+ #[test]
+ fn interpolated_generic_enum() {
+ assert_eq!(
+ InterpolatedGenericEnum::A::<_, u8> { field: 1 }.to_string(),
+ "Gen::A 1",
+ );
+ assert_eq!(
+ InterpolatedGenericEnum::B::<u8, _>(2).to_string(),
+ "Gen::B 2",
+ );
+ }
+
+ #[derive(Display)]
+ enum AutoGenericEnum<A, B> {
+ A { field: A },
+ B(B),
+ }
+ #[test]
+ fn auto_generic_enum() {
+ assert_eq!(AutoGenericEnum::A::<_, u8> { field: 1 }.to_string(), "1");
+ assert_eq!(AutoGenericEnum::B::<u8, _>(2).to_string(), "2");
+ }
+
+ #[derive(Display)]
+ #[display("{} {} <-> {0:o} {1:#x} <-> {0:?} {1:X?}", a, b)]
+ struct MultiTraitNamedGenericStruct<A, B> {
+ a: A,
+ b: B,
+ }
+ #[test]
+ fn multi_trait_named_generic_struct() {
+ let s = MultiTraitNamedGenericStruct { a: 8u8, b: 255 };
+ assert_eq!(s.to_string(), "8 255 <-> 10 0xff <-> 8 FF");
+ }
+
+ #[derive(Display)]
+ #[display("{} {b} <-> {0:o} {1:#x} <-> {0:?} {1:X?}", a, b)]
+ struct InterpolatedMultiTraitNamedGenericStruct<A, B> {
+ a: A,
+ b: B,
+ }
+ #[test]
+ fn interpolated_multi_trait_named_generic_struct() {
+ let s = InterpolatedMultiTraitNamedGenericStruct { a: 8u8, b: 255 };
+ assert_eq!(s.to_string(), "8 255 <-> 10 0xff <-> 8 FF");
+ }
+
+ #[derive(Display)]
+ #[display("{} {} {{}} {0:o} {1:#x} - {0:>4?} {1:^4X?}", _0, _1)]
+ struct MultiTraitUnnamedGenericStruct<A, B>(A, B);
+ #[test]
+ fn multi_trait_unnamed_generic_struct() {
+ let s = MultiTraitUnnamedGenericStruct(8u8, 255);
+ assert_eq!(s.to_string(), "8 255 {} 10 0xff - 8 FF ");
+ }
+
+ #[derive(Display)]
+ #[display("{} {_1} {{}} {0:o} {1:#x} - {0:>4?} {1:^4X?}", _0, _1)]
+ struct InterpolatedMultiTraitUnnamedGenericStruct<A, B>(A, B);
+ #[test]
+ fn interpolated_multi_trait_unnamed_generic_struct() {
+ let s = InterpolatedMultiTraitUnnamedGenericStruct(8u8, 255);
+ assert_eq!(s.to_string(), "8 255 {} 10 0xff - 8 FF ");
+ }
+
+ #[derive(Display)]
+ #[display("{}", 3 * 4)]
+ struct UnusedGenericStruct<T>(T);
+ #[test]
+ fn unused_generic_struct() {
+ let s = UnusedGenericStruct(());
+ assert_eq!(s.to_string(), "12");
+ }
+
+ mod associated_type_field_enumerator {
+ use super::*;
+
+ trait Trait {
+ type Type;
+ }
+
+ struct Struct;
+
+ impl Trait for Struct {
+ type Type = i32;
+ }
+
+ #[test]
+ fn auto_generic_named_struct_associated() {
+ #[derive(Display)]
+ struct AutoGenericNamedStructAssociated<T: Trait> {
+ field: <T as Trait>::Type,
+ }
+
+ let s = AutoGenericNamedStructAssociated::<Struct> { field: 10 };
+ assert_eq!(s.to_string(), "10");
+ }
+
+ #[test]
+ fn auto_generic_unnamed_struct_associated() {
+ #[derive(Display)]
+ struct AutoGenericUnnamedStructAssociated<T: Trait>(<T as Trait>::Type);
+
+ let s = AutoGenericUnnamedStructAssociated::<Struct>(10);
+ assert_eq!(s.to_string(), "10");
+ }
+
+ #[test]
+ fn auto_generic_enum_associated() {
+ #[derive(Display)]
+ enum AutoGenericEnumAssociated<T: Trait> {
+ Enumerator(<T as Trait>::Type),
+ }
+
+ let e = AutoGenericEnumAssociated::<Struct>::Enumerator(10);
+ assert_eq!(e.to_string(), "10");
+ }
+ }
+
+ mod complex_type_field_enumerator {
+ use super::*;
+
+ #[derive(Display)]
+ struct Struct<T>(T);
+
+ #[test]
+ fn auto_generic_named_struct_complex() {
+ #[derive(Display)]
+ struct AutoGenericNamedStructComplex<T> {
+ field: Struct<T>,
+ }
+
+ let s = AutoGenericNamedStructComplex { field: Struct(10) };
+ assert_eq!(s.to_string(), "10");
+ }
+
+ #[test]
+ fn auto_generic_unnamed_struct_complex() {
+ #[derive(Display)]
+ struct AutoGenericUnnamedStructComplex<T>(Struct<T>);
+
+ let s = AutoGenericUnnamedStructComplex(Struct(10));
+ assert_eq!(s.to_string(), "10");
+ }
+
+ #[test]
+ fn auto_generic_enum_complex() {
+ #[derive(Display)]
+ enum AutoGenericEnumComplex<T> {
+ Enumerator(Struct<T>),
+ }
+
+ let e = AutoGenericEnumComplex::Enumerator(Struct(10));
+ assert_eq!(e.to_string(), "10")
+ }
+ }
+
+ mod reference {
+ use super::*;
+
+ #[test]
+ fn auto_generic_reference() {
+ #[derive(Display)]
+ struct AutoGenericReference<'a, T>(&'a T);
+
+ let s = AutoGenericReference(&10);
+ assert_eq!(s.to_string(), "10");
+ }
+
+ #[test]
+ fn auto_generic_static_reference() {
+ #[derive(Display)]
+ struct AutoGenericStaticReference<T: 'static>(&'static T);
+
+ let s = AutoGenericStaticReference(&10);
+ assert_eq!(s.to_string(), "10");
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Display)]
+ struct Struct<T>(T);
+
+ #[test]
+ fn auto_generic_indirect() {
+ #[derive(Display)]
+ struct AutoGenericIndirect<T: 'static>(Struct<&'static T>);
+
+ const V: i32 = 10;
+ let s = AutoGenericIndirect(Struct(&V));
+ assert_eq!(s.to_string(), "10");
+ }
+ }
+
+ mod bound {
+ use super::*;
+
+ #[test]
+ fn simple() {
+ #[derive(Display)]
+ #[display("{} {}", _0, _1)]
+ struct Struct<T1, T2>(T1, T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(s.to_string(), "10 20");
+ }
+
+ #[test]
+ fn underscored_simple() {
+ #[derive(Display)]
+ #[display("{_0} {_1}")]
+ struct Struct<T1, T2>(T1, T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(s.to_string(), "10 20");
+ }
+
+ #[test]
+ fn redundant() {
+ #[derive(Display)]
+ #[display(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Display))]
+ #[display("{} {}", _0, _1)]
+ struct Struct<T1, T2>(T1, T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(s.to_string(), "10 20");
+ }
+
+ #[test]
+ fn underscored_redundant() {
+ #[derive(Display)]
+ #[display(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Display))]
+ #[display("{_0} {_1}")]
+ struct Struct<T1, T2>(T1, T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(s.to_string(), "10 20");
+ }
+
+ #[test]
+ fn complex() {
+ trait Trait1 {
+ fn function1(&self) -> &'static str;
+ }
+
+ trait Trait2 {
+ fn function2(&self) -> &'static str;
+ }
+
+ impl Trait1 for i32 {
+ fn function1(&self) -> &'static str {
+ "WHAT"
+ }
+ }
+
+ impl Trait2 for i32 {
+ fn function2(&self) -> &'static str {
+ "EVER"
+ }
+ }
+
+ #[derive(Display)]
+ #[display(bound(T1: Trait1 + Trait2, T2: Trait1 + Trait2))]
+ #[display("{} {} {} {}", _0.function1(), _0, _1.function2(), _1)]
+ struct Struct<T1, T2>(T1, T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(s.to_string(), "WHAT 10 EVER 20");
+ }
+
+ #[test]
+ fn underscored_complex() {
+ trait Trait1 {
+ fn function1(&self) -> &'static str;
+ }
+
+ trait Trait2 {
+ fn function2(&self) -> &'static str;
+ }
+
+ impl Trait1 for i32 {
+ fn function1(&self) -> &'static str {
+ "WHAT"
+ }
+ }
+
+ impl Trait2 for i32 {
+ fn function2(&self) -> &'static str {
+ "EVER"
+ }
+ }
+
+ #[derive(Display)]
+ #[display(bound(T1: Trait1 + Trait2, T2: Trait1 + Trait2))]
+ #[display("{} {_0} {} {_1}", _0.function1(), _1.function2())]
+ struct Struct<T1, T2>(T1, T2);
+
+ let s = Struct(10, 20);
+ assert_eq!(s.to_string(), "WHAT 10 EVER 20");
+ }
+ }
+}
diff --git a/third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs
new file mode 100644
index 0000000000..d8e5db7d7b
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs
@@ -0,0 +1,267 @@
+#![allow(dead_code)]
+use super::*;
+
+derive_display!(TestErr);
+#[derive(Debug, Error)]
+enum TestErr {
+ Unit,
+ NamedImplicitNoSource {
+ field: i32,
+ },
+ NamedImplicitSource {
+ source: SimpleErr,
+ field: i32,
+ },
+ #[cfg(feature = "std")]
+ NamedImplicitBoxedSource {
+ source: Box<dyn Error + Send + 'static>,
+ field: i32,
+ },
+ NamedExplicitNoSource {
+ #[error(not(source))]
+ source: SimpleErr,
+ field: i32,
+ },
+ NamedExplicitSource {
+ #[error(source)]
+ explicit_source: SimpleErr,
+ field: i32,
+ },
+ NamedExplicitNoSourceRedundant {
+ #[error(not(source))]
+ field: i32,
+ },
+ NamedExplicitSourceRedundant {
+ #[error(source)]
+ source: SimpleErr,
+ field: i32,
+ },
+ NamedExplicitSuppressesImplicit {
+ source: i32,
+ #[error(source)]
+ field: SimpleErr,
+ },
+ UnnamedImplicitNoSource(i32, i32),
+ UnnamedImplicitSource(SimpleErr),
+ UnnamedExplicitNoSource(#[error(not(source))] SimpleErr),
+ UnnamedExplicitSource(#[error(source)] SimpleErr, i32),
+ UnnamedExplicitNoSourceRedundant(
+ #[error(not(source))] i32,
+ #[error(not(source))] i32,
+ ),
+ UnnamedExplicitSourceRedundant(#[error(source)] SimpleErr),
+ NamedIgnore {
+ #[error(ignore)]
+ source: SimpleErr,
+ field: i32,
+ },
+ UnnamedIgnore(#[error(ignore)] SimpleErr),
+ NamedIgnoreRedundant {
+ #[error(ignore)]
+ field: i32,
+ },
+ UnnamedIgnoreRedundant(#[error(ignore)] i32, #[error(ignore)] i32),
+ #[error(ignore)]
+ NamedVariantIgnore {
+ source: SimpleErr,
+ field: i32,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnore(SimpleErr),
+ #[error(ignore)]
+ NamedVariantIgnoreRedundant {
+ field: i32,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnoreRedundant(i32, i32),
+}
+
+#[test]
+fn unit() {
+ assert!(TestErr::Unit.source().is_none());
+}
+
+#[test]
+fn named_implicit_no_source() {
+ let err = TestErr::NamedImplicitNoSource { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ let err = TestErr::NamedImplicitSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[cfg(feature = "std")]
+#[test]
+fn named_implicit_boxed_source() {
+ let err = TestErr::NamedImplicitBoxedSource {
+ source: Box::new(SimpleErr),
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ let err = TestErr::NamedExplicitNoSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ let err = TestErr::NamedExplicitSource {
+ explicit_source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ let err = TestErr::NamedExplicitNoSourceRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ let err = TestErr::NamedExplicitSourceRedundant {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ let err = TestErr::NamedExplicitSuppressesImplicit {
+ source: 0,
+ field: SimpleErr,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ assert!(TestErr::UnnamedImplicitNoSource(0, 0).source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ let err = TestErr::UnnamedImplicitSource(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ let err = TestErr::UnnamedExplicitNoSource(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ let err = TestErr::UnnamedExplicitSource(SimpleErr, 0);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ let err = TestErr::UnnamedExplicitNoSourceRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ let err = TestErr::UnnamedExplicitSourceRedundant(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ let err = TestErr::NamedIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ let err = TestErr::UnnamedIgnore(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ let err = TestErr::NamedIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ let err = TestErr::UnnamedIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_variant_ignore() {
+ let err = TestErr::NamedVariantIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore() {
+ let err = TestErr::UnnamedVariantIgnore(SimpleErr);
+
+ assert!(err.source().is_none())
+}
+
+#[test]
+fn named_variant_ignore_redundant() {
+ let err = TestErr::NamedVariantIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore_redundant() {
+ let err = TestErr::UnnamedVariantIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs
new file mode 100644
index 0000000000..8a7d42de8b
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs
@@ -0,0 +1,249 @@
+#![allow(dead_code)]
+use super::*;
+
+derive_display!(TestErr, T, E);
+#[derive(Debug, Error)]
+enum TestErr<E, T> {
+ Unit,
+ NamedImplicitNoSource {
+ field: T,
+ },
+ NamedImplicitSource {
+ source: E,
+ field: T,
+ },
+ NamedExplicitNoSource {
+ #[error(not(source))]
+ source: E,
+ field: T,
+ },
+ NamedExplicitSource {
+ #[error(source)]
+ explicit_source: E,
+ field: T,
+ },
+ NamedExplicitNoSourceRedundant {
+ #[error(not(source))]
+ field: T,
+ },
+ NamedExplicitSourceRedundant {
+ #[error(source)]
+ source: E,
+ field: T,
+ },
+ NamedExplicitSuppressesImplicit {
+ source: T,
+ #[error(source)]
+ field: E,
+ },
+ UnnamedImplicitNoSource(T, T),
+ UnnamedImplicitSource(E),
+ UnnamedExplicitNoSource(#[error(not(source))] E),
+ UnnamedExplicitSource(#[error(source)] E, T),
+ UnnamedExplicitNoSourceRedundant(#[error(not(source))] T, #[error(not(source))] T),
+ UnnamedExplicitSourceRedundant(#[error(source)] E),
+ NamedIgnore {
+ #[error(ignore)]
+ source: E,
+ field: T,
+ },
+ UnnamedIgnore(#[error(ignore)] E),
+ NamedIgnoreRedundant {
+ #[error(ignore)]
+ field: T,
+ },
+ UnnamedIgnoreRedundant(#[error(ignore)] T, #[error(ignore)] T),
+ #[error(ignore)]
+ NamedVariantIgnore {
+ source: E,
+ field: T,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnore(E),
+ #[error(ignore)]
+ NamedVariantIgnoreRedundant {
+ field: T,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnoreRedundant(T, T),
+}
+
+#[test]
+fn unit() {
+ assert!(TestErr::<SimpleErr, i32>::Unit.source().is_none());
+}
+
+#[test]
+fn named_implicit_no_source() {
+ let err = TestErr::<SimpleErr, _>::NamedImplicitNoSource { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ let err = TestErr::NamedImplicitSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ let err = TestErr::NamedExplicitNoSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ let err = TestErr::NamedExplicitSource {
+ explicit_source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ let err = TestErr::<SimpleErr, _>::NamedExplicitNoSourceRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ let err = TestErr::NamedExplicitSourceRedundant {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ let err = TestErr::NamedExplicitSuppressesImplicit {
+ source: 0,
+ field: SimpleErr,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ let err = TestErr::<SimpleErr, _>::UnnamedImplicitNoSource(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ let err = TestErr::<_, i32>::UnnamedImplicitSource(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ let err = TestErr::<_, i32>::UnnamedExplicitNoSource(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ let err = TestErr::UnnamedExplicitSource(SimpleErr, 0);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ let err = TestErr::<SimpleErr, _>::UnnamedExplicitNoSourceRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ let err = TestErr::<_, i32>::UnnamedExplicitSourceRedundant(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ let err = TestErr::NamedIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ let err = TestErr::<_, i32>::UnnamedIgnore(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::NamedIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::UnnamedIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_variant_ignore() {
+ let err = TestErr::NamedVariantIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore() {
+ let err = TestErr::<_, i32>::UnnamedVariantIgnore(SimpleErr);
+
+ assert!(err.source().is_none())
+}
+
+#[test]
+fn named_variant_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::NamedVariantIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::UnnamedVariantIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs
new file mode 100644
index 0000000000..65a1ca24fe
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs
@@ -0,0 +1,246 @@
+#![allow(dead_code)]
+use super::*;
+
+#[test]
+fn named_implicit_no_source() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(not(source))]
+ source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(source)]
+ explicit_source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(source))]
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(source)]
+ source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ source: E,
+ #[error(source)]
+ field: T,
+ }
+
+ let err = TestErr::<i32, SimpleErr>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(T, T);
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(E);
+
+ let err = TestErr::<SimpleErr>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(#[error(not(source))] E);
+
+ assert!(TestErr::<SimpleErr>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T>(#[error(source)] E, T);
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(#[error(not(source))] T, #[error(not(source))] T);
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(#[error(source)] E);
+
+ let err = TestErr::<SimpleErr>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(ignore)]
+ source: E,
+ field: T,
+ }
+
+ assert!(TestErr::<SimpleErr, i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(#[error(ignore)] E);
+
+ assert!(TestErr::<SimpleErr>::default().source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ #[error(ignore)]
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(#[error(ignore)] T, #[error(ignore)] T);
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn named_struct_ignore() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<E, T> {
+ source: E,
+ field: T,
+ }
+
+ assert!(TestErr::<SimpleErr, i32>::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<E>(E);
+
+ assert!(TestErr::<SimpleErr>::default().source().is_none())
+}
+
+#[test]
+fn named_struct_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<T> {
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<T>(T, T);
+
+ assert!(TestErr::<i32>::default().source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs
new file mode 100644
index 0000000000..c2b28a8271
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs
@@ -0,0 +1,250 @@
+#![allow(dead_code)]
+use super::*;
+
+#[test]
+fn unit() {
+ assert!(SimpleErr.source().is_none());
+}
+
+#[test]
+fn named_implicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ source: SimpleErr,
+ field: i32,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(not(source))]
+ source: SimpleErr,
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(source)]
+ explicit_source: SimpleErr,
+ field: i32,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(not(source))]
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(source)]
+ source: SimpleErr,
+ field: i32,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ source: i32,
+ #[error(source)]
+ field: SimpleErr,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(i32, i32);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(SimpleErr);
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(not(source))] SimpleErr);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(source)] SimpleErr, i32);
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(not(source))] i32, #[error(not(source))] i32);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(source)] SimpleErr);
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(ignore)]
+ source: SimpleErr,
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(ignore)] SimpleErr);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(ignore)]
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(ignore)] i32, #[error(ignore)] i32);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_struct_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr {
+ source: SimpleErr,
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr(SimpleErr);
+
+ assert!(TestErr::default().source().is_none())
+}
+
+#[test]
+fn named_struct_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr {
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr(i32, i32);
+
+ assert!(TestErr::default().source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/mod.rs b/third_party/rust/derive_more/tests/error/mod.rs
new file mode 100644
index 0000000000..352d40aa53
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/mod.rs
@@ -0,0 +1,56 @@
+use derive_more::Error;
+
+/// Derives `std::fmt::Display` for structs/enums.
+/// Derived implementation outputs empty string.
+/// Useful, as a way to formally satisfy `Display` trait bound.
+///
+/// ## Syntax:
+///
+/// For regular structs/enums:
+///
+/// ```
+/// enum MyEnum {
+/// ...
+/// }
+///
+/// derive_display!(MyEnum);
+/// ```
+///
+/// For generic structs/enums:
+///
+/// ```
+/// struct MyGenericStruct<T, U> {
+/// ...
+/// }
+///
+/// derive_display!(MyGenericStruct, T, U);
+/// ```
+macro_rules! derive_display {
+ (@fmt) => {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ write!(f, "")
+ }
+ };
+ ($type:ident) => {
+ impl ::core::fmt::Display for $type {
+ derive_display!(@fmt);
+ }
+ };
+ ($type:ident, $($type_parameters:ident),*) => {
+ impl<$($type_parameters),*> ::core::fmt::Display for $type<$($type_parameters),*> {
+ derive_display!(@fmt);
+ }
+ };
+}
+
+mod derives_for_enums_with_source;
+mod derives_for_generic_enums_with_source;
+mod derives_for_generic_structs_with_source;
+mod derives_for_structs_with_source;
+
+#[cfg(all(feature = "std", nightly))]
+mod nightly;
+
+derive_display!(SimpleErr);
+#[derive(Default, Debug, Error)]
+struct SimpleErr;
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs
new file mode 100644
index 0000000000..ca1a11b909
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs
@@ -0,0 +1,470 @@
+#![allow(dead_code)]
+
+use std::any;
+
+use super::*;
+
+derive_display!(TestErr);
+#[derive(Debug, Error)]
+enum TestErr {
+ Unit,
+ NamedImplicitNoBacktrace {
+ field: i32,
+ },
+ NamedImplicitBacktraceByFieldName {
+ backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace,
+ field: i32,
+ },
+ NamedExplicitNoBacktraceByFieldName {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedExplicitNoBacktraceByFieldType {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ },
+ NamedExplicitBacktrace {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedExplicitNoBacktraceRedundant {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: i32,
+ },
+ NamedExplicitBacktraceByFieldNameRedundant {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedExplicitBacktraceByFieldTypeRedundant {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ },
+ NamedExplicitSuppressesImplicit {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: i32,
+ },
+ NamedImplicitNoBacktraceFromSource {
+ #[error(source)]
+ err: BacktraceErr,
+ },
+ NamedExplicitNoBacktraceFromSource {
+ #[error(source, not(backtrace))]
+ err: BacktraceErr,
+ },
+ NamedExplicitBacktraceFromSource {
+ #[error(backtrace, source)]
+ err: BacktraceErr,
+ },
+ NamedImplicitDifferentSourceAndBacktrace {
+ #[error(source)]
+ err: BacktraceErr,
+ backtrace: Backtrace,
+ },
+ NamedExplicitDifferentSourceAndBacktrace {
+ #[error(source)]
+ err: BacktraceErr,
+ #[error(backtrace)]
+ backtrace: Backtrace,
+ },
+ UnnamedImplicitNoBacktrace(i32, i32),
+ UnnamedImplicitBacktrace(Backtrace, i32, i32),
+ UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, i32),
+ UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, i32, i32),
+ UnnamedExplicitNoBacktraceRedundant(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] i32,
+ ),
+ UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, i32, i32),
+ UnnamedExplicitSuppressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, i32),
+ UnnamedImplicitNoBacktraceFromSource(BacktraceErr),
+ UnnamedExplicitNoBacktraceFromSource(#[error(not(backtrace))] BacktraceErr),
+ UnnamedExplicitBacktraceFromSource(#[error(backtrace)] BacktraceErr),
+ UnnamedImplicitDifferentSourceAndBacktrace(
+ #[error(source)] BacktraceErr,
+ Backtrace,
+ ),
+ UnnamedExplicitDifferentSourceAndBacktrace(
+ #[error(source)] BacktraceErr,
+ #[error(backtrace)] Backtrace,
+ ),
+}
+
+impl TestErr {
+ fn get_stored_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedImplicitBacktraceByFieldName { backtrace, .. }
+ | Self::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: backtrace,
+ ..
+ }
+ | Self::NamedExplicitBacktrace {
+ explicit_backtrace: backtrace,
+ ..
+ }
+ | Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. }
+ | Self::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace: backtrace,
+ ..
+ }
+ | Self::NamedExplicitSuppressesImplicit {
+ not_backtrace: backtrace,
+ ..
+ }
+ | Self::NamedImplicitDifferentSourceAndBacktrace { backtrace, .. }
+ | Self::NamedExplicitDifferentSourceAndBacktrace { backtrace, .. }
+ | Self::UnnamedImplicitBacktrace(backtrace, _, _)
+ | Self::UnnamedExplicitBacktrace(backtrace, _, _)
+ | Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _)
+ | Self::UnnamedExplicitSuppressesImplicit(backtrace, _, _)
+ | Self::UnnamedImplicitDifferentSourceAndBacktrace(_, backtrace)
+ | Self::UnnamedExplicitDifferentSourceAndBacktrace(_, backtrace) => {
+ backtrace
+ }
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+
+ fn get_unused_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedExplicitSuppressesImplicit { backtrace, .. } => backtrace,
+ Self::UnnamedExplicitSuppressesImplicit(_, backtrace, _) => backtrace,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+
+ fn get_source_backtrace(&self) -> &Backtrace {
+ any::request_ref(match self {
+ Self::NamedExplicitBacktraceFromSource { err }
+ | Self::NamedExplicitDifferentSourceAndBacktrace { err, .. }
+ | Self::NamedImplicitDifferentSourceAndBacktrace { err, .. }
+ | Self::UnnamedExplicitBacktraceFromSource(err)
+ | Self::UnnamedExplicitDifferentSourceAndBacktrace(err, ..)
+ | Self::UnnamedImplicitDifferentSourceAndBacktrace(err, ..) => err,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ })
+ .unwrap()
+ }
+}
+
+type MyBacktrace = Backtrace;
+
+#[test]
+fn unit() {
+ assert!(any::request_ref::<Backtrace>(&TestErr::Unit).is_none());
+}
+
+#[test]
+fn named_implicit_no_backtrace() {
+ let err = TestErr::NamedImplicitNoBacktrace { field: 0 };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ let err = TestErr::NamedImplicitBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ let err = TestErr::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ let err = TestErr::NamedExplicitBacktrace {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ let err = TestErr::NamedExplicitNoBacktraceRedundant {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ let err = TestErr::NamedExplicitSuppressesImplicit {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
+
+#[test]
+fn named_implicit_no_backtrace_from_source() {
+ let err = TestErr::NamedImplicitNoBacktraceFromSource {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_from_source() {
+ let err = TestErr::NamedExplicitNoBacktraceFromSource {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_from_source() {
+ let err = TestErr::NamedExplicitBacktraceFromSource {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_source_backtrace);
+}
+
+#[test]
+fn named_implicit_different_source_and_backtrace() {
+ let err = TestErr::NamedImplicitDifferentSourceAndBacktrace {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
+
+#[test]
+fn named_explicit_different_source_and_backtrace() {
+ let err = TestErr::NamedExplicitDifferentSourceAndBacktrace {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ let err = TestErr::UnnamedImplicitNoBacktrace(0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_suppresses_implicit() {
+ let err = TestErr::UnnamedExplicitSuppressesImplicit(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace_from_source() {
+ let err = TestErr::UnnamedImplicitNoBacktraceFromSource(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_from_source() {
+ let err = TestErr::UnnamedExplicitNoBacktraceFromSource(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_from_source() {
+ let err = TestErr::UnnamedExplicitBacktraceFromSource(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_source_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_different_source_and_backtrace() {
+ let err = TestErr::UnnamedImplicitDifferentSourceAndBacktrace(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_different_source_and_backtrace() {
+ let err = TestErr::UnnamedExplicitDifferentSourceAndBacktrace(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs
new file mode 100644
index 0000000000..0d888fc760
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs
@@ -0,0 +1,479 @@
+#![allow(dead_code)]
+
+use std::any;
+
+use super::*;
+
+derive_display!(TestErr, T);
+#[derive(Debug, Error)]
+enum TestErr<T> {
+ Unit,
+ NamedImplicitNoBacktrace {
+ field: T,
+ },
+ NamedImplicitBacktraceByFieldName {
+ backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace,
+ field: T,
+ },
+ NamedExplicitNoBacktraceByFieldName {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedExplicitNoBacktraceByFieldType {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: T,
+ },
+ NamedExplicitBacktrace {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedExplicitNoBacktraceRedundant {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: T,
+ },
+ NamedExplicitBacktraceByFieldNameRedundant {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedExplicitBacktraceByFieldTypeRedundant {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: T,
+ },
+ NamedExplicitSuppressesImplicit {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: T,
+ },
+ UnnamedImplicitNoBacktrace(T, T),
+ UnnamedImplicitBacktrace(Backtrace, T, T),
+ UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, T),
+ UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, T, T),
+ UnnamedExplicitNoBacktraceRedundant(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] T,
+ ),
+ UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, T, T),
+ UnnamedExplicitSuppressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, T),
+}
+
+impl<T> TestErr<T> {
+ fn get_stored_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedImplicitBacktraceByFieldName { backtrace, .. } => backtrace,
+ Self::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace, ..
+ } => implicit_backtrace,
+ Self::NamedExplicitBacktrace {
+ explicit_backtrace, ..
+ } => explicit_backtrace,
+ Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. } => {
+ backtrace
+ }
+ Self::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace,
+ ..
+ } => implicit_backtrace,
+ Self::NamedExplicitSuppressesImplicit { not_backtrace, .. } => {
+ not_backtrace
+ }
+ Self::UnnamedImplicitBacktrace(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitBacktrace(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitSuppressesImplicit(backtrace, _, _) => backtrace,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+
+ fn get_unused_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedExplicitSuppressesImplicit { backtrace, .. } => backtrace,
+ Self::UnnamedExplicitSuppressesImplicit(_, backtrace, _) => backtrace,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+}
+
+type MyBacktrace = Backtrace;
+
+#[test]
+fn unit() {
+ assert!(any::request_ref::<Backtrace>(&TestErr::<i32>::Unit).is_none());
+}
+
+#[test]
+fn named_implicit_no_backtrace() {
+ let err = TestErr::NamedImplicitNoBacktrace { field: 0 };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ let err = TestErr::NamedImplicitBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ let err = TestErr::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ let err = TestErr::NamedExplicitBacktrace {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ let err = TestErr::NamedExplicitNoBacktraceRedundant {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ let err = TestErr::NamedExplicitSuppressesImplicit {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ let err = TestErr::UnnamedImplicitNoBacktrace(0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0);
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_suppresses_implicit() {
+ let err = TestErr::UnnamedExplicitSuppressesImplicit(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
+
+derive_display!(BoundedTestErr, T);
+#[derive(Debug, Error)]
+enum BoundedTestErr<T> {
+ NamedImplicitNoBacktraceFromSource {
+ #[error(source)]
+ err: T,
+ },
+ NamedExplicitNoBacktraceFromSource {
+ #[error(source, not(backtrace))]
+ err: T,
+ },
+ NamedExplicitBacktraceFromSource {
+ #[error(backtrace, source)]
+ err: T,
+ },
+ NamedImplicitDifferentSourceAndBacktrace {
+ #[error(source)]
+ err: T,
+ backtrace: Backtrace,
+ },
+ NamedExplicitDifferentSourceAndBacktrace {
+ #[error(source)]
+ err: T,
+ #[error(backtrace)]
+ backtrace: Backtrace,
+ },
+ UnnamedImplicitNoBacktraceFromSource(T),
+ UnnamedExplicitNoBacktraceFromSource(#[error(not(backtrace))] T),
+ UnnamedExplicitBacktraceFromSource(#[error(backtrace)] T),
+ UnnamedImplicitDifferentSourceAndBacktrace(#[error(source)] T, Backtrace),
+ UnnamedExplicitDifferentSourceAndBacktrace(
+ #[error(source)] T,
+ #[error(backtrace)] Backtrace,
+ ),
+}
+
+impl<T: Error> BoundedTestErr<T> {
+ fn get_stored_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedImplicitDifferentSourceAndBacktrace { backtrace, .. }
+ | Self::NamedExplicitDifferentSourceAndBacktrace { backtrace, .. }
+ | Self::UnnamedImplicitDifferentSourceAndBacktrace(_, backtrace)
+ | Self::UnnamedExplicitDifferentSourceAndBacktrace(_, backtrace) => {
+ backtrace
+ }
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+
+ fn get_source_backtrace(&self) -> &Backtrace {
+ any::request_ref(match self {
+ Self::NamedExplicitBacktraceFromSource { err }
+ | Self::NamedExplicitDifferentSourceAndBacktrace { err, .. }
+ | Self::NamedImplicitDifferentSourceAndBacktrace { err, .. }
+ | Self::UnnamedExplicitBacktraceFromSource(err)
+ | Self::UnnamedExplicitDifferentSourceAndBacktrace(err, ..)
+ | Self::UnnamedImplicitDifferentSourceAndBacktrace(err, ..) => err,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ })
+ .unwrap()
+ }
+}
+
+#[test]
+fn named_implicit_no_backtrace_from_source() {
+ let err = BoundedTestErr::NamedImplicitNoBacktraceFromSource {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_from_source() {
+ let err = BoundedTestErr::NamedExplicitNoBacktraceFromSource {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_from_source() {
+ let err = BoundedTestErr::NamedExplicitBacktraceFromSource {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_source_backtrace);
+}
+
+#[test]
+fn named_implicit_different_source_and_backtrace() {
+ let err = BoundedTestErr::NamedImplicitDifferentSourceAndBacktrace {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
+
+#[test]
+fn named_explicit_different_source_and_backtrace() {
+ let err = BoundedTestErr::NamedExplicitDifferentSourceAndBacktrace {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace_from_source() {
+ let err = BoundedTestErr::UnnamedImplicitNoBacktraceFromSource(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_from_source() {
+ let err = BoundedTestErr::UnnamedExplicitNoBacktraceFromSource(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_from_source() {
+ let err = BoundedTestErr::UnnamedExplicitBacktraceFromSource(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_source_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_different_source_and_backtrace() {
+ let err = BoundedTestErr::UnnamedImplicitDifferentSourceAndBacktrace(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_different_source_and_backtrace() {
+ let err = BoundedTestErr::UnnamedExplicitDifferentSourceAndBacktrace(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_source_backtrace);
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs
new file mode 100644
index 0000000000..d2f2c011dd
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs
@@ -0,0 +1,478 @@
+#![allow(dead_code)]
+
+use std::any;
+
+use super::*;
+
+#[test]
+fn named_implicit_no_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ field: T,
+ }
+
+ assert!(any::request_ref::<Backtrace>(&TestErr::<i32>::default()).is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ implicit_backtrace: Backtrace,
+ field: T,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(any::request_ref::<Backtrace>(&TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0
+ })
+ .is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: T,
+ }
+
+ assert!(any::request_ref::<Backtrace>(&TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0
+ })
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, explicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(any::request_ref::<Backtrace>(&TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0
+ })
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: T,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, not_backtrace);
+ assert_bt!(!=, err);
+}
+
+#[test]
+fn named_implicit_no_backtrace_from_source() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(source)]
+ err: T,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_from_source() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(source, not(backtrace))]
+ err: T,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_from_source() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace, source)]
+ err: T,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, any::request_ref::<Backtrace>(&err.err).unwrap());
+}
+
+#[test]
+fn named_implicit_different_source_and_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(source)]
+ err: T,
+ backtrace: Backtrace,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, backtrace);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.err).unwrap());
+}
+
+#[test]
+fn named_explicit_different_source_and_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(source)]
+ err: T,
+ #[error(backtrace)]
+ backtrace: Backtrace,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, backtrace);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.err).unwrap());
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(T, T);
+
+ assert!(any::request_ref::<Backtrace>(&TestErr::<i32>::default()).is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(Backtrace, T, T);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(not(backtrace))] Backtrace, T);
+
+ assert!(
+ any::request_ref::<Backtrace>(&TestErr(Backtrace::force_capture(), 0))
+ .is_none()
+ );
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(backtrace)] MyBacktrace, T, T);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] T,
+ );
+
+ type MyBacktrace = Backtrace;
+
+ assert!(
+ any::request_ref::<Backtrace>(&TestErr(Backtrace::force_capture(), 0))
+ .is_none()
+ );
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(backtrace)] Backtrace, T, T);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+}
+
+#[test]
+fn unnamed_explicit_suppresses_implicit() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(backtrace)] MyBacktrace, Backtrace, T);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+ assert_bt!(!=, err, .1);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace_from_source() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(T);
+
+ let err = TestErr(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_from_source() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(not(backtrace))] T);
+
+ let err = TestErr(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_from_source() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(backtrace)] T);
+
+ let err = TestErr(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, any::request_ref::<Backtrace>(&err.0).unwrap());
+}
+
+#[test]
+fn unnamed_implicit_different_source_and_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(source)] T, Backtrace);
+
+ let err = TestErr(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .1);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.0).unwrap());
+}
+
+#[test]
+fn unnamed_explicit_different_source_and_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(source)] T, #[error(backtrace)] Backtrace);
+
+ let err = TestErr(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .1);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.0).unwrap());
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs
new file mode 100644
index 0000000000..a262375999
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs
@@ -0,0 +1,483 @@
+#![allow(dead_code)]
+
+use std::any;
+
+use super::*;
+
+#[test]
+fn unit() {
+ assert!(any::request_ref::<Backtrace>(&SimpleErr).is_none());
+}
+
+#[test]
+fn named_implicit_no_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ field: i32,
+ }
+
+ assert!(any::request_ref::<Backtrace>(&TestErr::default()).is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ implicit_backtrace: Backtrace,
+ field: i32,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(any::request_ref::<Backtrace>(&TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0
+ })
+ .is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ }
+
+ assert!(any::request_ref::<Backtrace>(&TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0
+ })
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, explicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(any::request_ref::<Backtrace>(&TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0
+ })
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, not_backtrace);
+ assert_bt!(!=, err);
+}
+
+#[test]
+fn named_implicit_no_backtrace_from_source() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(source)]
+ err: BacktraceErr,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_from_source() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(source, not(backtrace))]
+ err: BacktraceErr,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_from_source() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace, source)]
+ err: BacktraceErr,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, any::request_ref::<Backtrace>(&err.err).unwrap());
+}
+
+#[test]
+fn named_implicit_different_source_and_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(source)]
+ err: BacktraceErr,
+ backtrace: Backtrace,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, backtrace);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.err).unwrap());
+}
+
+#[test]
+fn named_explicit_different_source_and_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(source)]
+ err: BacktraceErr,
+ #[error(backtrace)]
+ backtrace: Backtrace,
+ }
+
+ let err = TestErr {
+ err: BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ };
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, backtrace);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.err).unwrap());
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(i32, i32);
+
+ assert!(any::request_ref::<Backtrace>(&TestErr::default()).is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(Backtrace, i32, i32);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(not(backtrace))] Backtrace, i32);
+
+ assert!(
+ any::request_ref::<Backtrace>(&TestErr(Backtrace::force_capture(), 0))
+ .is_none()
+ );
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(backtrace)] MyBacktrace, i32, i32);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] i32,
+ );
+
+ type MyBacktrace = Backtrace;
+
+ assert!(
+ any::request_ref::<Backtrace>(&TestErr(Backtrace::force_capture(), 0))
+ .is_none()
+ );
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(backtrace)] Backtrace, i32, i32);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+}
+
+#[test]
+fn unnamed_explicit_suppresses_implicit() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(backtrace)] MyBacktrace, Backtrace, i32);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_bt!(==, err, .0);
+ assert_bt!(!=, err, .1);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace_from_source() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(BacktraceErr);
+
+ let err = TestErr(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_from_source() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(not(backtrace))] BacktraceErr);
+
+ let err = TestErr(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_none());
+ assert!(any::request_value::<i32>(&err).is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_from_source() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(backtrace)] BacktraceErr);
+
+ let err = TestErr(BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ });
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, any::request_ref::<Backtrace>(&err.0).unwrap());
+}
+
+#[test]
+fn unnamed_implicit_different_source_and_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(source)] BacktraceErr, Backtrace);
+
+ let err = TestErr(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .1);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.0).unwrap());
+}
+
+#[test]
+fn unnamed_explicit_different_source_and_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(source)] BacktraceErr, #[error(backtrace)] Backtrace);
+
+ let err = TestErr(
+ BacktraceErr {
+ backtrace: Backtrace::force_capture(),
+ },
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ );
+
+ assert!(err.source().is_some());
+ assert!(any::request_ref::<Backtrace>(&err).is_some());
+ assert_eq!(any::request_value::<i32>(&err), Some(42));
+ assert_bt!(==, err, .1);
+ assert_bt!(!=, err, any::request_ref::<Backtrace>(&err.0).unwrap());
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/mod.rs b/third_party/rust/derive_more/tests/error/nightly/mod.rs
new file mode 100644
index 0000000000..c9d432ff40
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/mod.rs
@@ -0,0 +1,93 @@
+use std::backtrace::Backtrace;
+
+use super::*;
+
+/// Asserts that backtrace returned by `Error::backtrace` method equals/not-equals
+/// backtrace stored in object itself.
+///
+/// Comparison is done by converting backtraces to strings
+/// and then comparing these strings.
+///
+/// ## Syntax
+///
+/// * Equals: `assert_bt!(==, ...)`
+/// * Not-equals: `assert_bt!(!=, ...)`
+///
+/// ### Backtrace Access
+///
+/// Shortcut for named-structs with `backtrace` field.
+/// Access backtrace as `error.backtrace`.
+///
+/// ```
+/// assert_bt!(==, error);
+/// ```
+///
+/// Full form for named- and tuple-structs.
+/// Access backtrace as `error.some_other_field` and `error.1` respectively.
+///
+/// ```
+/// assert_bt!(!=, error, some_other_field);
+/// assert_bt!(==, error, 1);
+/// ```
+///
+/// Access as a method call.
+/// Useful for enums (i.e., you can define a method that will match on enum variants
+/// and return backtrace for each variant).
+/// Access backtrace as `error.get_stored_backtrace_method()`.
+///
+/// ```
+/// assert_bt!(!=, error, .get_stored_backtrace_method);
+/// ```
+macro_rules! assert_bt {
+ (@impl $macro:ident, $error:expr, $backtrace:expr) => {
+ $macro!(std::any::request_ref::<Backtrace>(&$error).unwrap().to_string(), $backtrace.to_string());
+ };
+ (@expand $macro:ident, $error:expr, .$backtrace:ident) => {
+ assert_bt!(@impl $macro, $error, $error.$backtrace())
+ };
+ (@expand $macro:ident, $error:expr, .$backtrace:tt) => {
+ assert_bt!(@impl $macro, $error, $error.$backtrace)
+ };
+ (@expand $macro:ident, $error:expr, $backtrace:ident) => {
+ assert_bt!(@impl $macro, $error, $error.$backtrace)
+ };
+ (@expand $macro:ident, $error:expr, $backtrace:expr) => {
+ assert_bt!(@impl $macro, $error, $backtrace)
+ };
+ (@expand $macro:ident, $error:expr) => {
+ assert_bt!(@expand $macro, $error, backtrace)
+ };
+ (==, $($args:tt)*) => {
+ assert_bt!(@expand assert_eq, $($args)*)
+ };
+ (!=, $($args:tt)*) => {
+ assert_bt!(@expand assert_ne, $($args)*)
+ };
+}
+
+mod derives_for_enums_with_backtrace;
+mod derives_for_generic_enums_with_backtrace;
+mod derives_for_generic_structs_with_backtrace;
+mod derives_for_structs_with_backtrace;
+
+derive_display!(BacktraceErr);
+#[derive(Debug)]
+struct BacktraceErr {
+ backtrace: Backtrace,
+}
+
+impl Default for BacktraceErr {
+ fn default() -> Self {
+ Self {
+ backtrace: Backtrace::force_capture(),
+ }
+ }
+}
+
+impl Error for BacktraceErr {
+ fn provide<'a>(&'a self, demand: &mut std::any::Demand<'a>) {
+ demand
+ .provide_ref::<Backtrace>(&self.backtrace)
+ .provide_value::<i32>(42);
+ }
+}
diff --git a/third_party/rust/derive_more/tests/error_tests.rs b/third_party/rust/derive_more/tests/error_tests.rs
new file mode 100644
index 0000000000..28388ac078
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error_tests.rs
@@ -0,0 +1,5 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(nightly, feature(error_generic_member_access, provide_any))]
+#![cfg_attr(not(feature = "std"), feature(error_in_core))]
+
+mod error;
diff --git a/third_party/rust/derive_more/tests/from.rs b/third_party/rust/derive_more/tests/from.rs
new file mode 100644
index 0000000000..e43fa748c0
--- /dev/null
+++ b/third_party/rust/derive_more/tests/from.rs
@@ -0,0 +1,1791 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::{
+ borrow::Cow,
+ string::{String, ToString},
+};
+#[cfg(feature = "std")]
+use std::borrow::Cow;
+
+use derive_more::From;
+use static_assertions::assert_not_impl_any;
+
+mod structs {
+ use super::*;
+
+ mod unit {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Unit;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple();
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct {}
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unit, ().into());
+ assert_eq!(Tuple(), ().into());
+ assert_eq!(Struct {}, ().into());
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Unit<const N: usize>;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<const N: usize>();
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<const N: usize> {}
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unit::<1>, ().into());
+ assert_eq!(Tuple::<1>(), ().into());
+ assert_eq!(Struct::<1> {}, ().into());
+ }
+ }
+ }
+
+ mod single_field {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple(i32);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(42), 42.into());
+ assert_eq!(Struct { field: 42 }, 42.into());
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ #[from(i8)]
+ #[from(i16)]
+ struct Tuple(i32);
+
+ #[derive(Debug, From, PartialEq)]
+ #[from(&str, Cow<'_, str>)]
+ struct Struct {
+ field: String,
+ }
+
+ #[test]
+ fn assert() {
+ assert_not_impl_any!(Tuple: From<i32>);
+ assert_not_impl_any!(Struct: From<String>);
+
+ assert_eq!(Tuple(42), 42_i8.into());
+ assert_eq!(Tuple(42), 42_i16.into());
+ assert_eq!(
+ Struct {
+ field: "42".to_string(),
+ },
+ "42".into(),
+ );
+ assert_eq!(
+ Struct {
+ field: "42".to_string(),
+ },
+ Cow::Borrowed("42").into(),
+ );
+ }
+ }
+
+ mod forward {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ #[from(forward)]
+ struct Tuple(i32);
+
+ #[derive(Debug, From, PartialEq)]
+ #[from(forward)]
+ struct Struct {
+ field: String,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(42), 42_i8.into());
+ assert_eq!(Tuple(42), 42_i16.into());
+ assert_eq!(Tuple(42), 42_i32.into());
+ assert_eq!(
+ Struct {
+ field: "42".to_string(),
+ },
+ "42".into(),
+ );
+ assert_eq!(
+ Struct {
+ field: "42".to_string(),
+ },
+ Cow::Borrowed("42").into(),
+ );
+ }
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<T>(T);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<T> {
+ field: T,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(42), 42.into());
+ assert_eq!(Struct { field: 42 }, 42.into());
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<'a, T>(&'a T);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<'a, T> {
+ field: &'a T,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(&42), (&42).into());
+ assert_eq!(Struct { field: &42 }, (&42).into());
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<T: 'static>(&'static T);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<T: 'static> {
+ field: &'static T,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(&42), (&42).into());
+ assert_eq!(Struct { field: &42 }, (&42).into());
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<T: Clone>(T);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<T: Clone> {
+ field: T,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(42), 42.into());
+ assert_eq!(Struct { field: 42 }, 42.into());
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<const N: usize, T>(T);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<T, const N: usize> {
+ field: T,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::<1, _>(1), 1.into());
+ assert_eq!(Struct::<_, 1> { field: 1 }, 1.into());
+ }
+ }
+ }
+ }
+
+ mod multi_field {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple(i32, i16);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct {
+ field1: i32,
+ field2: i16,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(0, 1), (0, 1_i16).into());
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1,
+ },
+ (0, 1_i16).into(),
+ );
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ #[from((i16, i16))]
+ struct Tuple(i32, i16);
+
+ #[derive(Debug, From, PartialEq)]
+ #[from((i16, i16))]
+ struct Struct {
+ field1: i32,
+ field2: i16,
+ }
+
+ #[test]
+ fn assert() {
+ assert_not_impl_any!(Tuple: From<(i32, i16)>);
+ assert_not_impl_any!(Struct: From<(i32, i16)>);
+
+ assert_eq!(Tuple(0, 1), (0_i16, 1_i16).into());
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i16).into(),
+ );
+ }
+ }
+
+ mod forward {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ #[from(forward)]
+ struct Tuple(i32, i16);
+
+ #[derive(Debug, From, PartialEq)]
+ #[from(forward)]
+ struct Struct {
+ field1: i32,
+ field2: i16,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(0, 1), (0_i8, 1_i8).into());
+ assert_eq!(Tuple(0, 1), (0_i8, 1_i16).into());
+ assert_eq!(Tuple(0, 1), (0_i16, 1_i8).into());
+ assert_eq!(Tuple(0, 1), (0_i16, 1_i16).into());
+ assert_eq!(Tuple(0, 1), (0_i32, 1_i8).into());
+ assert_eq!(Tuple(0, 1), (0_i32, 1_i16).into());
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i8, 1_i8).into(),
+ );
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i8, 1_i16).into(),
+ );
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i8).into(),
+ );
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i16).into(),
+ );
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i32, 1_i8).into(),
+ );
+ assert_eq!(
+ Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i32, 1_i16).into(),
+ );
+ }
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<A, B>(A, B);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<A, B> {
+ field1: A,
+ field2: B,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(1, 2_i8), (1, 2_i8).into());
+ assert_eq!(
+ Struct {
+ field1: 1,
+ field2: 2_i8,
+ },
+ (1, 2_i8).into(),
+ );
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<'a, A, B>(&'a A, &'a B);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<'a, A, B> {
+ field1: &'a A,
+ field2: &'a B,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(&1, &2_i8), (&1, &2_i8).into());
+ assert_eq!(
+ Struct {
+ field1: &1,
+ field2: &2_i8,
+ },
+ (&1, &2_i8).into(),
+ );
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct Tuple<A: Clone, B>(A, B);
+
+ #[derive(Debug, From, PartialEq)]
+ struct Struct<A: Clone, B> {
+ field1: A,
+ field2: B,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple(1, 2_i8), (1, 2_i8).into());
+ assert_eq!(
+ Struct {
+ field1: 1,
+ field2: 2_i8,
+ },
+ (1, 2_i8).into(),
+ );
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ struct ConstTuple<const N: usize, A, B>(A, B);
+
+ #[derive(Debug, From, PartialEq)]
+ struct ConstStruct<const N: usize, A, B> {
+ field1: A,
+ field2: B,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(ConstTuple::<1, _, _>(1, 2_i8), (1, 2_i8).into());
+ assert_eq!(
+ ConstStruct::<1, _, _> {
+ field1: 1,
+ field2: 2_i8,
+ },
+ (1, 2_i8).into(),
+ );
+ }
+ }
+ }
+ }
+}
+
+mod enums {
+ use super::*;
+
+ mod unit_variant {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Enum {
+ #[from]
+ Unit,
+ Unnamed(),
+ Named {},
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::Unit, ().into());
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Unit {
+ Variant,
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple {
+ Variant(),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct {
+ Variant {},
+ }
+
+ assert_not_impl_any!(Unit: From<()>);
+ assert_not_impl_any!(Tuple: From<()>);
+ assert_not_impl_any!(Struct: From<()>);
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Unit<const N: usize> {
+ Variant,
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<const N: usize> {
+ Variant(),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<const N: usize> {
+ Variant {},
+ }
+
+ assert_not_impl_any!(Unit<0>: From<()>);
+ assert_not_impl_any!(Tuple<0>: From<()>);
+ assert_not_impl_any!(Struct<0>: From<()>);
+ }
+ }
+
+ mod from {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Unit {
+ #[from]
+ Variant,
+ AutomaticallySkipped,
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple {
+ #[from]
+ Variant(),
+ AutomaticallySkipped(),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct {
+ #[from]
+ Variant {},
+ AutomaticallySkipped {},
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unit::Variant, ().into());
+ assert_eq!(Tuple::Variant(), ().into());
+ assert_eq!(Struct::Variant {}, ().into());
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Unit<const N: usize> {
+ #[from]
+ Variant,
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<const N: usize> {
+ #[from]
+ Variant(),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<const N: usize> {
+ #[from]
+ Variant {},
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unit::<0>::Variant, ().into());
+ assert_eq!(Tuple::<0>::Variant(), ().into());
+ assert_eq!(Struct::<0>::Variant {}, ().into());
+ }
+ }
+ }
+ }
+
+ mod single_field_variant {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Enum {
+ Unnamed(i8),
+ Named { field: i16 },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::Unnamed(1), 1_i8.into());
+ assert_eq!(Enum::Named { field: 1 }, 1_i16.into());
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T> {
+ Variant(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T> {
+ Variant { field: T },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1), 1.into());
+ assert_eq!(Struct::Variant { field: 1 }, 1.into());
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<'a, T> {
+ Variant(&'a T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<'a, T> {
+ Variant { field: &'a T },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1), (&1).into());
+ assert_eq!(Struct::Variant { field: &1 }, (&1).into());
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T: 'static> {
+ Variant(&'static T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T: 'static> {
+ Variant { field: &'static T },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1), (&1).into());
+ assert_eq!(Struct::Variant { field: &1 }, (&1).into());
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T: Clone> {
+ Variant(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T: Clone> {
+ Variant { field: T },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1), 1.into());
+ assert_eq!(Struct::Variant { field: 1 }, 1.into());
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T, const N: usize> {
+ Variant(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<const N: usize, T> {
+ Variant { field: T },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<_, 1>(1), 1.into());
+ assert_eq!(Struct::Variant::<1, _> { field: 1 }, 1.into());
+ }
+ }
+ }
+
+ mod from {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple {
+ #[from]
+ Variant(i8),
+ AutomaticallySkipped(i8),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct {
+ #[from]
+ Variant {
+ field: i8,
+ },
+ AutomaticallySkipped {
+ field: i8,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1), 1_i8.into());
+ assert_eq!(Struct::Variant { field: 1 }, 1_i8.into());
+ }
+ }
+
+ mod skip {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Enum {
+ Unnamed(i8),
+ #[from(skip)]
+ UnnamedSkipped(i8),
+ Named {
+ field: i16,
+ },
+ #[from(skip)]
+ NamedSkipped {
+ field: i16,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::Unnamed(1), 1_i8.into());
+ assert_eq!(Enum::Named { field: 1 }, 1_i16.into());
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T> {
+ Variant(T),
+ #[from(skip)]
+ Skipped(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T> {
+ Variant {
+ field: T,
+ },
+ #[from(skip)]
+ Skipped {
+ field: T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1), 1.into());
+ assert_eq!(Struct::Variant { field: 1 }, 1.into());
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<'a, T> {
+ Variant(&'a T),
+ #[from(skip)]
+ Skipped(&'a T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<'a, T> {
+ Variant {
+ field: &'a T,
+ },
+ #[from(skip)]
+ Skipped {
+ field: &'a T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1), (&1).into());
+ assert_eq!(Struct::Variant { field: &1 }, (&1).into());
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T: 'static> {
+ Variant(&'static T),
+ #[from(skip)]
+ Skipped(&'static T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T: 'static> {
+ Variant {
+ field: &'static T,
+ },
+ #[from(skip)]
+ Skipped {
+ field: &'static T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1), (&1).into());
+ assert_eq!(Struct::Variant { field: &1 }, (&1).into());
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T: Clone> {
+ Variant(T),
+ #[from(skip)]
+ Skipped(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T: Clone> {
+ Variant {
+ field: T,
+ },
+ #[from(skip)]
+ Skipped {
+ field: T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1), 1.into());
+ assert_eq!(Struct::Variant { field: 1 }, 1.into());
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T, const N: usize> {
+ Variant(T),
+ #[from(skip)]
+ Skipped(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<const N: usize, T> {
+ Variant {
+ field: T,
+ },
+ #[from(skip)]
+ Skipped {
+ field: T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<_, 1>(1), 1.into());
+ assert_eq!(Struct::Variant::<1, _> { field: 1 }, 1.into());
+ }
+ }
+
+ mod concrete {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T> {
+ Variant(i32),
+ #[from(skip)]
+ Skipped(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T> {
+ Variant {
+ field: i32,
+ },
+ #[from(skip)]
+ Skipped {
+ field: T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<i32>(1), 1.into());
+ assert_eq!(Struct::Variant::<i32> { field: 1 }, 1.into());
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<'a, T> {
+ Variant(&'a i32),
+ #[from(skip)]
+ Skipped(&'a T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<'a, T> {
+ Variant {
+ field: &'a i32,
+ },
+ #[from(skip)]
+ Skipped {
+ field: &'a T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<i32>(&1), (&1).into());
+ assert_eq!(
+ Struct::Variant::<i32> { field: &1 },
+ (&1).into()
+ );
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T: 'static> {
+ Variant(&'static i32),
+ #[from(skip)]
+ Skipped(&'static T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T: 'static> {
+ Variant {
+ field: &'static i32,
+ },
+ #[from(skip)]
+ Skipped {
+ field: &'static T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<i32>(&1), (&1).into());
+ assert_eq!(
+ Struct::Variant::<i32> { field: &1 },
+ (&1).into()
+ );
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T: Clone> {
+ Variant(i32),
+ #[from(skip)]
+ Skipped(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<T: Clone> {
+ Variant {
+ field: i32,
+ },
+ #[from(skip)]
+ Skipped {
+ field: T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<i32>(1), 1.into());
+ assert_eq!(Struct::Variant::<i32> { field: 1 }, 1.into());
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<T, const N: usize> {
+ Variant(i32),
+ #[from(skip)]
+ Skipped(T),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<const N: usize, T> {
+ Variant {
+ field: i32,
+ },
+ #[from(skip)]
+ Skipped {
+ field: T,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<i32, 1>(1), 1.into());
+ assert_eq!(
+ Struct::Variant::<1, i32> { field: 1 },
+ 1.into()
+ );
+ }
+ }
+ }
+ }
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Enum {
+ #[from(i8)]
+ Unnamed(i16),
+ #[from(i16)]
+ Named {
+ field: i32,
+ },
+ AutomaticallySkipped(i32),
+ }
+
+ #[test]
+ fn assert() {
+ assert_not_impl_any!(Enum: From<i32>);
+ assert_eq!(Enum::Unnamed(1), 1_i8.into());
+ assert_eq!(Enum::Named { field: 1 }, 1_i16.into());
+ }
+ }
+
+ mod forward {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Unnamed {
+ #[from(forward)]
+ Variant(i32),
+ AutomaticallyIgnored(i32),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Named {
+ #[from(forward)]
+ Variant {
+ field: i32,
+ },
+ AutomaticallyIgnored {
+ field: i32,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unnamed::Variant(1), 1_i8.into());
+ assert_eq!(Unnamed::Variant(1), 1_i16.into());
+ assert_eq!(Unnamed::Variant(1), 1_i32.into());
+ assert_eq!(Named::Variant { field: 1 }, 1_i8.into());
+ assert_eq!(Named::Variant { field: 1 }, 1_i16.into());
+ assert_eq!(Named::Variant { field: 1 }, 1_i32.into());
+ }
+ }
+ }
+
+ mod multi_field_variant {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Enum {
+ Tuple(i8, i8),
+ Struct { field1: i16, field2: i16 },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::Tuple(0, 1), (0_i8, 1_i8).into());
+ assert_eq!(
+ Enum::Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i16).into(),
+ );
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A, B> {
+ Variant(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, B> {
+ Variant { field1: A, field2: B },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<'a, A, B> {
+ Variant(&'a A, &'a B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<'a, A, B> {
+ Variant { field1: &'a A, field2: &'a B },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: &1,
+ field2: &2_i16,
+ },
+ (&1, &2_i16).into(),
+ );
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A: 'static, B: 'static> {
+ Variant(&'static A, &'static B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A: 'static, B: 'static> {
+ Variant {
+ field1: &'static A,
+ field2: &'static B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: &1,
+ field2: &2_i16,
+ },
+ (&1, &2_i16).into(),
+ );
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A: Clone, B> {
+ Variant(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, B: Clone> {
+ Variant { field1: A, field2: B },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<const N: usize, A, B> {
+ Variant(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, const N: usize, B> {
+ Variant { field1: A, field2: B },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant::<0, _, _>(1, 2_i16), (1, 2_i16).into());
+ assert_eq!(
+ Struct::<_, 1, _>::Variant {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+ }
+ }
+
+ mod from {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple {
+ #[from]
+ Variant(i8, i16),
+ AutomaticallySkipped(i8, i16),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct {
+ #[from]
+ Variant {
+ field1: i8,
+ field2: i16,
+ },
+ AutomaticallySkipped {
+ field1: i8,
+ field2: i16,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1, 2), (1_i8, 2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: 1,
+ field2: 2,
+ },
+ (1_i8, 2_i16).into(),
+ );
+ }
+ }
+
+ mod skip {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Enum {
+ Tuple(i8, i8),
+ #[from(skip)]
+ TupleSkipped(i8, i8),
+ Struct {
+ field1: i16,
+ field2: i16,
+ },
+ #[from(skip)]
+ StructSkipped {
+ field1: i16,
+ field2: i16,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Enum::Tuple(0, 1), (0_i8, 1_i8).into());
+ assert_eq!(
+ Enum::Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i16).into(),
+ );
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A, B> {
+ Variant(A, B),
+ #[from(skip)]
+ Skipped(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, B> {
+ Variant {
+ field1: A,
+ field2: B,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: A,
+ field2: B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<'a, A, B> {
+ Variant(&'a A, &'a B),
+ #[from(skip)]
+ Skipped(&'a A, &'a B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<'a, A, B> {
+ Variant {
+ field1: &'a A,
+ field2: &'a B,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: &'a A,
+ field2: &'a B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: &1,
+ field2: &2_i16,
+ },
+ (&1, &2_i16).into(),
+ );
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A: 'static, B: 'static> {
+ Variant(&'static A, &'static B),
+ #[from(skip)]
+ Skipped(&'static A, &'static B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A: 'static, B: 'static> {
+ Variant {
+ field1: &'static A,
+ field2: &'static B,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: &'static A,
+ field2: &'static B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: &1,
+ field2: &2_i16,
+ },
+ (&1, &2_i16).into(),
+ );
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A: Clone, B> {
+ Variant(A, B),
+ #[from(skip)]
+ Skipped(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, B: Clone> {
+ Variant {
+ field1: A,
+ field2: B,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: A,
+ field2: B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into());
+ assert_eq!(
+ Struct::Variant {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<const N: usize, A, B> {
+ Variant(A, B),
+ #[from(skip)]
+ Skipped(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, const N: usize, B> {
+ Variant {
+ field1: A,
+ field2: B,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: A,
+ field2: B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ Tuple::Variant::<0, _, _>(1, 2_i16),
+ (1, 2_i16).into()
+ );
+ assert_eq!(
+ Struct::<_, 1, _>::Variant {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+ }
+
+ mod concrete {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A, B> {
+ Variant(i32, i16),
+ #[from(skip)]
+ Skipped(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, B> {
+ Variant {
+ field1: i32,
+ field2: i16,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: A,
+ field2: B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ Tuple::Variant::<i32, i16>(1, 2_i16),
+ (1, 2_i16).into(),
+ );
+ assert_eq!(
+ Struct::Variant::<i32, i16> {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+
+ mod reference {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<'a, A, B> {
+ Variant(&'a i32, &'a i16),
+ #[from(skip)]
+ Skipped(&'a A, &'a B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<'a, A, B> {
+ Variant {
+ field1: &'a i32,
+ field2: &'a i16,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: &'a A,
+ field2: &'a B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ Tuple::Variant::<i32, i16>(&1, &2_i16),
+ (&1, &2_i16).into(),
+ );
+ assert_eq!(
+ Struct::Variant::<i32, i16> {
+ field1: &1,
+ field2: &2_i16,
+ },
+ (&1, &2_i16).into(),
+ );
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A: 'static, B: 'static> {
+ Variant(&'static i32, &'static i16),
+ #[from(skip)]
+ Skipped(&'static A, &'static B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A: 'static, B: 'static> {
+ Variant {
+ field1: &'static i32,
+ field2: &'static i16,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: &'static A,
+ field2: &'static B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ Tuple::Variant::<i32, i16>(&1, &2_i16),
+ (&1, &2_i16).into(),
+ );
+ assert_eq!(
+ Struct::Variant::<i32, i16> {
+ field1: &1,
+ field2: &2_i16,
+ },
+ (&1, &2_i16).into(),
+ );
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<A: Clone, B> {
+ Variant(i32, i16),
+ #[from(skip)]
+ Skipped(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, B: Clone> {
+ Variant {
+ field1: i32,
+ field2: i16,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: A,
+ field2: B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ Tuple::Variant::<i32, i16>(1, 2_i16),
+ (1, 2_i16).into(),
+ );
+ assert_eq!(
+ Struct::Variant::<i32, i16> {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Tuple<const N: usize, A, B> {
+ Variant(i32, i16),
+ #[from(skip)]
+ Skipped(A, B),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Struct<A, const N: usize, B> {
+ Variant {
+ field1: i32,
+ field2: i16,
+ },
+ #[from(skip)]
+ Skipped {
+ field1: A,
+ field2: B,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ Tuple::Variant::<0, i32, i16>(1, 2_i16),
+ (1, 2_i16).into()
+ );
+ assert_eq!(
+ Struct::<i32, 1, i16>::Variant {
+ field1: 1,
+ field2: 2_i16,
+ },
+ (1, 2_i16).into(),
+ );
+ }
+ }
+ }
+ }
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Enum {
+ #[from((i8, i8))]
+ Tuple(i16, i16),
+ #[from((i16, i16))]
+ Struct {
+ field1: i32,
+ field2: i32,
+ },
+ AutomaticallySkipped {
+ field1: i32,
+ field2: i32,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_not_impl_any!(Enum: From<(i32, i32)>);
+ assert_eq!(Enum::Tuple(0, 1), (0_i8, 1_i8).into());
+ assert_eq!(
+ Enum::Struct {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i16).into(),
+ );
+ }
+ }
+
+ mod forward {
+ use super::*;
+
+ #[derive(Debug, From, PartialEq)]
+ enum Unnamed {
+ #[from(forward)]
+ Variant(i16, i16),
+ AutomaticallyIgnored(i16, i16),
+ }
+
+ #[derive(Debug, From, PartialEq)]
+ enum Named {
+ #[from(forward)]
+ Variant {
+ field1: i16,
+ field2: i16,
+ },
+ AutomaticallyIgnored {
+ field1: i16,
+ field2: i16,
+ },
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Unnamed::Variant(0, 1), (0_i8, 1_i8).into());
+ assert_eq!(Unnamed::Variant(0, 1), (0_i8, 1_i16).into());
+ assert_eq!(Unnamed::Variant(0, 1), (0_i16, 1_i8).into());
+ assert_eq!(Unnamed::Variant(0, 1), (0_i16, 1_i16).into());
+ assert_eq!(
+ Named::Variant {
+ field1: 0,
+ field2: 1
+ },
+ (0_i8, 1_i8).into(),
+ );
+ assert_eq!(
+ Named::Variant {
+ field1: 0,
+ field2: 1
+ },
+ (0_i8, 1_i16).into(),
+ );
+ assert_eq!(
+ Named::Variant {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i8).into(),
+ );
+ assert_eq!(
+ Named::Variant {
+ field1: 0,
+ field2: 1
+ },
+ (0_i16, 1_i16).into(),
+ );
+ }
+ }
+ }
+}
diff --git a/third_party/rust/derive_more/tests/from_str.rs b/third_party/rust/derive_more/tests/from_str.rs
new file mode 100644
index 0000000000..64f2848cbc
--- /dev/null
+++ b/third_party/rust/derive_more/tests/from_str.rs
@@ -0,0 +1,47 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::string::ToString;
+
+use derive_more::FromStr;
+
+#[derive(FromStr)]
+struct MyInt(i32);
+
+#[derive(FromStr)]
+struct Point1D {
+ x: i32,
+}
+
+#[derive(Debug, FromStr, PartialEq, Eq)]
+enum EnumNoFields {
+ Foo,
+ Bar,
+ Baz,
+ BaZ,
+}
+
+#[test]
+fn enum_test() {
+ assert_eq!("Foo".parse::<EnumNoFields>().unwrap(), EnumNoFields::Foo);
+ assert_eq!("FOO".parse::<EnumNoFields>().unwrap(), EnumNoFields::Foo);
+ assert_eq!("foo".parse::<EnumNoFields>().unwrap(), EnumNoFields::Foo);
+ assert_eq!(
+ "other".parse::<EnumNoFields>().unwrap_err().to_string(),
+ "Invalid `EnumNoFields` string representation",
+ );
+}
+
+#[test]
+fn enum_test_case_sensitive() {
+ assert_eq!("Baz".parse::<EnumNoFields>().unwrap(), EnumNoFields::Baz);
+ assert_eq!("BaZ".parse::<EnumNoFields>().unwrap(), EnumNoFields::BaZ);
+ assert_eq!(
+ "baz".parse::<EnumNoFields>().unwrap_err().to_string(),
+ "Invalid `EnumNoFields` string representation",
+ );
+}
diff --git a/third_party/rust/derive_more/tests/generics.rs b/third_party/rust/derive_more/tests/generics.rs
new file mode 100644
index 0000000000..039e8903ec
--- /dev/null
+++ b/third_party/rust/derive_more/tests/generics.rs
@@ -0,0 +1,264 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code, non_camel_case_types)]
+
+use derive_more::{
+ Add, AddAssign, Constructor, Deref, DerefMut, Display, Error, From, FromStr, Index,
+ IndexMut, IntoIterator, Mul, MulAssign, Not, Sum,
+};
+
+#[derive(
+ From,
+ FromStr,
+ Display,
+ Index,
+ Not,
+ Add,
+ Mul,
+ Sum,
+ IndexMut,
+ AddAssign,
+ MulAssign,
+ Deref,
+ DerefMut,
+ IntoIterator,
+ Constructor
+)]
+#[deref(forward)]
+#[deref_mut(forward)]
+#[into_iterator(owned, ref, ref_mut)]
+struct Wrapped<T: Clone>(T);
+
+#[derive(Deref, DerefMut)]
+struct Wrapped2<T: Clone>(T);
+
+#[derive(From, Not, Add, Mul, AddAssign, MulAssign, Constructor, Sum)]
+struct WrappedDouble<T: Clone, U: Clone>(T, U);
+
+#[derive(From)]
+#[from(forward)]
+struct WrappedDouble2<T: Clone, U: Clone>(T, U);
+
+#[cfg(nightly)]
+#[derive(
+ From,
+ FromStr,
+ Display,
+ Index,
+ Not,
+ Add,
+ Mul,
+ Sum,
+ IndexMut,
+ AddAssign,
+ MulAssign,
+ Deref,
+ DerefMut,
+ IntoIterator,
+ Constructor
+)]
+struct WrappedWithConst<T, const C: u32>(T);
+
+#[derive(
+ From,
+ FromStr,
+ Display,
+ Index,
+ Not,
+ Add,
+ Mul,
+ IndexMut,
+ AddAssign,
+ MulAssign,
+ Deref,
+ DerefMut,
+ IntoIterator,
+ Constructor,
+ Sum
+)]
+#[deref(forward)]
+#[deref_mut(forward)]
+#[into_iterator(owned, ref, ref_mut)]
+struct Struct1<T: Clone> {
+ t: T,
+}
+
+#[derive(Deref, DerefMut)]
+struct Struct2<T: Clone> {
+ t: T,
+}
+
+#[derive(From, Not, Add, Mul, AddAssign, MulAssign, Constructor, Sum)]
+struct DoubleStruct<T: Clone, U: Clone> {
+ t: T,
+ u: U,
+}
+
+#[derive(From)]
+#[from(forward)]
+struct DoubleStruct2<T: Clone, U: Clone> {
+ t: T,
+ u: U,
+}
+
+#[derive(From, Not, Add)]
+enum TupleEnum<T: Clone, U: Clone> {
+ Tuple(T),
+ DoubleTuple(T, U),
+}
+
+#[derive(From)]
+#[from(forward)]
+enum TupleEnum2<T: Clone, U: Clone, X: Clone> {
+ DoubleTuple(T, U),
+ TripleTuple(T, U, X),
+}
+
+#[derive(From, Not, Add)]
+enum StructEnum<T: Clone, U: Clone> {
+ Struct { t: T },
+ DoubleStruct { t: T, u: U },
+}
+
+#[derive(From)]
+#[from(forward)]
+enum StructEnum2<T: Clone, U: Clone, X: Clone> {
+ DoubleStruct { t: T, u: U },
+ TripleStruct { t: T, u: U, x: X },
+}
+
+#[derive(Debug, Display, Error)]
+enum Enum {}
+
+#[derive(Debug, Display, Error)]
+enum EnumGeneric<E> {
+ Inner(E),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumConst<const X: usize> {}
+
+#[derive(Debug, Display, Error)]
+enum EnumConstDefault<const X: usize = 42> {}
+
+#[derive(Debug, Display, Error)]
+enum EnumLifetime<'lt: 'static> {
+ Inner(&'lt Enum),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumConstGeneric<const X: usize, E> {
+ Inner(E),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumGenericConst<E, const X: usize> {
+ Inner(E),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumGenericConstDefault<E, const X: usize = 42> {
+ Inner(E),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumLifetimeGeneric<'lt: 'static, E> {
+ Inner(&'lt E),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumLifetimeConst<'lt: 'static, const X: usize> {
+ Inner(&'lt EnumConst<X>),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumLifetimeConstDefault<'lt: 'static, const X: usize = 42> {
+ Inner(&'lt EnumConst<X>),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumLifetimeConstGeneric<'lt: 'static, const X: usize, E> {
+ Inner(&'lt E),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumLifetimeGenericConst<'lt: 'static, E, const X: usize> {
+ Inner(&'lt E),
+}
+
+#[derive(Debug, Display, Error)]
+enum EnumLifetimeGenericConstDefault<'lt: 'static, E, const X: usize = 42> {
+ Inner(&'lt E),
+}
+
+#[derive(Debug, Display, Error)]
+struct Struct;
+
+#[derive(Debug, Display, Error)]
+struct StructGeneric<E> {
+ inner: E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructConst<const X: usize> {}
+
+#[derive(Debug, Display, Error)]
+struct StructConstDefault<const X: usize = 42> {}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetime<'lt: 'static> {
+ inner: &'lt Enum,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructConstGeneric<const X: usize, E> {
+ inner: E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructGenericConst<E, const X: usize> {
+ inner: E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructGenericConstDefault<E, const X: usize = 42> {
+ inner: E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetimeGeneric<'lt: 'static, E> {
+ inner: &'lt E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetimeConst<'lt: 'static, const X: usize> {
+ inner: &'lt EnumConst<X>,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetimeConstDefault<'lt: 'static, const X: usize = 42> {
+ inner: &'lt EnumConst<X>,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetimeConstGeneric<'lt: 'static, const X: usize, E> {
+ inner: &'lt E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetimeGenericConst<'lt: 'static, E, const X: usize> {
+ inner: &'lt E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetimeGenericConstDefault<'lt: 'static, E, const X: usize = 42> {
+ inner: &'lt E,
+}
+
+#[derive(Debug, Display, Error)]
+struct StructLifetimeGenericBoundsConstDefault<
+ 'lt: 'static,
+ E: Clone,
+ const X: usize = 42,
+> {
+ inner: &'lt E,
+}
diff --git a/third_party/rust/derive_more/tests/index.rs b/third_party/rust/derive_more/tests/index.rs
new file mode 100644
index 0000000000..b972388bcf
--- /dev/null
+++ b/third_party/rust/derive_more/tests/index.rs
@@ -0,0 +1,20 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code, unused_imports)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::vec::Vec;
+
+use derive_more::Index;
+
+#[derive(Index)]
+struct MyVec(Vec<i32>);
+
+#[derive(Index)]
+struct Numbers {
+ #[index]
+ numbers: Vec<i32>,
+ useless: bool,
+}
diff --git a/third_party/rust/derive_more/tests/index_mut.rs b/third_party/rust/derive_more/tests/index_mut.rs
new file mode 100644
index 0000000000..0aba15ad52
--- /dev/null
+++ b/third_party/rust/derive_more/tests/index_mut.rs
@@ -0,0 +1,36 @@
+#![allow(dead_code, unused_imports)]
+
+use derive_more::IndexMut;
+
+#[derive(IndexMut)]
+struct MyVec(Vec<i32>);
+//Index implementation is required for IndexMut
+impl<__IdxT> ::core::ops::Index<__IdxT> for MyVec
+where
+ Vec<i32>: ::core::ops::Index<__IdxT>,
+{
+ type Output = <Vec<i32> as ::core::ops::Index<__IdxT>>::Output;
+ #[inline]
+ fn index(&self, idx: __IdxT) -> &Self::Output {
+ <Vec<i32> as ::core::ops::Index<__IdxT>>::index(&self.0, idx)
+ }
+}
+
+#[derive(IndexMut)]
+struct Numbers {
+ #[index_mut]
+ numbers: Vec<i32>,
+ useless: bool,
+}
+
+//Index implementation is required for IndexMut
+impl<__IdxT> ::core::ops::Index<__IdxT> for Numbers
+where
+ Vec<i32>: ::core::ops::Index<__IdxT>,
+{
+ type Output = <Vec<i32> as ::core::ops::Index<__IdxT>>::Output;
+ #[inline]
+ fn index(&self, idx: __IdxT) -> &Self::Output {
+ <Vec<i32> as ::core::ops::Index<__IdxT>>::index(&self.numbers, idx)
+ }
+}
diff --git a/third_party/rust/derive_more/tests/into.rs b/third_party/rust/derive_more/tests/into.rs
new file mode 100644
index 0000000000..95799d2f26
--- /dev/null
+++ b/third_party/rust/derive_more/tests/into.rs
@@ -0,0 +1,1045 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::{
+ borrow::Cow,
+ borrow::ToOwned,
+ boxed::Box,
+ string::{String, ToString},
+};
+use core::mem;
+#[cfg(feature = "std")]
+use std::borrow::Cow;
+
+use derive_more::Into;
+use static_assertions::assert_not_impl_any;
+
+/// Nasty [`mem::transmute()`] that works in generic contexts
+/// by [`mem::forget`]ing stuff.
+///
+/// It's OK for tests!
+unsafe fn transmute<From, To>(from: From) -> To {
+ let to = unsafe { mem::transmute_copy(&from) };
+ mem::forget(from);
+ to
+}
+
+#[derive(Debug, PartialEq)]
+#[repr(transparent)]
+struct Wrapped<T>(T);
+
+#[derive(Debug, PartialEq)]
+#[repr(transparent)]
+struct Transmuted<T>(T);
+
+impl<T> From<Wrapped<T>> for Transmuted<T> {
+ fn from(from: Wrapped<T>) -> Self {
+ // SAFETY: repr(transparent)
+ unsafe { transmute(from) }
+ }
+}
+
+impl<T> From<&Wrapped<T>> for &Transmuted<T> {
+ fn from(from: &Wrapped<T>) -> Self {
+ // SAFETY: repr(transparent)
+ unsafe { transmute(from) }
+ }
+}
+
+impl<T> From<&mut Wrapped<T>> for &mut Transmuted<T> {
+ fn from(from: &mut Wrapped<T>) -> Self {
+ // SAFETY: repr(transparent)
+ unsafe { transmute(from) }
+ }
+}
+
+mod unit {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Unit;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple();
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct {}
+
+ #[test]
+ fn assert() {
+ assert_eq!((), Unit.into());
+ assert_eq!((), Tuple().into());
+ assert_eq!((), Struct {}.into());
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Unit<const N: usize>;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<const N: usize>();
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<const N: usize> {}
+
+ #[test]
+ fn assert() {
+ assert_eq!((), Unit::<1>.into());
+ assert_eq!((), Tuple::<1>().into());
+ assert_eq!((), Struct::<1> {}.into());
+ }
+ }
+}
+
+mod single_field {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple(i32);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(42, Tuple(42).into());
+ assert_eq!(42, Struct { field: 42 }.into());
+ }
+
+ mod skip {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple(#[into(skip)] i32);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct {
+ #[into(skip)]
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!((), Tuple(42).into());
+ assert_eq!((), Struct { field: 42 }.into());
+ }
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(i64)]
+ #[into(i128)]
+ struct Tuple(i32);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(Box<str>, Cow<'_, str>)]
+ struct Struct {
+ field: String,
+ }
+
+ #[test]
+ fn assert() {
+ assert_not_impl_any!(Tuple: Into<i32>);
+ assert_not_impl_any!(Struct: Into<String>);
+
+ assert_eq!(42_i64, Tuple(42).into());
+ assert_eq!(42_i128, Tuple(42).into());
+ assert_eq!(
+ Box::<str>::from("42".to_owned()),
+ Struct {
+ field: "42".to_string(),
+ }
+ .into(),
+ );
+ assert_eq!(
+ Cow::Borrowed("42"),
+ Cow::<str>::from(Struct {
+ field: "42".to_string(),
+ }),
+ );
+ }
+
+ mod ref_ {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Unnamed(i32);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Named {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(&42, <&i32>::from(&Unnamed(42)));
+ assert_eq!(&42, <&i32>::from(&Named { field: 42 }));
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref(i32, Unnamed))]
+ struct Tuple(Unnamed);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref(i32, Named))]
+ struct Struct {
+ field: Named,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(&42, <&i32>::from(&Tuple(Unnamed(42))));
+ assert_eq!(&Unnamed(42), <&Unnamed>::from(&Tuple(Unnamed(42))));
+ assert_eq!(
+ &42,
+ <&i32>::from(&Struct {
+ field: Named { field: 42 },
+ }),
+ );
+ assert_eq!(
+ &Named { field: 42 },
+ <&Named>::from(&Struct {
+ field: Named { field: 42 },
+ }),
+ );
+ }
+ }
+ }
+
+ mod ref_mut {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Unnamed(i32);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Named {
+ field: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(&mut 42, <&mut i32>::from(&mut Unnamed(42)));
+ assert_eq!(&mut 42, <&mut i32>::from(&mut Named { field: 42 }));
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut(i32, Unnamed))]
+ struct Tuple(Unnamed);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut(i32, Named))]
+ struct Struct {
+ field: Named,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(&mut 42, <&mut i32>::from(&mut Tuple(Unnamed(42))));
+ assert_eq!(
+ &mut Unnamed(42),
+ <&mut Unnamed>::from(&mut Tuple(Unnamed(42))),
+ );
+ assert_eq!(
+ &mut 42,
+ <&mut i32>::from(&mut Struct {
+ field: Named { field: 42 },
+ }),
+ );
+ assert_eq!(
+ &mut Named { field: 42 },
+ <&mut Named>::from(&mut Struct {
+ field: Named { field: 42 },
+ }),
+ );
+ }
+ }
+ }
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<T>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<T> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Wrapped(42), Tuple(Wrapped(42)).into());
+ assert_eq!(Wrapped(42), Struct { field: Wrapped(42) }.into());
+ }
+
+ mod skip {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<T>(#[into(skip)] Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<T> {
+ #[into(skip)]
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!((), Tuple(Wrapped(42)).into());
+ assert_eq!((), Struct { field: Wrapped(42) }.into());
+ }
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(Transmuted<T>)]
+ struct Tuple<T>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(Transmuted<T>)]
+ struct Struct<T> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Transmuted(42), Tuple(Wrapped(42)).into());
+ assert_eq!(Transmuted(42), Struct { field: Wrapped(42) }.into());
+ }
+ }
+
+ mod ref_ {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Tuple<T>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Struct<T> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(&Wrapped(42), <&Wrapped<_>>::from(&Tuple(Wrapped(42))));
+ assert_eq!(
+ &Wrapped(42),
+ <&Wrapped<_>>::from(&Struct { field: Wrapped(42) })
+ );
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref(Transmuted<T>))]
+ struct Tuple<T>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref(Transmuted<T>))]
+ struct Struct<T> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ &Transmuted(42),
+ <&Transmuted<_>>::from(&Tuple(Wrapped(42))),
+ );
+ assert_eq!(
+ &Transmuted(42),
+ <&Transmuted<_>>::from(&Struct { field: Wrapped(42) }),
+ );
+ }
+ }
+ }
+
+ mod ref_mut {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Tuple<T>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Struct<T> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ &mut Wrapped(42),
+ <&mut Wrapped<_>>::from(&mut Tuple(Wrapped(42)))
+ );
+ assert_eq!(
+ &mut Wrapped(42),
+ <&mut Wrapped<_>>::from(&mut Struct { field: Wrapped(42) }),
+ );
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut(Transmuted<T>))]
+ struct Tuple<T>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut(Transmuted<T>))]
+ struct Struct<T> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ &mut Transmuted(42),
+ <&mut Transmuted<_>>::from(&mut Tuple(Wrapped(42))),
+ );
+ assert_eq!(
+ &mut Transmuted(42),
+ <&mut Transmuted<_>>::from(&mut Struct { field: Wrapped(42) }),
+ );
+ }
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<T: 'static>(&'static Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<T: 'static> {
+ field: &'static Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(&Wrapped(42), <&Wrapped<_>>::from(Tuple(&Wrapped(42))));
+ assert_eq!(
+ &Wrapped(42),
+ <&Wrapped<_>>::from(Struct {
+ field: &Wrapped(42),
+ }),
+ );
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<T: Clone>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<T: Clone> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Wrapped(42), Tuple(Wrapped(42)).into());
+ assert_eq!(Wrapped(42), Struct { field: Wrapped(42) }.into());
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<const N: usize, T>(Wrapped<T>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<T, const N: usize> {
+ field: Wrapped<T>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Wrapped(1), Tuple::<1, _>(Wrapped(1)).into());
+ assert_eq!(Wrapped(1), Struct::<_, 1> { field: Wrapped(1) }.into());
+ }
+ }
+ }
+}
+
+mod multi_field {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple(i32, i64);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct {
+ field1: i32,
+ field2: i64,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!((1, 2_i64), Tuple(1, 2_i64).into());
+ assert_eq!(
+ (1, 2_i64),
+ Struct {
+ field1: 1,
+ field2: 2_i64,
+ }
+ .into(),
+ );
+ }
+
+ mod skip {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple(i32, #[into(skip)] i64);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct {
+ #[into(skip)]
+ field1: i32,
+ field2: i64,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(1, Tuple(1, 2_i64).into());
+ assert_eq!(
+ 2_i64,
+ Struct {
+ field1: 1,
+ field2: 2_i64,
+ }
+ .into(),
+ );
+ }
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into((i32, i64))]
+ #[into((i64, i128))]
+ struct Tuple(i16, i32);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into((Box<str>, i32), (Cow<'_, str>, i64))]
+ struct Struct {
+ field1: String,
+ field2: i32,
+ }
+
+ #[test]
+ fn assert() {
+ assert_not_impl_any!(Tuple: Into<(i16, i32)>);
+ assert_not_impl_any!(Struct: Into<(String, i32)>);
+
+ assert_eq!((1, 2_i64), Tuple(1_i16, 2).into());
+ assert_eq!((1_i64, 2_i128), Tuple(1_i16, 2).into());
+ assert_eq!(
+ (Box::<str>::from("42".to_owned()), 1),
+ Struct {
+ field1: "42".to_string(),
+ field2: 1,
+ }
+ .into(),
+ );
+ assert_eq!(
+ (Cow::Borrowed("42"), 1_i64),
+ Struct {
+ field1: "42".to_string(),
+ field2: 1,
+ }
+ .into(),
+ );
+ }
+
+ mod ref_ {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Unnamed(i32, i64);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Named {
+ field1: i32,
+ field2: i64,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!((&1, &2_i64), (&Unnamed(1, 2_i64)).into());
+ assert_eq!(
+ (&1, &2_i64),
+ (&Named {
+ field1: 1,
+ field2: 2_i64,
+ })
+ .into(),
+ );
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref(
+ (Transmuted<i32>, Transmuted<i64>),
+ (Transmuted<i32>, Wrapped<i64>)),
+ )]
+ struct Tuple(Wrapped<i32>, Wrapped<i64>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref(
+ (Transmuted<i32>, Transmuted<i64>),
+ (Transmuted<i32>, Wrapped<i64>)),
+ )]
+ struct Struct {
+ field1: Wrapped<i32>,
+ field2: Wrapped<i64>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (&Transmuted(1), &Transmuted(2_i64)),
+ (&Tuple(Wrapped(1), Wrapped(2_i64))).into(),
+ );
+ assert_eq!(
+ (&Transmuted(1), &Wrapped(2_i64)),
+ (&Tuple(Wrapped(1), Wrapped(2_i64))).into(),
+ );
+ assert_eq!(
+ (&Transmuted(1), &Transmuted(2_i64)),
+ (&Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2_i64),
+ })
+ .into(),
+ );
+ assert_eq!(
+ (&Transmuted(1), &Wrapped(2_i64)),
+ (&Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2_i64),
+ })
+ .into(),
+ );
+ }
+ }
+ }
+
+ mod ref_mut {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Unnamed(i32, i64);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Named {
+ field1: i32,
+ field2: i64,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!((&mut 1, &mut 2_i64), (&mut Unnamed(1, 2_i64)).into());
+ assert_eq!(
+ (&mut 1, &mut 2_i64),
+ (&mut Named {
+ field1: 1,
+ field2: 2_i64,
+ })
+ .into(),
+ );
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut(
+ (Transmuted<i32>, Transmuted<i64>),
+ (Transmuted<i32>, Wrapped<i64>)),
+ )]
+ struct Tuple(Wrapped<i32>, Wrapped<i64>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut(
+ (Transmuted<i32>, Transmuted<i64>),
+ (Transmuted<i32>, Wrapped<i64>)),
+ )]
+ struct Struct {
+ field1: Wrapped<i32>,
+ field2: Wrapped<i64>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (&mut Transmuted(1), &mut Transmuted(2_i64)),
+ (&mut Tuple(Wrapped(1), Wrapped(2_i64))).into(),
+ );
+ assert_eq!(
+ (&mut Transmuted(1), &mut Wrapped(2_i64)),
+ (&mut Tuple(Wrapped(1), Wrapped(2_i64))).into(),
+ );
+ assert_eq!(
+ (&mut Transmuted(1), &mut Transmuted(2_i64)),
+ (&mut Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2_i64),
+ })
+ .into(),
+ );
+ assert_eq!(
+ (&mut Transmuted(1), &mut Wrapped(2_i64)),
+ (&mut Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2_i64),
+ })
+ .into(),
+ );
+ }
+ }
+ }
+ }
+
+ mod generic {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<A, B>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<A, B> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (Wrapped(1), Wrapped(2)),
+ Tuple(Wrapped(1), Wrapped(2)).into(),
+ );
+ assert_eq!(
+ (Wrapped(1), Wrapped(2)),
+ Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ }
+ .into(),
+ );
+ }
+
+ mod skip {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<A, B>(Wrapped<A>, #[into(skip)] Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<A, B> {
+ #[into(skip)]
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(Wrapped(1), Tuple(Wrapped(1), Wrapped(2)).into());
+ assert_eq!(
+ Wrapped(2),
+ Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ }
+ .into(),
+ );
+ }
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into((Transmuted<A>, Transmuted<B>))]
+ struct Tuple<A, B>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into((Transmuted<A>, Transmuted<B>))]
+ struct Struct<A, B> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (Transmuted(1), Transmuted(2)),
+ Tuple(Wrapped(1), Wrapped(2)).into(),
+ );
+ assert_eq!(
+ (Transmuted(1), Transmuted(2)),
+ Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ }
+ .into(),
+ );
+ }
+ }
+
+ mod ref_ {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Tuple<A, B>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref)]
+ struct Struct<A, B> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (&Wrapped(1), &Wrapped(2)),
+ (&Tuple(Wrapped(1), Wrapped(2))).into(),
+ );
+ assert_eq!(
+ (&Wrapped(1), &Wrapped(2)),
+ (&Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ })
+ .into(),
+ );
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref((Transmuted<A>, Transmuted<B>)))]
+ struct Tuple<A, B>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref((Transmuted<A>, Transmuted<B>)))]
+ struct Struct<A, B> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (&Transmuted(1), &Transmuted(2)),
+ (&Tuple(Wrapped(1), Wrapped(2))).into(),
+ );
+ assert_eq!(
+ (&Transmuted(1), &Transmuted(2)),
+ (&Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ })
+ .into(),
+ );
+ }
+ }
+ }
+
+ mod ref_mut {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Tuple<A, B>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut)]
+ struct Struct<A, B> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (&mut Wrapped(1), &mut Wrapped(2)),
+ (&mut Tuple(Wrapped(1), Wrapped(2))).into(),
+ );
+ assert_eq!(
+ (&mut Wrapped(1), &mut Wrapped(2)),
+ (&mut Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ })
+ .into(),
+ );
+ }
+
+ mod types {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut((Transmuted<A>, Transmuted<B>)))]
+ struct Tuple<A, B>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ #[into(ref_mut((Transmuted<A>, Transmuted<B>)))]
+ struct Struct<A, B> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (&mut Transmuted(1), &mut Transmuted(2)),
+ (&mut Tuple(Wrapped(1), Wrapped(2))).into(),
+ );
+ assert_eq!(
+ (&mut Transmuted(1), &mut Transmuted(2)),
+ (&mut Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ })
+ .into(),
+ );
+ }
+ }
+ }
+
+ mod indirect {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<A: 'static, B: 'static>(
+ &'static Wrapped<A>,
+ &'static Wrapped<B>,
+ );
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<A: 'static, B: 'static> {
+ field1: &'static Wrapped<A>,
+ field2: &'static Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (&Wrapped(1), &Wrapped(2)),
+ Tuple(&Wrapped(1), &Wrapped(2)).into(),
+ );
+ assert_eq!(
+ (&Wrapped(1), &Wrapped(2)),
+ (Struct {
+ field1: &Wrapped(1),
+ field2: &Wrapped(2),
+ })
+ .into(),
+ );
+ }
+ }
+
+ mod bounded {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<A: Clone, B: Clone>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<A: Clone, B: Clone> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (Wrapped(1), Wrapped(2)),
+ Tuple(Wrapped(1), Wrapped(2)).into(),
+ );
+ assert_eq!(
+ (Wrapped(1), Wrapped(2)),
+ Struct {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ }
+ .into(),
+ );
+ }
+ }
+
+ mod r#const {
+ use super::*;
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Tuple<const N: usize, A, B>(Wrapped<A>, Wrapped<B>);
+
+ #[derive(Debug, Into, PartialEq)]
+ struct Struct<A, const N: usize, B> {
+ field1: Wrapped<A>,
+ field2: Wrapped<B>,
+ }
+
+ #[test]
+ fn assert() {
+ assert_eq!(
+ (Wrapped(1), Wrapped(2)),
+ Tuple::<1, _, _>(Wrapped(1), Wrapped(2)).into(),
+ );
+ assert_eq!(
+ (Wrapped(1), Wrapped(2)),
+ Struct::<_, 1, _> {
+ field1: Wrapped(1),
+ field2: Wrapped(2),
+ }
+ .into(),
+ );
+ }
+ }
+ }
+}
diff --git a/third_party/rust/derive_more/tests/into_iterator.rs b/third_party/rust/derive_more/tests/into_iterator.rs
new file mode 100644
index 0000000000..7f9d6a36df
--- /dev/null
+++ b/third_party/rust/derive_more/tests/into_iterator.rs
@@ -0,0 +1,47 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code, unused_imports)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::vec::Vec;
+
+use derive_more::IntoIterator;
+
+#[derive(IntoIterator)]
+#[into_iterator(owned, ref, ref_mut)]
+struct MyVec(Vec<i32>);
+
+#[derive(IntoIterator)]
+#[into_iterator(owned, ref, ref_mut)]
+struct Numbers {
+ numbers: Vec<i32>,
+}
+
+#[derive(IntoIterator)]
+struct Numbers2 {
+ #[into_iterator(owned, ref, ref_mut)]
+ numbers: Vec<i32>,
+ useless: bool,
+ useless2: bool,
+}
+
+#[derive(IntoIterator)]
+struct Numbers3 {
+ #[into_iterator(ref, ref_mut)]
+ numbers: Vec<i32>,
+ useless: bool,
+ useless2: bool,
+}
+
+// Test that owned is not enabled when ref/ref_mut are enabled without owned
+impl ::core::iter::IntoIterator for Numbers3 {
+ type Item = <Vec<i32> as ::core::iter::IntoIterator>::Item;
+ type IntoIter = <Vec<i32> as ::core::iter::IntoIterator>::IntoIter;
+
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ <Vec<i32> as ::core::iter::IntoIterator>::into_iter(self.numbers)
+ }
+}
diff --git a/third_party/rust/derive_more/tests/is_variant.rs b/third_party/rust/derive_more/tests/is_variant.rs
new file mode 100644
index 0000000000..e778ca47af
--- /dev/null
+++ b/third_party/rust/derive_more/tests/is_variant.rs
@@ -0,0 +1,163 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use derive_more::IsVariant;
+
+#[derive(IsVariant)]
+enum Either<TLeft, TRight> {
+ Left(TLeft),
+ Right(TRight),
+}
+
+const _: () = {
+ let either: Either<u8, i16> = Either::Right(7);
+ assert!(either.is_right());
+ assert!(!either.is_left());
+
+ let either: Either<u8, i16> = Either::Left(7);
+ assert!(!either.is_right());
+ assert!(either.is_left());
+};
+
+#[derive(IsVariant)]
+enum Maybe<T> {
+ Nothing,
+ Just(T),
+}
+
+const _: () = {
+ let maybe: Maybe<u8> = Maybe::Just(7);
+ assert!(maybe.is_just());
+ assert!(!maybe.is_nothing());
+
+ let maybe: Maybe<u8> = Maybe::Nothing;
+ assert!(!maybe.is_just());
+ assert!(maybe.is_nothing());
+};
+
+#[test]
+pub fn test_is_variant() {
+ assert!(Maybe::<()>::Nothing.is_nothing());
+ assert!(!Maybe::<()>::Nothing.is_just());
+}
+
+#[derive(IsVariant)]
+enum Color {
+ RGB(u8, u8, u8),
+ CMYK { c: u8, m: u8, y: u8, k: u8 },
+}
+
+const _: () = {
+ let color = Color::RGB(0, 0, 0);
+ assert!(color.is_rgb());
+ assert!(!color.is_cmyk());
+
+ let color = Color::CMYK {
+ c: 0,
+ m: 0,
+ y: 0,
+ k: 0,
+ };
+ assert!(!color.is_rgb());
+ assert!(color.is_cmyk());
+};
+
+#[derive(IsVariant)]
+enum Nonsense<'a, T> {
+ Ref(&'a T),
+ NoRef,
+ #[is_variant(ignore)]
+ NoRefIgnored,
+}
+
+const _: () = {
+ let nonsense: Nonsense<u8> = Nonsense::Ref(&7);
+ assert!(nonsense.is_ref());
+ assert!(!nonsense.is_no_ref());
+
+ let nonsense: Nonsense<u8> = Nonsense::NoRef;
+ assert!(!nonsense.is_ref());
+ assert!(nonsense.is_no_ref());
+};
+
+#[derive(IsVariant)]
+enum WithConstraints<T>
+where
+ T: Copy,
+{
+ One(T),
+ Two,
+}
+
+const _: () = {
+ let wc: WithConstraints<u8> = WithConstraints::One(1);
+ assert!(wc.is_one());
+ assert!(!wc.is_two());
+
+ let wc: WithConstraints<u8> = WithConstraints::Two;
+ assert!(!wc.is_one());
+ assert!(wc.is_two());
+};
+
+#[derive(IsVariant)]
+enum KitchenSink<'a, 'b, T1: Copy, T2: Clone>
+where
+ T2: Into<T1> + 'b,
+{
+ Left(&'a T1),
+ Right(&'b T2),
+ OwnBoth { left: T1, right: T2 },
+ Empty,
+ NeverMind(),
+ NothingToSeeHere {},
+}
+
+const _: () = {
+ let ks: KitchenSink<u16, u8> = KitchenSink::Left(&1);
+ assert!(ks.is_left());
+ assert!(!ks.is_right());
+ assert!(!ks.is_own_both());
+ assert!(!ks.is_empty());
+ assert!(!ks.is_never_mind());
+ assert!(!ks.is_nothing_to_see_here());
+
+ let ks: KitchenSink<u16, u8> = KitchenSink::Right(&1);
+ assert!(!ks.is_left());
+ assert!(ks.is_right());
+ assert!(!ks.is_own_both());
+ assert!(!ks.is_empty());
+ assert!(!ks.is_never_mind());
+ assert!(!ks.is_nothing_to_see_here());
+
+ let ks: KitchenSink<u16, u8> = KitchenSink::OwnBoth { left: 1, right: 2 };
+ assert!(!ks.is_left());
+ assert!(!ks.is_right());
+ assert!(ks.is_own_both());
+ assert!(!ks.is_empty());
+ assert!(!ks.is_never_mind());
+ assert!(!ks.is_nothing_to_see_here());
+
+ let ks: KitchenSink<u16, u8> = KitchenSink::Empty;
+ assert!(!ks.is_left());
+ assert!(!ks.is_right());
+ assert!(!ks.is_own_both());
+ assert!(ks.is_empty());
+ assert!(!ks.is_never_mind());
+ assert!(!ks.is_nothing_to_see_here());
+
+ let ks: KitchenSink<u16, u8> = KitchenSink::NeverMind();
+ assert!(!ks.is_left());
+ assert!(!ks.is_right());
+ assert!(!ks.is_own_both());
+ assert!(!ks.is_empty());
+ assert!(ks.is_never_mind());
+ assert!(!ks.is_nothing_to_see_here());
+
+ let ks: KitchenSink<u16, u8> = KitchenSink::NothingToSeeHere {};
+ assert!(!ks.is_left());
+ assert!(!ks.is_right());
+ assert!(!ks.is_own_both());
+ assert!(!ks.is_empty());
+ assert!(!ks.is_never_mind());
+ assert!(ks.is_nothing_to_see_here());
+};
diff --git a/third_party/rust/derive_more/tests/lib.rs b/third_party/rust/derive_more/tests/lib.rs
new file mode 100644
index 0000000000..0a734eccad
--- /dev/null
+++ b/third_party/rust/derive_more/tests/lib.rs
@@ -0,0 +1,278 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use derive_more::{
+ Add, AddAssign, Binary, BitAnd, BitOr, BitXor, Constructor, Deref, DerefMut,
+ Display, Div, From, FromStr, Index, IndexMut, Into, IntoIterator, Mul, MulAssign,
+ Neg, Not, Octal, Product, Rem, Shl, Shr, Sub, Sum,
+};
+
+#[derive(From)]
+#[derive(Into)]
+#[derive(Constructor)]
+#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Add)]
+#[derive(Mul)]
+#[derive(Neg)]
+#[derive(AddAssign)]
+#[derive(MulAssign)]
+#[derive(FromStr)]
+#[derive(Display)]
+#[derive(Octal)]
+#[derive(Binary)]
+#[derive(Deref, DerefMut)]
+#[into(owned, ref, ref_mut)]
+struct MyInt(i32);
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Add)]
+#[derive(Sum)]
+#[derive(Mul)]
+#[derive(MulAssign)]
+#[derive(Product)]
+#[mul(forward)]
+#[mul_assign(forward)]
+struct MyInt2(i32);
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(Index, IndexMut)]
+#[derive(Deref, DerefMut)]
+#[derive(IntoIterator)]
+#[deref(forward)]
+#[deref_mut(forward)]
+#[into_iterator(owned, ref, ref_mut)]
+struct MyVec(Vec<i32>);
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(Deref, DerefMut)]
+#[deref(forward)]
+#[deref_mut(forward)]
+struct MyBoxedInt(Box<i32>);
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(Not)]
+#[derive(From)]
+struct MyBool(bool);
+
+#[derive(From)]
+#[derive(Into)]
+#[derive(Constructor)]
+#[derive(Add)]
+#[derive(Debug, Eq, PartialEq)]
+#[derive(Mul)]
+#[derive(AddAssign)]
+struct MyUInt(u64, u64);
+
+#[derive(From)]
+#[derive(Into)]
+#[derive(Constructor)]
+#[derive(FromStr)]
+#[derive(Debug, Eq, PartialEq)]
+#[derive(Display)]
+struct SimpleStruct {
+ int1: u64,
+}
+
+#[derive(From)]
+#[derive(Constructor)]
+#[derive(Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shr, Shl)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[derive(Into)]
+#[derive(AddAssign)]
+#[into(owned, ref, ref_mut)]
+struct NormalStruct {
+ int1: u64,
+ int2: u64,
+}
+
+#[derive(From)]
+#[derive(Debug, Eq, PartialEq)]
+struct NestedInt(MyInt);
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(From)]
+#[derive(Add, Sub)]
+enum SimpleMyIntEnum {
+ Int(i32),
+ #[from(ignore)]
+ _UnsignedOne(u32),
+ _UnsignedTwo(u32),
+}
+#[derive(Debug, Eq, PartialEq)]
+#[derive(From)]
+#[derive(Neg)]
+enum SimpleSignedIntEnum {
+ Int(i32),
+ Int2(i16),
+}
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(From)]
+#[derive(Add, Sub)]
+#[derive(Neg)]
+enum SimpleEnum {
+ Int(i32),
+ #[from(ignore)]
+ _Ints(i32, i32),
+ LabeledInts {
+ a: i32,
+ b: i32,
+ },
+ _SomeUnit,
+}
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(From)]
+#[derive(Add, Sub)]
+enum MyIntEnum {
+ SmallInt(i32),
+ BigInt(i64),
+ TwoInts(i32, i32),
+ Point2D {
+ x: i64,
+ y: i64,
+ },
+ #[from(ignore)]
+ _UnsignedOne(u32),
+ _UnsignedTwo(u32),
+ #[from(ignore)]
+ _Uints1(u64, u64),
+ _Uints2 {
+ x: u64,
+ y: u64,
+ },
+}
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(Add, Mul)]
+struct DoubleUInt(u32, u32);
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(Add, Mul)]
+struct DoubleUIntStruct {
+ x: u32,
+ y: u32,
+}
+
+#[derive(Debug, Eq, PartialEq)]
+#[derive(From, Into, Constructor)]
+struct Unit;
+
+// Tests that we can forward to a path
+// containing `$crate`
+macro_rules! use_dollar_crate {
+ () => {
+ struct Foo;
+ #[derive(From)]
+ enum Bar {
+ First(#[from(forward)] $crate::Foo),
+ }
+ };
+}
+
+use_dollar_crate!();
+
+#[test]
+fn main() {
+ let mut myint: MyInt = 5.into();
+ let _: SimpleMyIntEnum = 5i32.into();
+ let _: MyIntEnum = 5i32.into();
+ let _: MyIntEnum = 6i64.into();
+ let _: MyIntEnum = (5i32, 8i32).into();
+ let _: MyIntEnum = (5i64, 8i64).into();
+
+ let int_ref: &i32 = (&myint).into();
+ assert_eq!(int_ref, &5);
+
+ let int_ref_mut: &mut i32 = (&mut myint).into();
+ assert_eq!(int_ref_mut, &mut 5);
+
+ let mut myint: MyInt = 5.into();
+ let _: Unit = ().into();
+ assert_eq!((), Unit.into());
+ assert_eq!(Unit, Unit::new());
+ assert_eq!(MyInt(5), 5.into());
+ assert_eq!(Ok(MyInt(5)), "5".parse());
+ assert_eq!(5, MyInt(5).into());
+ assert_eq!(MyInt(5), MyInt::new(5));
+ assert_eq!(-MyInt(5), (-5).into());
+ assert_eq!("30", MyInt(30).to_string());
+ assert_eq!("36", format!("{:o}", MyInt(30)));
+ assert_eq!("100", format!("{:b}", MyInt(4)));
+ assert_eq!(!MyBool(true), false.into());
+ assert_eq!(MyIntEnum::SmallInt(5), 5.into());
+
+ assert_eq!(SimpleStruct { int1: 5 }, 5.into());
+ assert_eq!(5u64, SimpleStruct { int1: 5 }.into());
+ assert_eq!(Ok(SimpleStruct { int1: 5 }), "5".parse());
+ assert_eq!("5", SimpleStruct { int1: 5 }.to_string());
+ assert_eq!(NormalStruct { int1: 5, int2: 6 }, (5, 6).into());
+ assert_eq!(SimpleStruct { int1: 5 }, SimpleStruct::new(5));
+ assert_eq!(NormalStruct { int1: 5, int2: 6 }, NormalStruct::new(5, 6));
+ assert_eq!((5, 6), NormalStruct::new(5, 6).into());
+ let mut norm_struct = NormalStruct::new(5, 6);
+ let uints_ref: (&u64, &u64) = (&norm_struct).into();
+ assert_eq!((&5, &6), uints_ref);
+ let uints_ref_mut: (&mut u64, &mut u64) = (&mut norm_struct).into();
+ assert_eq!((&mut 5, &mut 6), uints_ref_mut);
+
+ assert_eq!(MyInt(4) + MyInt(1), 5.into());
+ myint += MyInt(3);
+ assert_eq!(myint, 8.into());
+ myint *= 5;
+ assert_eq!(myint, 40.into());
+ assert_eq!(MyInt(4) + MyInt(1), 5.into());
+ assert_eq!(MyUInt(4, 5) + MyUInt(1, 2), MyUInt(5, 7));
+ assert_eq!(MyUInt(4, 5), MyUInt::new(4, 5));
+ assert_eq!((4, 5), MyUInt(4, 5).into());
+ let mut s1 = NormalStruct { int1: 1, int2: 2 };
+ let s2 = NormalStruct { int1: 2, int2: 3 };
+ let s3 = NormalStruct { int1: 3, int2: 5 };
+ assert_eq!(s1 + s2, s3);
+ assert_eq!(s3 - s2, s1);
+ s1 += s2;
+ assert_eq!(s1, s3);
+
+ assert_eq!((SimpleMyIntEnum::Int(6) + 5.into()).unwrap(), 11.into());
+ assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
+ assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
+ assert_eq!(-SimpleSignedIntEnum::Int(6), (-6i32).into());
+ assert_eq!(
+ (SimpleEnum::LabeledInts { a: 6, b: 5 }
+ + SimpleEnum::LabeledInts { a: 1, b: 4 })
+ .unwrap(),
+ SimpleEnum::LabeledInts { a: 7, b: 9 }
+ );
+
+ let _ = (MyIntEnum::SmallInt(5) + 6.into()).unwrap();
+ assert_eq!((-SimpleEnum::Int(5)).unwrap(), (-5).into());
+
+ assert_eq!(MyInt(50), MyInt(5) * 10);
+ assert_eq!(DoubleUInt(5, 6) * 10, DoubleUInt(50, 60));
+ // assert_eq!(DoubleUIntStruct{x:5, y:6} * 10, DoubleUIntStruct{x:50, y:60});
+
+ let mut myint = MyInt(5);
+ assert_eq!(5, *myint);
+ *myint = 7;
+ assert_eq!(MyInt(7), myint);
+
+ let mut my_vec = MyVec(vec![5, 8]);
+ assert_eq!(5, my_vec[0]);
+ assert_eq!(8, my_vec[1]);
+ my_vec[0] = 20;
+ assert_eq!(20, my_vec[0]);
+ assert_eq!((&my_vec).into_iter().next(), Some(&20));
+ assert_eq!((&mut my_vec).into_iter().next(), Some(&mut 20));
+ assert_eq!(my_vec.into_iter().next(), Some(20));
+
+ let int_vec = vec![MyInt2(2), MyInt2(3)];
+ assert_eq!(MyInt2(5), int_vec.clone().into_iter().sum());
+ assert_eq!(MyInt2(6), int_vec.clone().into_iter().product());
+ let mut myint2 = MyInt2(8);
+ myint2 *= MyInt2(4);
+ assert_eq!(MyInt2(32), myint2);
+
+ let mut boxed = MyBoxedInt(Box::new(5));
+ assert_eq!(5, *boxed);
+ *boxed = 7;
+ assert_eq!(MyBoxedInt(Box::new(7)), boxed)
+}
diff --git a/third_party/rust/derive_more/tests/mul.rs b/third_party/rust/derive_more/tests/mul.rs
new file mode 100644
index 0000000000..706c3ec3e2
--- /dev/null
+++ b/third_party/rust/derive_more/tests/mul.rs
@@ -0,0 +1,21 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use derive_more::Mul;
+
+#[derive(Mul)]
+struct MyInt(i32);
+
+#[derive(Mul)]
+struct MyInts(i32, i32);
+
+#[derive(Mul)]
+struct Point1D {
+ x: i32,
+}
+
+#[derive(Mul)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
diff --git a/third_party/rust/derive_more/tests/mul_assign.rs b/third_party/rust/derive_more/tests/mul_assign.rs
new file mode 100644
index 0000000000..51087ac683
--- /dev/null
+++ b/third_party/rust/derive_more/tests/mul_assign.rs
@@ -0,0 +1,33 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use core::marker::PhantomData;
+
+use derive_more::MulAssign;
+
+#[derive(MulAssign)]
+struct MyInt(i32);
+
+#[derive(MulAssign)]
+struct MyInts(i32, i32);
+
+#[derive(MulAssign)]
+#[mul_assign(forward)]
+struct MyIntForward(i32);
+
+#[derive(MulAssign)]
+struct Point1D {
+ x: i32,
+}
+
+#[derive(MulAssign)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
+
+#[derive(MulAssign)]
+struct MyInt2<T> {
+ x: i32,
+ ph: PhantomData<T>,
+}
diff --git a/third_party/rust/derive_more/tests/no_std.rs b/third_party/rust/derive_more/tests/no_std.rs
new file mode 100644
index 0000000000..3b5cdb2d85
--- /dev/null
+++ b/third_party/rust/derive_more/tests/no_std.rs
@@ -0,0 +1,76 @@
+#![no_std]
+#![allow(dead_code)]
+
+use derive_more::{
+ Add, AddAssign, Constructor, Deref, DerefMut, Display, From, FromStr, Index,
+ IndexMut, Into, IntoIterator, Mul, MulAssign, Not, Sum, TryInto,
+};
+
+#[derive(
+ AddAssign,
+ MulAssign,
+ Add,
+ Mul,
+ Not,
+ Index,
+ Display,
+ FromStr,
+ Into,
+ From,
+ IndexMut,
+ Sum,
+ Deref,
+ DerefMut,
+ Constructor
+)]
+#[into(owned, ref, ref_mut)]
+struct MyInts(u64);
+
+#[derive(Deref, DerefMut)]
+#[deref(forward)]
+#[deref_mut(forward)]
+struct MyBoxedInt<'a>(&'a mut u64);
+
+#[derive(
+ From,
+ FromStr,
+ Display,
+ Index,
+ Not,
+ Add,
+ Mul,
+ Sum,
+ IndexMut,
+ AddAssign,
+ Deref,
+ DerefMut,
+ IntoIterator,
+ Constructor
+)]
+#[deref(forward)]
+#[deref_mut(forward)]
+#[into_iterator(owned, ref, ref_mut)]
+struct Wrapped<T: Clone>(T);
+
+#[derive(Deref, DerefMut)]
+struct Wrapped2<T: Clone>(T);
+
+#[derive(From, Not, Add, Mul, AddAssign, Constructor, Sum)]
+struct WrappedDouble<T: Clone, U: Clone>(T, U);
+
+#[derive(Add, Not, TryInto)]
+#[try_into(owned, ref, ref_mut)]
+enum MixedInts {
+ SmallInt(i32),
+ BigInt(i64),
+ TwoSmallInts(i32, i32),
+ NamedSmallInts { x: i32, y: i32 },
+ UnsignedOne(u32),
+ UnsignedTwo(u32),
+}
+
+#[derive(Not, Add)]
+enum EnumWithUnit {
+ SmallInt(i32),
+ Unit,
+}
diff --git a/third_party/rust/derive_more/tests/not.rs b/third_party/rust/derive_more/tests/not.rs
new file mode 100644
index 0000000000..bb340faced
--- /dev/null
+++ b/third_party/rust/derive_more/tests/not.rs
@@ -0,0 +1,29 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use derive_more::Not;
+
+#[derive(Not)]
+struct MyInts(i32, i32);
+
+#[derive(Not)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
+
+#[derive(Not)]
+enum MixedInts {
+ SmallInt(i32),
+ BigInt(i64),
+ TwoSmallInts(i32, i32),
+ NamedSmallInts { x: i32, y: i32 },
+ UnsignedOne(u32),
+ UnsignedTwo(u32),
+}
+
+#[derive(Not)]
+enum EnumWithUnit {
+ SmallInt(i32),
+ Unit,
+}
diff --git a/third_party/rust/derive_more/tests/sum.rs b/third_party/rust/derive_more/tests/sum.rs
new file mode 100644
index 0000000000..d220fd5a63
--- /dev/null
+++ b/third_party/rust/derive_more/tests/sum.rs
@@ -0,0 +1,32 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use derive_more::Sum;
+
+#[derive(Sum)]
+struct MyInts(i32, i64);
+
+// Add implementation is needed for Sum
+impl ::core::ops::Add for MyInts {
+ type Output = MyInts;
+ #[inline]
+ fn add(self, rhs: MyInts) -> MyInts {
+ MyInts(self.0.add(rhs.0), self.1.add(rhs.1))
+ }
+}
+
+#[derive(Sum)]
+struct Point2D {
+ x: i32,
+ y: i32,
+}
+
+impl ::core::ops::Add for Point2D {
+ type Output = Point2D;
+ #[inline]
+ fn add(self, rhs: Point2D) -> Point2D {
+ Point2D {
+ x: self.x.add(rhs.x),
+ y: self.y.add(rhs.y),
+ }
+ }
+}
diff --git a/third_party/rust/derive_more/tests/try_into.rs b/third_party/rust/derive_more/tests/try_into.rs
new file mode 100644
index 0000000000..6d158ec5be
--- /dev/null
+++ b/third_party/rust/derive_more/tests/try_into.rs
@@ -0,0 +1,234 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::string::ToString;
+
+use derive_more::TryInto;
+
+// Ensure that the `TryInto` macro is hygienic and doesn't break when `Result`
+// has been redefined.
+type Result = ();
+
+#[derive(TryInto, Clone, Copy, Debug, Eq, PartialEq)]
+#[try_into(owned, ref, ref_mut)]
+enum MixedInts {
+ SmallInt(i32),
+ NamedBigInt {
+ int: i64,
+ },
+ UnsignedWithIgnoredField(#[try_into(ignore)] bool, i64),
+ NamedUnsignedWithIgnoredField {
+ #[try_into(ignore)]
+ useless: bool,
+ x: i64,
+ },
+ TwoSmallInts(i32, i32),
+ NamedBigInts {
+ x: i64,
+ y: i64,
+ },
+ Unsigned(u32),
+ NamedUnsigned {
+ x: u32,
+ },
+ Unit,
+ #[try_into(ignore)]
+ Unit2,
+}
+
+#[test]
+fn test_try_into() {
+ let mut i = MixedInts::SmallInt(42);
+ assert_eq!(42i32, i.try_into().unwrap());
+ assert_eq!(&42i32, <_ as TryInto<&i32>>::try_into(&i).unwrap());
+ assert_eq!(
+ &mut 42i32,
+ <_ as TryInto<&mut i32>>::try_into(&mut i).unwrap()
+ );
+ assert_eq!(
+ i64::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64"
+ );
+ assert_eq!(i64::try_from(i).unwrap_err().input, MixedInts::SmallInt(42));
+ assert_eq!(
+ <(i32, i32)>::try_from(i).unwrap_err().to_string(),
+ "Only TwoSmallInts can be converted to (i32, i32)"
+ );
+ assert_eq!(
+ <(i64, i64)>::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInts can be converted to (i64, i64)"
+ );
+ assert_eq!(
+ u32::try_from(i).unwrap_err().to_string(),
+ "Only Unsigned, NamedUnsigned can be converted to u32"
+ );
+ assert_eq!(
+ <()>::try_from(i).unwrap_err().to_string(),
+ "Only Unit can be converted to ()"
+ );
+
+ let mut i = MixedInts::NamedBigInt { int: 42 };
+ assert_eq!(
+ i32::try_from(i).unwrap_err().to_string(),
+ "Only SmallInt can be converted to i32"
+ );
+ assert_eq!(42i64, i.try_into().unwrap());
+ assert_eq!(&42i64, <_ as TryInto<&i64>>::try_into(&i).unwrap());
+ assert_eq!(
+ &mut 42i64,
+ <_ as TryInto<&mut i64>>::try_into(&mut i).unwrap()
+ );
+ assert_eq!(
+ <(i32, i32)>::try_from(i).unwrap_err().to_string(),
+ "Only TwoSmallInts can be converted to (i32, i32)"
+ );
+ assert_eq!(
+ <(i64, i64)>::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInts can be converted to (i64, i64)"
+ );
+ assert_eq!(
+ u32::try_from(i).unwrap_err().to_string(),
+ "Only Unsigned, NamedUnsigned can be converted to u32"
+ );
+ assert_eq!(
+ <()>::try_from(i).unwrap_err().to_string(),
+ "Only Unit can be converted to ()"
+ );
+
+ let mut i = MixedInts::TwoSmallInts(42, 64);
+ assert_eq!(
+ i32::try_from(i).unwrap_err().to_string(),
+ "Only SmallInt can be converted to i32"
+ );
+ assert_eq!(
+ i64::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64"
+ );
+ assert_eq!((42i32, 64i32), i.try_into().unwrap());
+ assert_eq!((&42i32, &64i32), (&i).try_into().unwrap());
+ assert_eq!((&mut 42i32, &mut 64i32), (&mut i).try_into().unwrap());
+ assert_eq!(
+ <(i64, i64)>::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInts can be converted to (i64, i64)"
+ );
+ assert_eq!(
+ u32::try_from(i).unwrap_err().to_string(),
+ "Only Unsigned, NamedUnsigned can be converted to u32"
+ );
+ assert_eq!(
+ <()>::try_from(i).unwrap_err().to_string(),
+ "Only Unit can be converted to ()"
+ );
+
+ let mut i = MixedInts::NamedBigInts { x: 42, y: 64 };
+ assert_eq!(
+ i32::try_from(i).unwrap_err().to_string(),
+ "Only SmallInt can be converted to i32"
+ );
+ assert_eq!(
+ i64::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64"
+ );
+ assert_eq!(
+ <(i32, i32)>::try_from(i).unwrap_err().to_string(),
+ "Only TwoSmallInts can be converted to (i32, i32)"
+ );
+ assert_eq!((42i64, 64i64), i.try_into().unwrap());
+ assert_eq!((&42i64, &64i64), (&i).try_into().unwrap());
+ assert_eq!((&mut 42i64, &mut 64i64), (&mut i).try_into().unwrap());
+ assert_eq!(
+ u32::try_from(i).unwrap_err().to_string(),
+ "Only Unsigned, NamedUnsigned can be converted to u32"
+ );
+ assert_eq!(
+ <()>::try_from(i).unwrap_err().to_string(),
+ "Only Unit can be converted to ()"
+ );
+
+ let mut i = MixedInts::Unsigned(42);
+ assert_eq!(
+ i32::try_from(i).unwrap_err().to_string(),
+ "Only SmallInt can be converted to i32"
+ );
+ assert_eq!(
+ i64::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64"
+ );
+ assert_eq!(
+ <(i32, i32)>::try_from(i).unwrap_err().to_string(),
+ "Only TwoSmallInts can be converted to (i32, i32)"
+ );
+ assert_eq!(
+ <(i64, i64)>::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInts can be converted to (i64, i64)"
+ );
+ assert_eq!(42u32, i.try_into().unwrap());
+ assert_eq!(&42u32, <_ as TryInto<&u32>>::try_into(&i).unwrap());
+ assert_eq!(
+ &mut 42u32,
+ <_ as TryInto<&mut u32>>::try_into(&mut i).unwrap()
+ );
+ assert_eq!(
+ <()>::try_from(i).unwrap_err().to_string(),
+ "Only Unit can be converted to ()"
+ );
+
+ let mut i = MixedInts::NamedUnsigned { x: 42 };
+ assert_eq!(
+ i32::try_from(i).unwrap_err().to_string(),
+ "Only SmallInt can be converted to i32"
+ );
+ assert_eq!(
+ i64::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64"
+ );
+ assert_eq!(
+ i64::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64"
+ );
+ assert_eq!(
+ <(i32, i32)>::try_from(i).unwrap_err().to_string(),
+ "Only TwoSmallInts can be converted to (i32, i32)"
+ );
+ assert_eq!(
+ <(i64, i64)>::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInts can be converted to (i64, i64)"
+ );
+ assert_eq!(42u32, i.try_into().unwrap());
+ assert_eq!(&42u32, <_ as TryInto<&u32>>::try_into(&i).unwrap());
+ assert_eq!(
+ &mut 42u32,
+ <_ as TryInto<&mut u32>>::try_into(&mut i).unwrap()
+ );
+ assert_eq!(
+ <()>::try_from(i).unwrap_err().to_string(),
+ "Only Unit can be converted to ()"
+ );
+
+ let i = MixedInts::Unit;
+ assert_eq!(
+ i32::try_from(i).unwrap_err().to_string(),
+ "Only SmallInt can be converted to i32"
+ );
+ assert_eq!(
+ i64::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64"
+ );
+ assert_eq!(
+ <(i32, i32)>::try_from(i).unwrap_err().to_string(),
+ "Only TwoSmallInts can be converted to (i32, i32)"
+ );
+ assert_eq!(
+ <(i64, i64)>::try_from(i).unwrap_err().to_string(),
+ "Only NamedBigInts can be converted to (i64, i64)"
+ );
+ assert_eq!(
+ u32::try_from(i).unwrap_err().to_string(),
+ "Only Unsigned, NamedUnsigned can be converted to u32"
+ );
+ assert_eq!((), i.try_into().unwrap());
+}
diff --git a/third_party/rust/derive_more/tests/try_unwrap.rs b/third_party/rust/derive_more/tests/try_unwrap.rs
new file mode 100644
index 0000000000..abcc927032
--- /dev/null
+++ b/third_party/rust/derive_more/tests/try_unwrap.rs
@@ -0,0 +1,135 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+#[cfg(not(feature = "std"))]
+extern crate alloc;
+
+#[cfg(not(feature = "std"))]
+use alloc::string::ToString;
+
+use derive_more::TryUnwrap;
+
+#[derive(TryUnwrap)]
+enum Either<TLeft, TRight> {
+ Left(TLeft),
+ Right(TRight),
+}
+
+#[derive(TryUnwrap)]
+#[derive(Debug, PartialEq)]
+#[try_unwrap(ref, ref_mut)]
+enum Maybe<T> {
+ Nothing,
+ Just(T),
+}
+
+#[derive(TryUnwrap)]
+enum Color {
+ RGB(u8, u8, u8),
+ CMYK(u8, u8, u8, u8),
+}
+
+/// With lifetime
+#[derive(TryUnwrap)]
+enum Nonsense<'a, T> {
+ Ref(&'a T),
+ NoRef,
+ #[try_unwrap(ignore)]
+ NoRefIgnored,
+}
+
+#[derive(TryUnwrap)]
+enum WithConstraints<T>
+where
+ T: Copy,
+{
+ One(T),
+ Two,
+}
+
+#[derive(TryUnwrap)]
+enum KitchenSink<'a, 'b, T1: Copy, T2: Clone>
+where
+ T2: Into<T1> + 'b,
+{
+ Left(&'a T1),
+ Right(&'b T2),
+ OwnBoth(T1, T2),
+ Empty,
+ NeverMind(),
+ NothingToSeeHere(),
+}
+
+/// Single variant enum
+#[derive(TryUnwrap)]
+enum Single {
+ Value(i32),
+}
+
+#[derive(TryUnwrap)]
+#[derive(Debug, PartialEq)]
+#[try_unwrap(ref, ref_mut)]
+enum Tuple<T> {
+ None,
+ Single(T),
+ Double(T, T),
+ Triple(T, T, T),
+}
+
+#[test]
+pub fn test_try_unwrap() {
+ assert_eq!(Maybe::<()>::Nothing.try_unwrap_nothing().ok(), Some(()));
+ assert_eq!((&Maybe::Just(1)).try_unwrap_just_ref().ok(), Some(&1));
+ assert_eq!(
+ (&mut Maybe::Just(42)).try_unwrap_just_mut().ok(),
+ Some(&mut 42)
+ );
+
+ assert_eq!(
+ Maybe::<()>::Nothing.try_unwrap_just().map_err(|e| e.input),
+ Err(Maybe::<()>::Nothing),
+ );
+ assert_eq!(
+ (&Maybe::Just(1))
+ .try_unwrap_nothing_ref()
+ .map_err(|e| e.input),
+ Err(&Maybe::Just(1)),
+ );
+ assert_eq!(
+ (&mut Maybe::Just(42))
+ .try_unwrap_nothing_mut()
+ .map_err(|e| e.to_string()),
+ Err(
+ "Attempt to call `Maybe::try_unwrap_nothing_mut()` on a `Maybe::Just` value"
+ .to_string()
+ ),
+ );
+}
+
+#[test]
+pub fn test_try_unwrap_mut_1() {
+ let mut value = Tuple::Double(1, 12);
+
+ if let Ok((a, b)) = value.try_unwrap_double_mut() {
+ *a = 9;
+ *b = 10;
+ }
+
+ assert_eq!(value, Tuple::Double(9, 10));
+}
+
+#[test]
+pub fn test_try_unwrap_mut_2() {
+ let mut value = Tuple::Single(128);
+
+ if let Ok(x) = value.try_unwrap_single_mut() {
+ *x *= 2;
+ }
+
+ if let Err(e) = value.try_unwrap_none_mut() {
+ let x = *e.input.try_unwrap_single_ref().unwrap_or(&0);
+ *e.input = Tuple::Double(x - 1, x);
+ }
+
+ assert_eq!(value, Tuple::Double(255, 256));
+}
diff --git a/third_party/rust/derive_more/tests/unwrap.rs b/third_party/rust/derive_more/tests/unwrap.rs
new file mode 100644
index 0000000000..dca8fc4c19
--- /dev/null
+++ b/third_party/rust/derive_more/tests/unwrap.rs
@@ -0,0 +1,119 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+#![allow(dead_code)]
+
+use derive_more::Unwrap;
+
+#[derive(Unwrap)]
+enum Either<TLeft, TRight> {
+ Left(TLeft),
+ Right(TRight),
+}
+
+#[derive(Unwrap)]
+#[derive(Debug)]
+#[unwrap(ref, ref_mut)]
+enum Maybe<T> {
+ Nothing,
+ Just(T),
+}
+
+#[derive(Unwrap)]
+enum Color {
+ RGB(u8, u8, u8),
+ CMYK(u8, u8, u8, u8),
+}
+
+/// With lifetime
+#[derive(Unwrap)]
+enum Nonsense<'a, T> {
+ Ref(&'a T),
+ NoRef,
+ #[unwrap(ignore)]
+ NoRefIgnored,
+}
+
+#[derive(Unwrap)]
+enum WithConstraints<T>
+where
+ T: Copy,
+{
+ One(T),
+ Two,
+}
+
+#[derive(Unwrap)]
+enum KitchenSink<'a, 'b, T1: Copy, T2: Clone>
+where
+ T2: Into<T1> + 'b,
+{
+ Left(&'a T1),
+ Right(&'b T2),
+ OwnBoth(T1, T2),
+ Empty,
+ NeverMind(),
+ NothingToSeeHere(),
+}
+
+/// Single variant enum
+#[derive(Unwrap)]
+enum Single {
+ Value(i32),
+}
+
+#[derive(Unwrap)]
+#[derive(Debug, PartialEq)]
+#[unwrap(ref, ref_mut)]
+enum Tuple<T> {
+ None,
+ Single(T),
+ Double(T, T),
+ Triple(T, T, T),
+}
+
+#[test]
+pub fn test_unwrap() {
+ assert_eq!(Maybe::<()>::Nothing.unwrap_nothing(), ());
+ assert_eq!(Maybe::Just(1).unwrap_just(), 1);
+
+ assert_eq!((&Maybe::Just(42)).unwrap_just_ref(), &42);
+ assert_eq!((&mut Maybe::Just(42)).unwrap_just_mut(), &mut 42);
+}
+
+#[test]
+#[should_panic]
+pub fn test_unwrap_panic_1() {
+ Maybe::<()>::Nothing.unwrap_just();
+}
+
+#[test]
+#[should_panic]
+pub fn test_unwrap_panic_2() {
+ Maybe::Just(2).unwrap_nothing();
+}
+
+#[test]
+#[should_panic]
+pub fn test_unwrap_ref_panic() {
+ Maybe::Just(2).unwrap_nothing_ref();
+}
+
+#[test]
+pub fn test_unwrap_mut_1() {
+ let mut value = Tuple::Double(1, 12);
+
+ let (a, b) = value.unwrap_double_mut();
+ *a = 9;
+ *b = 10;
+
+ assert_eq!(value, Tuple::Double(9, 10))
+}
+
+#[test]
+pub fn test_unwrap_mut_2() {
+ let mut value = Tuple::Single(128);
+
+ let x = value.unwrap_single_mut();
+ *x *= 2;
+
+ assert_eq!(value, Tuple::Single(256));
+}