summaryrefslogtreecommitdiffstats
path: root/third_party/rust/darling
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /third_party/rust/darling
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/darling')
-rw-r--r--third_party/rust/darling/.cargo-checksum.json1
-rw-r--r--third_party/rust/darling/CHANGELOG.md224
-rw-r--r--third_party/rust/darling/Cargo.lock216
-rw-r--r--third_party/rust/darling/Cargo.toml58
-rw-r--r--third_party/rust/darling/LICENSE21
-rw-r--r--third_party/rust/darling/README.md138
-rw-r--r--third_party/rust/darling/clippy.toml2
-rwxr-xr-xthird_party/rust/darling/compiletests.sh1
-rw-r--r--third_party/rust/darling/examples/automatic_bounds.rs73
-rw-r--r--third_party/rust/darling/examples/consume_fields.rs175
-rw-r--r--third_party/rust/darling/examples/fallible_read.rs85
-rw-r--r--third_party/rust/darling/examples/shorthand_or_long_field.rs79
-rw-r--r--third_party/rust/darling/examples/supports_struct.rs61
-rw-r--r--third_party/rust/darling/src/lib.rs108
-rw-r--r--third_party/rust/darling/src/macros_public.rs96
-rw-r--r--third_party/rust/darling/tests/accrue_errors.rs102
-rw-r--r--third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.rs12
-rw-r--r--third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.stderr21
-rw-r--r--third_party/rust/darling/tests/compile-fail/not_impl_from_meta.rs16
-rw-r--r--third_party/rust/darling/tests/compile-fail/not_impl_from_meta.stderr33
-rw-r--r--third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.rs18
-rw-r--r--third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.stderr21
-rw-r--r--third_party/rust/darling/tests/compiletests.rs16
-rw-r--r--third_party/rust/darling/tests/computed_bound.rs42
-rw-r--r--third_party/rust/darling/tests/custom_bound.rs25
-rw-r--r--third_party/rust/darling/tests/defaults.rs189
-rw-r--r--third_party/rust/darling/tests/enums_newtype.rs90
-rw-r--r--third_party/rust/darling/tests/enums_struct.rs15
-rw-r--r--third_party/rust/darling/tests/enums_unit.rs14
-rw-r--r--third_party/rust/darling/tests/error.rs54
-rw-r--r--third_party/rust/darling/tests/from_generics.rs175
-rw-r--r--third_party/rust/darling/tests/from_meta.rs66
-rw-r--r--third_party/rust/darling/tests/from_type_param.rs59
-rw-r--r--third_party/rust/darling/tests/from_type_param_default.rs53
-rw-r--r--third_party/rust/darling/tests/from_variant.rs57
-rw-r--r--third_party/rust/darling/tests/generics.rs23
-rw-r--r--third_party/rust/darling/tests/happy_path.rs69
-rw-r--r--third_party/rust/darling/tests/hash_map.rs42
-rw-r--r--third_party/rust/darling/tests/multiple.rs30
-rw-r--r--third_party/rust/darling/tests/newtype.rs26
-rw-r--r--third_party/rust/darling/tests/skip.rs74
-rw-r--r--third_party/rust/darling/tests/split_declaration.rs67
-rw-r--r--third_party/rust/darling/tests/suggestions.rs29
-rw-r--r--third_party/rust/darling/tests/supports.rs90
-rw-r--r--third_party/rust/darling/tests/unsupported_attributes.rs49
45 files changed, 2915 insertions, 0 deletions
diff --git a/third_party/rust/darling/.cargo-checksum.json b/third_party/rust/darling/.cargo-checksum.json
new file mode 100644
index 0000000000..5b94cd2201
--- /dev/null
+++ b/third_party/rust/darling/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"36a132403864fecc7e435509e8339d9f2c0962a451c53357c1d9b08f6d8a36bc","Cargo.lock":"e77a5ba77d6ef12db6c6cdafde228004d938601f46b0bd28a0df7ca836a90142","Cargo.toml":"6ed8f0ac89f171b24a69d4da2c4e8cd711028f0463bd47e9e07026c92f92d16e","LICENSE":"8ea93490d74a5a1b1af3ff71d786271b3f1e5f0bea79ac16e02ec533cef040d6","README.md":"2147b655029789a691d4b9428c836ee55716bea250fba63b8b1c3b4b280d761c","clippy.toml":"0728f8cee5cdb954e4d5c64c9a84c83ff356a913d531412baf4b5852ba6712ef","compiletests.sh":"a255ae505d79b4a40bdc80b215a5384eadee228593d042fbed60e99cc278e220","examples/automatic_bounds.rs":"2950c8d33bb40f095decba1990d7d0bcd48dffc6e9b7cefce2fcb3818ecf1d18","examples/consume_fields.rs":"ce436936441f1f6734f47074e6625ebf64f15180b9c126a58e24aaa33613b59c","examples/fallible_read.rs":"1e5f2b69e436d899209dc8a4deec0dbe3e998f10a6632a79c0876c46f68267b4","examples/shorthand_or_long_field.rs":"ec2e2b155fd0803c80f98d0ba94e8419dd7307012ccfb916b8f752925a295d55","examples/supports_struct.rs":"08c5cc46400a0e5cf811c0d254a37b42de94b34cd04ac801069105bc792051f6","src/lib.rs":"7fb89b93193dbbab4f32327576fa49d8ba677fc32b09a36f84d3c942b2d7ea06","src/macros_public.rs":"7d2ce0c5026227ef7854db11d7a885ad891255438b2e49bbdfda56fa2f92feec","tests/accrue_errors.rs":"4f0f5be65c5cd639b107a6a14e9fb51573b27cfa9210a2182fa5f450bc1d56db","tests/compile-fail/default_expr_wrong_type.rs":"e09889ac3a243bd6096a0ef7076822b146f1481b70aae703e170ea6527071448","tests/compile-fail/default_expr_wrong_type.stderr":"dce0c05f344be36bf66407b459eb1f6abb560b6f5500d4b771d3fd5babc78325","tests/compile-fail/not_impl_from_meta.rs":"20ef167d88ea06967c26a05234d3b1787f0695d45b4ab1150bf9dc77625f9c74","tests/compile-fail/not_impl_from_meta.stderr":"3e52d37d2a5a6f98e4af70389327f9248ea283aac9bdb0660058ec92e23999b8","tests/compile-fail/skip_field_not_impl_default.rs":"5cb7e2e68d7dc42e6508eb0c170869179f127cf641b44f08f6403760f30c469b","tests/compile-fail/skip_field_not_impl_default.stderr":"664f0c2a5c3c85901b65e923b8907870bead9b2781a4c75497eb6df621a0f701","tests/compiletests.rs":"dc2b570d0e0ab4895d7cd039fa9572d507221f2ff2e546a3dacfd9c64fe1c936","tests/computed_bound.rs":"aed9c00f2b8373e9426337137207e5b9341d236adef682bd2c9427db9ce1d1ff","tests/custom_bound.rs":"9b823063b7fc6c6b3b23905405ce7f316e8a937d5c67c416b89642e537bf9110","tests/defaults.rs":"6894fded24b2f9d173b11f54bbe3b640946c6eb6f5ff5492369e8cd84fc217ef","tests/enums_newtype.rs":"ed63735b88fdfd9037580d878be895a311c13d7d8083ee3077f5ab61e754eb7c","tests/enums_struct.rs":"36ca3d4996644d566b45c78d8c343c4a74fcaa2eba96b4e012c8a1819eb6f4c6","tests/enums_unit.rs":"7f94f793e6adc265c6cdc4b657aa237da1ab0be03b03bce23d3e2180cd3e8d03","tests/error.rs":"f5f84991472e184e1167f0fe8d5f2cbad3844c4022987c9eff46b4db2bcc804a","tests/from_generics.rs":"f2c1f98f654c4e6ad3606d7b12ea7ea66782950c05da132e8d7f2f7e1bdf3af0","tests/from_meta.rs":"b9c73340c44a53a43d7234c6030d37d1ab7c63ea2ec2ae1f7f09e5f2d65baa6b","tests/from_type_param.rs":"94d2766d5ae11d69750497225d6aa3c2f34b09fbc8c3580d61f077d7bb41265b","tests/from_type_param_default.rs":"e00e2f0c779753f66b95e5c0106451f65cbd6fbc28e676381d276290da6254b6","tests/from_variant.rs":"48046b156f6c5d9b3e9c3d0b36b5eebaba1d417447e3babf81ed9c74bee3bfcb","tests/generics.rs":"0c2830acf511148d71ecd4a8b5aa17f80e377aa89f7fe0fc10f6db34671d034a","tests/happy_path.rs":"c7a540fc1755cef757aa5e6cd202a49a47a2040facb0c05c167ec62f8ebbc557","tests/hash_map.rs":"c30764bf1845ca81bc1d752dbe0de965ba70cfbb1571884a20a873ed7bf26360","tests/multiple.rs":"1362ec057f4796ffabf7161033b561b51f069b818af7bac85fe66935c62038dd","tests/newtype.rs":"b5ecf605652b194372cab6d6fef96a2dd4b63ac24649cb52ca944ef9647512ad","tests/skip.rs":"11b5f190d6eac837d4a44a7dedd1ba9e623b0c7a8bf2bdc92882e1f8a8d2aeac","tests/split_declaration.rs":"019863370414af227144aac13272fc39a1e256a9ed0bd3ca2dbf1114f1a9e1ba","tests/suggestions.rs":"e9f8ab55718a5853411a4606f1be1473b57fc7a2789f622d0ed807fcd8ac5606","tests/supports.rs":"fd27b20893a1b1078eff077d426fea7d715b8decd12ad1e0b940cfbfd4fbbfba","tests/unsupported_attributes.rs":"96333cd6602a6f18f47563d5faa923e423b2c02f2ae0d09a15e2d3514593c38d"},"package":"c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"} \ No newline at end of file
diff --git a/third_party/rust/darling/CHANGELOG.md b/third_party/rust/darling/CHANGELOG.md
new file mode 100644
index 0000000000..208ca80bc1
--- /dev/null
+++ b/third_party/rust/darling/CHANGELOG.md
@@ -0,0 +1,224 @@
+# Changelog
+
+## v0.14.3 (February 3, 2023)
+
+- Re-export `syn` from `darling` to avoid requiring that consuming crates have a `syn` dependency.
+- Change `<SpannedValue<T> as FromMeta>` impl to more precisely capture the _value_ span, as opposed to the span of the entire item.
+- Add `darling::util::{AsShape, Shape, ShapeSet}` to improve "shape" validation for structs and variants. [#222](https://github.com/TedDriggs/issues/222)
+
+## v0.14.2 (October 26, 2022)
+
+- Derived impls of `FromMeta` will now error on literals, rather than silently ignoring them. [#193](https://github.com/TedDriggs/darling/pull/193)
+- Don't include property paths in compile errors when spans are available. [#203](https://github.com/TedDriggs/darling/pull/203)
+
+## v0.14.1 (April 28, 2022)
+
+- Fix a bug where using a trait that accepts `#[darling(attributes(...))]` without specifying any attributes would emit code that did not compile. [#183](https://github.com/TedDriggs/darling/issues/183)
+- Impl `Clone` for `darling::Error` [#184](https://github.com/TedDriggs/darling/pull/184)
+- Impl `From<darling::Error> for syn::Error` [#184](https://github.com/TedDriggs/darling/pull/184)
+- Add `Error::span` and `Error::explicit_span` methods [#184](https://github.com/TedDriggs/darling/pull/184)
+
+## v0.14.0 (April 13, 2022)
+
+- **BREAKING CHANGE:** Remove many trait impls from `util::Flag`.
+ This type had a number of deref and operator impls that made it usable as sort-of-a-boolean.
+ Real-world usage showed this type is more useful if it's able to carry a span for good errors,
+ and that most of those impls were unnecessary. [#179](https://github.com/TedDriggs/darling/pull/179)
+- Remove need for `#[darling(default)]` on `Option<T>` and `Flag` fields [#161](https://github.com/TedDriggs/darling/issues/161)
+- Improve validation of enum shapes [#178](https://github.com/TedDriggs/darling/pull/178)
+- Bump `proc-macro2` dependency to 1.0.37 [#180](https://github.com/TedDriggs/darling/pull/180)
+- Bump `quote` dependency to 1.0.18 [#180](https://github.com/TedDriggs/darling/pull/180)
+- Bump `syn` dependency to 1.0.91 [#180](https://github.com/TedDriggs/darling/pull/180)
+
+## v0.13.4 (April 6, 2022)
+
+- Impl `FromMeta` for `syn::Visibility` [#173](https://github.com/TedDriggs/darling/pull/173)
+
+## v0.13.3 (April 5, 2022)
+
+- Add `error::Accumulator` for dealing with multiple errors [#164](https://github.com/TedDriggs/darling/pull/164)
+- Impl `FromMeta` for `syn::Type` and its variants [#172](https://github.com/TedDriggs/darling/pulls/172)
+
+## v0.13.2 (March 30, 2022)
+
+- Impl `FromMeta` for `syn::ExprPath` [#169](https://github.com/TedDriggs/darling/issues/169)
+
+## v0.13.1 (December 7, 2021)
+
+- Add `FromAttributes` trait and macro [#151](https://github.com/TedDriggs/darling/issues/151)
+
+## v0.13.0 (May 20, 2021)
+
+- Update darling to 2018 edition [#129](https://github.com/TedDriggs/darling/pull/129)
+- Error on duplicate fields in `#[darling(...)]` attributes [#130](https://github.com/TedDriggs/darling/pull/130)
+- Impl `Copy` for `SpannedValue<T: Copy>`
+- Add `SpannedValue::map_ref`
+
+## v0.13.0-beta (April 20, 2021)
+
+- Update darling to 2018 edition [#129](https://github.com/TedDriggs/darling/pull/129)
+- Error on duplicate fields in `#[darling(...)]` attributes [#130](https://github.com/TedDriggs/darling/pull/130)
+
+## v0.12.4 (April 20, 2021)
+
+- Add `and_then` to derive macros for `darling`
+
+## v0.12.3 (April 8, 2021)
+
+- Fix `FromMeta` impl for `char` not to panic [#126](https://github.com/TedDriggs/darling/pull/126)
+
+## v0.12.2 (February 23, 2021)
+
+- Impl `FromMeta` for `HashMap<Ident, V>` and `HashMap<Path, V>`
+
+## v0.12.1 (February 22, 2021)
+
+- Impl `FromMeta` for `syn::ExprArray` [#122](https://github.com/TedDriggs/darling/pull/122)
+- Remove use of `unreachable` from `darling::ast::Data` [#123](https://github.com/TedDriggs/darling/pull/123)
+- Add `darling::ast::Data::try_empty_from` to avoid panics when trying to read a union body [#123](https://github.com/TedDriggs/darling/pull/123)
+
+## v0.12.0 (January 5, 2021)
+
+- POSSIBLY BREAKING: Derived impls of `FromDeriveInput`, `FromField`, `FromVariant`, and `FromTypeParam` will now error when encountering an attribute `darling` has been asked to parse that isn't a supported shape.
+ Any crates using `darling` that relied on those attributes being silently ignored could see new errors reported in their dependent crates. [#113](https://github.com/TedDriggs/darling/pull/113)
+- Impl `syn::spanned::Spanned` for `darling::util::SpannedValue` [#113](https://github.com/TedDriggs/darling/pull/113)
+- Add `darling::util::parse_attribute_to_meta_list` to provide useful errors during attribute parsing [#113](https://github.com/TedDriggs/darling/pull/113)
+- Add `impl From<syn::Error> for Error` to losslessly propagate `syn` errors [#116](https://github.com/TedDriggs/darling/pull/116)
+
+## v0.11.0 (December 14, 2020)
+
+- Bump minor version due to unexpected breaking change [#107](https://github.com/TedDriggs/darling/issues/107)
+
+## v0.10.3 (December 10, 2020)
+
+- Add `discriminant` magic field when deriving `FromVariant` [#105](https://github.com/TedDriggs/darling/pull/105)
+
+## v0.10.2 (October 30, 2019)
+
+- Bump syn dependency to 1.0.1 [#83](https://github.com/TedDriggs/darling/pull/83)
+
+## v0.10.1 (September 25, 2019)
+
+- Fix test compilation errors [#81](https://github.com/TedDriggs/darling/pull/81)
+
+## v0.10.0 (August 15, 2019)
+
+- Bump syn and quote to 1.0 [#79](https://github.com/TedDriggs/darling/pull/79)
+- Increase rust version to 1.31
+
+## v0.9.0 (March 20, 2019)
+
+- Enable "did you mean" suggestions by default
+- Make `darling_core::{codegen, options}` private [#58](https://github.com/TedDriggs/darling/issues/58)
+- Fix `Override::as_mut`: [#66](https://github.com/TedDriggs/darling/issues/66)
+
+## v0.8.6 (March 18, 2019)
+
+- Added "did you mean" suggestions for unknown fields behind the `suggestions` flag [#60](https://github.com/TedDriggs/issues/60)
+- Added `Error::unknown_field_with_alts` to support the suggestion use-case.
+- Added `ast::Fields::len` and `ast::Fields::is_empty` methods.
+
+## v0.8.5 (February 4, 2019)
+
+- Accept unquoted positive numeric literals [#52](https://github.com/TedDriggs/issues/52)
+- Add `FromMeta` to the `syn::Lit` enum and its variants
+- Improve error message for unexpected literal formats to not say "other"
+
+## v0.8.4 (February 4, 2019)
+
+- Use `syn::Error` to provide precise errors before `proc_macro::Diagnostic` is available
+- Add `diagnostics` feature flag to toggle between stable and unstable error backends
+- Attach error information in more contexts
+- Add `allow_unknown_fields` to support parsing the same attribute multiple times for different macros [#51](https://github.com/darling/issues/51)
+- Proc-macro authors will now see better errors in `darling` attributes
+
+## v0.8.3 (January 21, 2019)
+
+- Attach spans to errors in generated trait impls [#37](https://github.com/darling/issues/37)
+- Attach spans to errors for types with provided bespoke implementations
+- Deprecate `set_span` from 0.8.2, as spans should never be broadened after being initially set
+
+## v0.8.2 (January 17, 2019)
+
+- Add spans to errors to make quality warnings and errors easy in darling. This is blocked on diagnostics stabilizing.
+- Add `darling::util::SpannedValue` so proc-macro authors can remember position information alongside parsed values.
+
+## v0.8.0
+
+- Update dependency on `syn` to 0.15 [#44](https://github.com/darling/pull/44). Thanks to @hcpl
+
+## v0.7.0 (July 24, 2018)
+
+- Update dependencies on `syn` and `proc-macro2`
+- Add `util::IdentString`, which acts as an Ident or its string equivalent
+
+## v0.6.3 (May 22, 2018)
+
+- Add support for `Uses*` traits in where predicates
+
+## v0.6.2 (May 22, 2018)
+
+- Add `usage` module for tracking type param and lifetime usage in generic declarations
+ - Add `UsesTypeParams` and `CollectsTypeParams` traits [#37](https://github.com/darling/issues/37)
+ - Add `UsesLifetimes` and `CollectLifetimes` traits [#41](https://github.com/darling/pull/41)
+- Don't add `FromMeta` bounds to type parameters only used by skipped fields [#40](https://github.com/darling/pull/40)
+
+## v0.6.1 (May 17, 2018)
+
+- Fix an issue where the `syn` update broke shape validation [#36](https://github.com/TedDriggs/darling/issues/36)
+
+## v0.6.0 (May 15, 2018)
+
+### Breaking Changes
+
+- Renamed `FromMetaItem` to `FromMeta`, and renamed `from_meta_item` method to `from_meta`
+- Added dedicated `derive(FromMetaItem)` which panics and redirects users to `FromMeta`
+
+## v0.5.0 (May 10, 2018)
+
+- Add `ast::Generics` and `ast::GenericParam` to work with generics in a manner similar to `ast::Data`
+- Add `ast::GenericParamExt` to support alternate representations of generic parameters
+- Add `util::WithOriginal` to get a parsed representation and syn's own struct for a syntax block
+- Add `FromGenerics` and `FromGenericParam` traits (without derive support)
+- Change generated code for `generics` magic field to invoke `FromGenerics` trait during parsing
+- Add `FromTypeParam` trait [#30](https://github.com/TedDriggs/darling/pull/30). Thanks to @upsuper
+
+## v0.4.0 (April 5, 2018)
+
+- Update dependencies on `proc-macro`, `quote`, and `syn` [#26](https://github.com/TedDriggs/darling/pull/26). Thanks to @hcpl
+
+## v0.3.3 (April 2, 2018)
+
+**YANKED**
+
+## v0.3.2 (March 13, 2018)
+
+- Derive `Default` on `darling::Ignored` (fixes [#25](https://github.com/TedDriggs/darling/issues/25)).
+
+## v0.3.1 (March 7, 2018)
+
+- Support proc-macro2/nightly [#24](https://github.com/TedDriggs/darling/pull/24). Thanks to @kdy1
+
+## v0.3.0 (January 26, 2018)
+
+### Breaking Changes
+
+- Update `syn` to 0.12 [#20](https://github.com/TedDriggs/darling/pull/20). Thanks to @Eijebong
+- Update `quote` to 0.4 [#20](https://github.com/TedDriggs/darling/pull/20). Thanks to @Eijebong
+- Rename magic field `body` in derived `FromDeriveInput` structs to `data` to stay in sync with `syn`
+- Rename magic field `data` in derived `FromVariant` structs to `fields` to stay in sync with `syn`
+
+## v0.2.2 (December 5, 2017)
+
+- Update `lazy_static` to 1.0 [#15](https://github.com/TedDriggs/darling/pull/16). Thanks to @Eijebong
+
+## v0.2.1 (November 28, 2017)
+
+- Add `impl FromMetaItem` for integer types [#15](https://github.com/TedDriggs/darling/pull/15)
+
+## v0.2.0 (June 18, 2017)
+
+- Added support for returning multiple errors from parsing [#5](https://github.com/TedDriggs/darling/pull/5)
+- Derived impls no longer return on first error [#5](https://github.com/TedDriggs/darling/pull/5)
+- Removed default types for `V` and `F` from `ast::Body`
+- Enum variants are automatically converted to snake_case [#12](https://github.com/TedDriggs/darling/pull/12)
diff --git a/third_party/rust/darling/Cargo.lock b/third_party/rust/darling/Cargo.lock
new file mode 100644
index 0000000000..f116d65c3f
--- /dev/null
+++ b/third_party/rust/darling/Cargo.lock
@@ -0,0 +1,216 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "darling"
+version = "0.14.3"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+ "proc-macro2",
+ "quote",
+ "rustversion",
+ "syn",
+ "trybuild",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[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.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+dependencies = [
+ "proc-macro2",
+]
+
+[[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 = "serde"
+version = "1.0.148"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc"
+
+[[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",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.89"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[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.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db29f438342820400f2d9acfec0d363e987a38b2950bdb50a7069ed17b2148ee"
+dependencies = [
+ "glob",
+ "once_cell",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "termcolor",
+ "toml",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+
+[[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/darling/Cargo.toml b/third_party/rust/darling/Cargo.toml
new file mode 100644
index 0000000000..68115fdb63
--- /dev/null
+++ b/third_party/rust/darling/Cargo.toml
@@ -0,0 +1,58 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "darling"
+version = "0.14.3"
+authors = ["Ted Driggs <ted.driggs@outlook.com>"]
+exclude = [
+ "/.travis.yml",
+ "/publish.sh",
+ "/.github/**",
+]
+description = """
+A proc-macro library for reading attributes into structs when
+implementing custom derives.
+"""
+documentation = "https://docs.rs/darling/0.14.3"
+readme = "README.md"
+license = "MIT"
+repository = "https://github.com/TedDriggs/darling"
+
+[dependencies.darling_core]
+version = "=0.14.3"
+
+[dependencies.darling_macro]
+version = "=0.14.3"
+
+[dev-dependencies.proc-macro2]
+version = "1.0.37"
+
+[dev-dependencies.quote]
+version = "1.0.18"
+
+[dev-dependencies.syn]
+version = "1.0.91"
+
+[features]
+default = ["suggestions"]
+diagnostics = ["darling_core/diagnostics"]
+suggestions = ["darling_core/suggestions"]
+
+[target."cfg(compiletests)".dev-dependencies.rustversion]
+version = "1.0.9"
+
+[target."cfg(compiletests)".dev-dependencies.trybuild]
+version = "1.0.38"
+
+[badges.maintenance]
+status = "actively-developed"
diff --git a/third_party/rust/darling/LICENSE b/third_party/rust/darling/LICENSE
new file mode 100644
index 0000000000..0b48eadc9d
--- /dev/null
+++ b/third_party/rust/darling/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Ted Driggs
+
+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/darling/README.md b/third_party/rust/darling/README.md
new file mode 100644
index 0000000000..5f7f9d5b21
--- /dev/null
+++ b/third_party/rust/darling/README.md
@@ -0,0 +1,138 @@
+Darling
+=======
+
+[![Build Status](https://github.com/TedDriggs/darling/workflows/CI/badge.svg)](https://github.com/TedDriggs/darling/actions)
+[![Latest Version](https://img.shields.io/crates/v/darling.svg)](https://crates.io/crates/darling)
+[![Rustc Version 1.31+](https://img.shields.io/badge/rustc-1.31+-lightgray.svg)](https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html)
+
+`darling` is a crate for proc macro authors, which enables parsing attributes into structs. It is heavily inspired by `serde` both in its internals and in its API.
+
+# Benefits
+* Easy and declarative parsing of macro input - make your proc-macros highly controllable with minimal time investment.
+* Great validation and errors, no work required. When users of your proc-macro make a mistake, `darling` makes sure they get error markers at the right place in their source, and provides "did you mean" suggestions for misspelled fields.
+
+# Usage
+`darling` provides a set of traits which can be derived or manually implemented.
+
+1. `FromMeta` is used to extract values from a meta-item in an attribute. Implementations are likely reusable for many libraries, much like `FromStr` or `serde::Deserialize`. Trait implementations are provided for primitives, some std types, and some `syn` types.
+2. `FromDeriveInput` is implemented or derived by each proc-macro crate which depends on `darling`. This is the root for input parsing; it gets access to the identity, generics, and visibility of the target type, and can specify which attribute names should be parsed or forwarded from the input AST.
+3. `FromField` is implemented or derived by each proc-macro crate which depends on `darling`. Structs deriving this trait will get access to the identity (if it exists), type, and visibility of the field.
+4. `FromVariant` is implemented or derived by each proc-macro crate which depends on `darling`. Structs deriving this trait will get access to the identity and contents of the variant, which can be transformed the same as any other `darling` input.
+5. `FromAttributes` is a lower-level version of the more-specific `FromDeriveInput`, `FromField`, and `FromVariant` traits. Structs deriving this trait get a meta-item extractor and error collection which works for any syntax element, including traits, trait items, and functions. This is useful for non-derive proc macros.
+
+## Additional Modules
+* `darling::ast` provides generic types for representing the AST.
+* `darling::usage` provides traits and functions for determining where type parameters and lifetimes are used in a struct or enum.
+* `darling::util` provides helper types with special `FromMeta` implementations, such as `IdentList`.
+
+# Example
+
+```rust,ignore
+#[macro_use]
+extern crate darling;
+extern crate syn;
+
+#[derive(Default, FromMeta)]
+#[darling(default)]
+pub struct Lorem {
+ #[darling(rename = "sit")]
+ ipsum: bool,
+ dolor: Option<String>,
+}
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(my_crate), forward_attrs(allow, doc, cfg))]
+pub struct MyTraitOpts {
+ ident: syn::Ident,
+ attrs: Vec<syn::Attribute>,
+ lorem: Lorem,
+}
+```
+
+The above code will then be able to parse this input:
+
+```rust,ignore
+/// A doc comment which will be available in `MyTraitOpts::attrs`.
+#[derive(MyTrait)]
+#[my_crate(lorem(dolor = "Hello", sit))]
+pub struct ConsumingType;
+```
+
+# Attribute Macros
+Non-derive attribute macros are supported.
+To parse arguments for attribute macros, derive `FromMeta` on the argument receiver type, then pass `&syn::AttributeArgs` to the `from_list` method.
+This will produce a normal `darling::Result<T>` that can be used the same as a result from parsing a `DeriveInput`.
+
+## Macro Code
+```rust,ignore
+use darling::FromMeta;
+use syn::{AttributeArgs, ItemFn};
+use proc_macro::TokenStream;
+
+#[derive(Debug, FromMeta)]
+pub struct MacroArgs {
+ #[darling(default)]
+ timeout_ms: Option<u16>,
+ path: String,
+}
+
+#[proc_macro_attribute]
+fn your_attr(args: TokenStream, input: TokenStream) -> TokenStream {
+ let attr_args = parse_macro_input!(args as AttributeArgs);
+ let _input = parse_macro_input!(input as ItemFn);
+
+ let _args = match MacroArgs::from_list(&attr_args) {
+ Ok(v) => v,
+ Err(e) => { return TokenStream::from(e.write_errors()); }
+ };
+
+ // do things with `args`
+ unimplemented!()
+}
+```
+
+## Consuming Code
+```rust,ignore
+use your_crate::your_attr;
+
+#[your_attr(path = "hello", timeout_ms = 15)]
+fn do_stuff() {
+ println!("Hello");
+}
+```
+
+# Features
+Darling's features are built to work well for real-world projects.
+
+* **Defaults**: Supports struct- and field-level defaults, using the same path syntax as `serde`.
+ Additionally, `Option<T>` and `darling::util::Flag` fields are innately optional; you don't need to declare `#[darling(default)]` for those.
+* **Field Renaming**: Fields can have different names in usage vs. the backing code.
+* **Auto-populated fields**: Structs deriving `FromDeriveInput` and `FromField` can declare properties named `ident`, `vis`, `ty`, `attrs`, and `generics` to automatically get copies of the matching values from the input AST. `FromDeriveInput` additionally exposes `data` to get access to the body of the deriving type, and `FromVariant` exposes `fields`.
+* **Mapping function**: Use `#[darling(map="path")]` or `#[darling(and_then="path")]` to specify a function that runs on the result of parsing a meta-item field. This can change the return type, which enables you to parse to an intermediate form and convert that to the type you need in your struct.
+* **Skip fields**: Use `#[darling(skip)]` to mark a field that shouldn't be read from attribute meta-items.
+* **Multiple-occurrence fields**: Use `#[darling(multiple)]` on a `Vec` field to allow that field to appear multiple times in the meta-item. Each occurrence will be pushed into the `Vec`.
+* **Span access**: Use `darling::util::SpannedValue` in a struct to get access to that meta item's source code span. This can be used to emit warnings that point at a specific field from your proc macro. In addition, you can use `darling::Error::write_errors` to automatically get precise error location details in most cases.
+* **"Did you mean" suggestions**: Compile errors from derived darling trait impls include suggestions for misspelled fields.
+
+## Shape Validation
+Some proc-macros only work on structs, while others need enums whose variants are either unit or newtype variants.
+Darling makes this sort of validation extremely simple.
+On the receiver that derives `FromDeriveInput`, add `#[darling(supports(...))]` and then list the shapes that your macro should accept.
+
+|Name|Description|
+|---|---|
+|`any`|Accept anything|
+|`struct_any`|Accept any struct|
+|`struct_named`|Accept structs with named fields, e.g. `struct Example { field: String }`|
+|`struct_newtype`|Accept newtype structs, e.g. `struct Example(String)`|
+|`struct_tuple`|Accept tuple structs, e.g. `struct Example(String, String)`|
+|`struct_unit`|Accept unit structs, e.g. `struct Example;`|
+|`enum_any`|Accept any enum|
+|`enum_named`|Accept enum variants with named fields|
+|`enum_newtype`|Accept newtype enum variants|
+|`enum_tuple`|Accept tuple enum variants|
+|`enum_unit`|Accept unit enum variants|
+
+Each one is additive, so listing `#[darling(supports(struct_any, enum_newtype))]` would accept all structs and any enum where every variant is a newtype variant.
+
+This can also be used when deriving `FromVariant`, without the `enum_` prefix. \ No newline at end of file
diff --git a/third_party/rust/darling/clippy.toml b/third_party/rust/darling/clippy.toml
new file mode 100644
index 0000000000..ce89b55090
--- /dev/null
+++ b/third_party/rust/darling/clippy.toml
@@ -0,0 +1,2 @@
+msrv = "1.31.0"
+disallowed-names = [] # we want to be able to use placeholder names in tests \ No newline at end of file
diff --git a/third_party/rust/darling/compiletests.sh b/third_party/rust/darling/compiletests.sh
new file mode 100755
index 0000000000..a8ce04288d
--- /dev/null
+++ b/third_party/rust/darling/compiletests.sh
@@ -0,0 +1 @@
+RUSTFLAGS="--cfg=compiletests" cargo +1.65.0 test --test compiletests \ No newline at end of file
diff --git a/third_party/rust/darling/examples/automatic_bounds.rs b/third_party/rust/darling/examples/automatic_bounds.rs
new file mode 100644
index 0000000000..8312afed4c
--- /dev/null
+++ b/third_party/rust/darling/examples/automatic_bounds.rs
@@ -0,0 +1,73 @@
+use darling::{FromDeriveInput, FromMeta};
+
+#[derive(FromMeta, PartialEq, Eq, Debug)]
+enum Volume {
+ Whisper,
+ Talk,
+ Shout,
+}
+
+/// A more complex example showing the ability to skip at a field or struct
+/// level while still tracking which type parameters need to be bounded.
+/// This can be seen by expanding this example using `cargo expand`.
+#[derive(FromMeta)]
+#[allow(dead_code)]
+enum Emphasis<T> {
+ Constant(Volume),
+ Variable(darling::util::PathList),
+ #[darling(skip)]
+ PerPhoneme(Option<T>),
+ Strided {
+ #[darling(skip)]
+ step: Vec<T>,
+ #[darling(multiple)]
+ volume: Vec<Volume>,
+ },
+}
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(speak))]
+struct SpeakingOptions<T, U> {
+ max_volume: U,
+ #[darling(skip, default)]
+ additional_data: Vec<T>,
+}
+
+#[derive(Default)]
+struct Phoneme {
+ #[allow(dead_code)]
+ first: String,
+}
+
+// This is probably the holy grail for `darling`'s own internal use-case:
+// Auto-apply `Default` bound to skipped *field* types in `where` clause.
+impl<T, U> Default for SpeakingOptions<T, U>
+where
+ Vec<T>: Default,
+ U: Default,
+{
+ fn default() -> Self {
+ Self {
+ max_volume: Default::default(),
+ additional_data: Default::default(),
+ }
+ }
+}
+
+fn main() {
+ let derive_input = syn::parse_str(
+ r#"
+ #[derive(Speak)]
+ #[speak(max_volume = "shout")]
+ enum HtmlElement {
+ Div(String)
+ }
+ "#,
+ )
+ .unwrap();
+
+ let parsed: SpeakingOptions<Phoneme, Volume> =
+ FromDeriveInput::from_derive_input(&derive_input).unwrap();
+ assert_eq!(parsed.max_volume, Volume::Shout);
+ assert_eq!(parsed.additional_data.len(), 0);
+}
diff --git a/third_party/rust/darling/examples/consume_fields.rs b/third_party/rust/darling/examples/consume_fields.rs
new file mode 100644
index 0000000000..f5cd435b90
--- /dev/null
+++ b/third_party/rust/darling/examples/consume_fields.rs
@@ -0,0 +1,175 @@
+// The use of fields in debug print commands does not count as "used",
+// which causes the fields to trigger an unwanted dead code warning.
+#![allow(dead_code)]
+
+//! This example shows how to do struct and field parsing using darling.
+
+use darling::{ast, FromDeriveInput, FromField, FromMeta};
+use proc_macro2::TokenStream;
+use quote::{quote, ToTokens};
+use syn::parse_str;
+
+/// A speaking volume. Deriving `FromMeta` will cause this to be usable
+/// as a string value for a meta-item key.
+#[derive(Debug, Clone, Copy, FromMeta)]
+#[darling(default)]
+enum Volume {
+ Normal,
+ Whisper,
+ Shout,
+}
+
+impl Default for Volume {
+ fn default() -> Self {
+ Volume::Normal
+ }
+}
+
+/// Support parsing from a full derive input. Unlike FromMeta, this isn't
+/// composable; each darling-dependent crate should have its own struct to handle
+/// when its trait is derived.
+#[derive(Debug, FromDeriveInput)]
+// This line says that we want to process all attributes declared with `my_trait`,
+// and that darling should panic if this receiver is given an enum.
+#[darling(attributes(my_trait), supports(struct_any))]
+struct MyInputReceiver {
+ /// The struct ident.
+ ident: syn::Ident,
+
+ /// The type's generics. You'll need these any time your trait is expected
+ /// to work with types that declare generics.
+ generics: syn::Generics,
+
+ /// Receives the body of the struct or enum. We don't care about
+ /// struct fields because we previously told darling we only accept structs.
+ data: ast::Data<(), MyFieldReceiver>,
+
+ /// The Input Receiver demands a volume, so use `Volume::Normal` if the
+ /// caller doesn't provide one.
+ #[darling(default)]
+ volume: Volume,
+}
+
+impl ToTokens for MyInputReceiver {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let MyInputReceiver {
+ ref ident,
+ ref generics,
+ ref data,
+ volume,
+ } = *self;
+
+ let (imp, ty, wher) = generics.split_for_impl();
+ let fields = data
+ .as_ref()
+ .take_struct()
+ .expect("Should never be enum")
+ .fields;
+
+ // Generate the format string which shows each field and its name
+ let fmt_string = fields
+ .iter()
+ .enumerate()
+ .map(|(i, f)| {
+ // We have to preformat the ident in this case so we can fall back
+ // to the field index for unnamed fields. It's not easy to read,
+ // unfortunately.
+ format!(
+ "{} = {{}}",
+ f.ident
+ .as_ref()
+ .map(|v| format!("{}", v))
+ .unwrap_or_else(|| format!("{}", i))
+ )
+ })
+ .collect::<Vec<_>>()
+ .join(", ");
+
+ // Generate the actual values to fill the format string.
+ let field_list = fields
+ .into_iter()
+ .enumerate()
+ .map(|(i, f)| {
+ let field_volume = f.volume.unwrap_or(volume);
+
+ // This works with named or indexed fields, so we'll fall back to the index so we can
+ // write the output as a key-value pair.
+ let field_ident = f.ident
+ .as_ref()
+ .map(|v| quote!(#v))
+ .unwrap_or_else(|| {
+ let i = syn::Index::from(i);
+ quote!(#i)
+ });
+
+ match field_volume {
+ Volume::Normal => quote!(self.#field_ident),
+ Volume::Shout => {
+ quote!(::std::string::ToString::to_string(&self.#field_ident).to_uppercase())
+ }
+ Volume::Whisper => {
+ quote!(::std::string::ToString::to_string(&self.#field_ident).to_lowercase())
+ }
+ }
+ })
+ .collect::<Vec<_>>();
+
+ tokens.extend(quote! {
+ impl #imp Speak for #ident #ty #wher {
+ fn speak(&self, writer: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(writer, #fmt_string, #(#field_list),*)
+ }
+ }
+ });
+ }
+}
+
+#[derive(Debug, FromField)]
+#[darling(attributes(my_trait))]
+struct MyFieldReceiver {
+ /// Get the ident of the field. For fields in tuple or newtype structs or
+ /// enum bodies, this can be `None`.
+ ident: Option<syn::Ident>,
+
+ /// This magic field name pulls the type from the input.
+ ty: syn::Type,
+
+ /// We declare this as an `Option` so that during tokenization we can write
+ /// `field.volume.unwrap_or(derive_input.volume)` to facilitate field-level
+ /// overrides of struct-level settings.
+ ///
+ /// Because this field is an `Option`, we don't need to include `#[darling(default)]`
+ volume: Option<Volume>,
+}
+
+fn main() {
+ let input = r#"#[derive(MyTrait)]
+#[my_trait(volume = "shout")]
+pub struct Foo {
+ #[my_trait(volume = "whisper")]
+ bar: bool,
+
+ baz: i64,
+}"#;
+
+ let parsed = parse_str(input).unwrap();
+ let receiver = MyInputReceiver::from_derive_input(&parsed).unwrap();
+ let tokens = quote!(#receiver);
+
+ println!(
+ r#"
+INPUT:
+
+{}
+
+PARSED AS:
+
+{:?}
+
+EMITS:
+
+{}
+ "#,
+ input, receiver, tokens
+ );
+}
diff --git a/third_party/rust/darling/examples/fallible_read.rs b/third_party/rust/darling/examples/fallible_read.rs
new file mode 100644
index 0000000000..850465e82d
--- /dev/null
+++ b/third_party/rust/darling/examples/fallible_read.rs
@@ -0,0 +1,85 @@
+//! This example demonstrates techniques for performing custom error handling
+//! in a derive-input receiver.
+//!
+//! 1. Using `darling::Result` as a carrier to preserve the error for later display
+//! 1. Using `Result<T, syn::Meta>` to attempt a recovery in imperative code
+//! 1. Using the `map` darling meta-item to post-process a field before returning
+//! 1. Using the `and_then` darling meta-item to post-process the receiver before returning
+
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_str;
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(my_trait), and_then = "MyInputReceiver::autocorrect")]
+pub struct MyInputReceiver {
+ /// This field must be present and a string or else parsing will panic.
+ #[darling(map = "MyInputReceiver::make_string_shouty")]
+ name: String,
+
+ /// If this field fails to parse, the struct can still be built; the field
+ /// will contain the error. The consuming struct can then decide if this
+ /// blocks code generation. If so, panic or fail in `and_then`.
+ frequency: darling::Result<i64>,
+
+ /// If this field fails to parse, the struct can still be built; the field
+ /// will contain an `Err` with the original `syn::Meta`. This can be used
+ /// for alternate parsing attempts before panicking.
+ amplitude: Result<u64, syn::Meta>,
+}
+
+impl MyInputReceiver {
+ /// This function will be called by `darling` _after_ it's finished parsing the
+ /// `name` field but before initializing `name` with the resulting value. It's
+ /// a good place for transforms that are easiest to express on already-built
+ /// types.
+ fn make_string_shouty(s: String) -> String {
+ s.to_uppercase()
+ }
+
+ /// This function will be called by `darling` _after_ it's finished parsing the
+ /// input but before returning to the caller. This is a good place to initialize
+ /// skipped fields or to perform corrections that don't lend themselves to being
+ /// done elsewhere.
+ fn autocorrect(self) -> darling::Result<Self> {
+ let Self {
+ name,
+ frequency,
+ amplitude,
+ } = self;
+
+ // Amplitude doesn't have a sign, so if we received a negative number then
+ // we'll go ahead and make it positive.
+ let amplitude = match amplitude {
+ Ok(amp) => amp,
+ Err(mi) => (i64::from_meta(&mi)?).abs() as u64,
+ };
+
+ Ok(Self {
+ name,
+ frequency,
+ amplitude: Ok(amplitude),
+ })
+ }
+}
+
+fn main() {
+ let input = r#"#[derive(MyTrait)]
+#[my_trait(name="Jon", amplitude = "-1", frequency = 1)]
+pub struct Foo;"#;
+
+ let parsed = parse_str(input).unwrap();
+ let receiver = MyInputReceiver::from_derive_input(&parsed).unwrap();
+
+ println!(
+ r#"
+INPUT:
+
+{}
+
+PARSED AS:
+
+{:?}
+ "#,
+ input, receiver
+ );
+}
diff --git a/third_party/rust/darling/examples/shorthand_or_long_field.rs b/third_party/rust/darling/examples/shorthand_or_long_field.rs
new file mode 100644
index 0000000000..750d83efbc
--- /dev/null
+++ b/third_party/rust/darling/examples/shorthand_or_long_field.rs
@@ -0,0 +1,79 @@
+//! Example showing potentially-nested meta item parsing with `darling::util::Override`.
+//!
+//! Based on https://stackoverflow.com/q/68046070/86381 by https://github.com/peterjoel
+
+// The use of fields in debug print commands does not count as "used",
+// which causes the fields to trigger an unwanted dead code warning.
+#![allow(dead_code)]
+
+use std::borrow::Cow;
+
+use darling::{util::Override, FromDeriveInput, FromMeta};
+use syn::{Ident, Path};
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(myderive))]
+struct MyDeriveInput {
+ ident: Ident,
+ /// We can infer the right "table" behavior for this derive, but we want the caller to be
+ /// explicit that they're expecting the inference behavior to avoid cluttering some hypothetical
+ /// database. Therefore this field is required, but can take word form or key-value form.
+ ///
+ /// To make this field optional, we could add `#[darling(default)]`, or we could
+ /// wrap it in `Option` if the presence or absence of the word makes a difference.
+ table: Override<Table>,
+}
+
+impl MyDeriveInput {
+ fn table(&self) -> Cow<'_, Table> {
+ match &self.table {
+ Override::Explicit(value) => Cow::Borrowed(value),
+ Override::Inherit => Cow::Owned(Table {
+ name: self.ident.to_string(),
+ value: None,
+ }),
+ }
+ }
+}
+
+#[derive(Debug, Clone, FromMeta)]
+struct Table {
+ name: String,
+ value: Option<Path>,
+}
+
+fn from_str(s: &str) -> darling::Result<MyDeriveInput> {
+ FromDeriveInput::from_derive_input(&syn::parse_str(s)?)
+}
+
+fn main() {
+ let missing = from_str(
+ r#"
+ #[derive(MyTrait)]
+ struct Foo(u64);
+ "#,
+ )
+ .unwrap_err();
+
+ let short_form = from_str(
+ r#"
+ #[derive(MyTrait)]
+ #[myderive(table)]
+ struct Foo(u64);
+ "#,
+ )
+ .unwrap();
+
+ let long_form = from_str(
+ r#"
+ #[derive(MyTrait)]
+ #[myderive(table(name = "Custom"))]
+ struct Foo(u64);
+ "#,
+ )
+ .unwrap();
+
+ println!("Error when missing: {}", missing);
+ println!("Short form: {:?}", short_form.table());
+ println!("Long form: {:?}", long_form.table());
+}
diff --git a/third_party/rust/darling/examples/supports_struct.rs b/third_party/rust/darling/examples/supports_struct.rs
new file mode 100644
index 0000000000..97a5bb9c05
--- /dev/null
+++ b/third_party/rust/darling/examples/supports_struct.rs
@@ -0,0 +1,61 @@
+// The use of fields in debug print commands does not count as "used",
+// which causes the fields to trigger an unwanted dead code warning.
+#![allow(dead_code)]
+
+use darling::{ast, util, FromDeriveInput, FromField};
+use syn::{Ident, Type};
+
+#[derive(Debug, FromField)]
+#[darling(attributes(lorem))]
+pub struct LoremField {
+ ident: Option<Ident>,
+ ty: Type,
+ #[darling(default)]
+ skip: bool,
+}
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(lorem), supports(struct_named))]
+pub struct Lorem {
+ ident: Ident,
+ data: ast::Data<util::Ignored, LoremField>,
+}
+
+fn main() {
+ let good_input = r#"#[derive(Lorem)]
+pub struct Foo {
+ #[lorem(skip)]
+ bar: bool,
+
+ baz: i64,
+}"#;
+
+ let bad_input = r#"#[derive(Lorem)]
+ pub struct BadFoo(String, u32);"#;
+
+ let parsed = syn::parse_str(good_input).unwrap();
+ let receiver = Lorem::from_derive_input(&parsed).unwrap();
+ let wrong_shape_parsed = syn::parse_str(bad_input).unwrap();
+ let wrong_shape = Lorem::from_derive_input(&wrong_shape_parsed).expect_err("Shape was wrong");
+
+ println!(
+ r#"
+INPUT:
+
+{}
+
+PARSED AS:
+
+{:?}
+
+BAD INPUT:
+
+{}
+
+PRODUCED ERROR:
+
+{}
+ "#,
+ good_input, receiver, bad_input, wrong_shape
+ );
+}
diff --git a/third_party/rust/darling/src/lib.rs b/third_party/rust/darling/src/lib.rs
new file mode 100644
index 0000000000..b2be36d0cb
--- /dev/null
+++ b/third_party/rust/darling/src/lib.rs
@@ -0,0 +1,108 @@
+//! # Darling
+//! Darling is a tool for declarative attribute parsing in proc macro implementations.
+//!
+//!
+//! ## Design
+//! Darling takes considerable design inspiration from [`serde`](https://serde.rs). A data structure that can be
+//! read from any attribute implements `FromMeta` (or has an implementation automatically
+//! generated using `derive`). Any crate can provide `FromMeta` implementations, even one not
+//! specifically geared towards proc-macro authors.
+//!
+//! Proc-macro crates should provide their own structs which implement or derive `FromDeriveInput`,
+//! `FromField`, `FromVariant`, `FromGenerics`, _et alia_ to gather settings relevant to their operation.
+//!
+//! ## Attributes
+//! There are a number of attributes that `darling` exposes to enable finer-grained control over the code
+//! it generates.
+//!
+//! * **Field renaming**: You can use `#[darling(rename="new_name")]` on a field to change the name Darling looks for.
+//! You can also use `#[darling(rename_all="...")]` at the struct or enum level to apply a casing rule to all fields or variants.
+//! * **Map function**: You can use `#[darling(map="path::to::function")]` to run code on a field before its stored in the struct.
+//! * **Default values**: You can use `#[darling(default)]` at the type or field level to use that type's default value to fill
+//! in values not specified by the caller.
+//! * **Skipped fields**: You can skip a variant or field using `#[darling(skip)]`. Fields marked with this will fall back to
+//! `Default::default()` for their value, but you can override that with an explicit default or a value from the type-level default.
+//!
+//! ## Forwarded Fields
+//! All derivable traits except `FromMeta` support forwarding some fields from the input AST to the derived struct.
+//! These fields are matched up by identifier **before** `rename` attribute values are considered,
+//! allowing you to use their names for your own properties.
+//! The deriving struct is responsible for making sure the types of fields it chooses to declare are compatible with this table.
+//!
+//! A deriving struct is free to include or exclude any of the fields below.
+//!
+//! ### `FromDeriveInput`
+//! |Field name|Type|Meaning|
+//! |---|---|---|
+//! |`ident`|`syn::Ident`|The identifier of the passed-in type|
+//! |`vis`|`syn::Visibility`|The visibility of the passed-in type|
+//! |`generics`|`T: darling::FromGenerics`|The generics of the passed-in type. This can be `syn::Generics`, `darling::ast::Generics`, or any compatible type.|
+//! |`data`|`darling::ast::Data`|The body of the passed-in type|
+//! |`attrs`|`Vec<syn::Attribute>`|The forwarded attributes from the passed in type. These are controlled using the `forward_attrs` attribute.|
+//!
+//! ### `FromField`
+//! |Field name|Type|Meaning|
+//! |---|---|---|
+//! |`ident`|`Option<syn::Ident>`|The identifier of the passed-in field, or `None` for tuple fields|
+//! |`vis`|`syn::Visibility`|The visibility of the passed-in field|
+//! |`ty`|`syn::Type`|The type of the passed-in field|
+//! |`attrs`|`Vec<syn::Attribute>`|The forwarded attributes from the passed in field. These are controlled using the `forward_attrs` attribute.|
+//!
+//! ### `FromTypeParam`
+//! |Field name|Type|Meaning|
+//! |---|---|---|
+//! |`ident`|`syn::Ident`|The identifier of the passed-in type param|
+//! |`bounds`|`Vec<syn::TypeParamBound>`|The bounds applied to the type param|
+//! |`default`|`Option<syn::Type>`|The default type of the parameter, if one exists|
+//! |`attrs`|`Vec<syn::Attribute>`|The forwarded attributes from the passed in type param. These are controlled using the `forward_attrs` attribute.|
+//!
+//! ### `FromVariant`
+//! |Field name|Type|Meaning|
+//! |---|---|---|
+//! |`ident`|`syn::Ident`|The identifier of the passed-in variant|
+//! |`discriminant`|`Option<syn::Expr>`|For a variant such as `Example = 2`, the `2`|
+//! |`fields`|`darling::ast::Fields<T> where T: FromField`|The fields associated with the variant|
+//! |`attrs`|`Vec<syn::Attribute>`|The forwarded attributes from the passed in variant. These are controlled using the `forward_attrs` attribute.|
+
+extern crate core;
+
+#[allow(unused_imports)]
+#[macro_use]
+extern crate darling_macro;
+
+#[doc(hidden)]
+pub use darling_macro::*;
+
+#[doc(inline)]
+pub use darling_core::{
+ FromAttributes, FromDeriveInput, FromField, FromGenericParam, FromGenerics, FromMeta,
+ FromTypeParam, FromVariant,
+};
+
+#[doc(inline)]
+pub use darling_core::{Error, Result};
+
+#[doc(inline)]
+pub use darling_core::{ast, error, usage, util};
+
+// XXX exported so that `ExtractAttribute::extractor` can convert a path into tokens.
+// This is likely to change in the future, so only generated code should depend on this export.
+#[doc(hidden)]
+pub use darling_core::ToTokens;
+
+/// Core/std trait re-exports. This should help produce generated code which doesn't
+/// depend on `std` unnecessarily, and avoids problems caused by aliasing `std` or any
+/// of the referenced types.
+#[doc(hidden)]
+pub mod export {
+ pub use core::convert::From;
+ pub use core::default::Default;
+ pub use core::option::Option::{self, None, Some};
+ pub use core::result::Result::{self, Err, Ok};
+ pub use darling_core::syn;
+ pub use std::string::ToString;
+ pub use std::vec::Vec;
+}
+
+#[macro_use]
+mod macros_public;
diff --git a/third_party/rust/darling/src/macros_public.rs b/third_party/rust/darling/src/macros_public.rs
new file mode 100644
index 0000000000..c264fcc2a8
--- /dev/null
+++ b/third_party/rust/darling/src/macros_public.rs
@@ -0,0 +1,96 @@
+//! Macros that should be exported from both `darling_core` and `darling`.
+//! Note that these are **sym-linked** into the main code, and so cannot declare on items that are exported differently
+//! in `darling_core` vs. `darling`.
+
+/// Generator for `UsesTypeParam` impls that unions the used type parameters of the selected fields.
+///
+/// # Usage
+/// The macro takes the type implementing the trait as the first argument, then a comma-separated list of
+/// fields for the rest of its arguments.
+///
+/// The type of each passed-in field must implement `UsesTypeParams`, or the resulting code won't compile.
+///
+/// ```rust
+/// # extern crate syn;
+/// # use darling_core::uses_type_params;
+/// #
+/// struct MyField {
+/// ty: syn::Type,
+/// }
+///
+/// uses_type_params!(MyField, ty);
+///
+/// fn main() {
+/// // no test run
+/// }
+/// ```
+///
+/// `darling` cannot derive this trait automatically, as it doesn't know which information extracted from
+/// proc-macro input is meant to constitute "using" the type parameter, but crate consumers should
+/// implement it by hand or using the macro.
+#[macro_export]
+macro_rules! uses_type_params {
+ ($impl_type:ty, $accessor:ident) => {
+ impl $crate::usage::UsesTypeParams for $impl_type {
+ fn uses_type_params<'gen>(
+ &self,
+ options: &$crate::usage::Options,
+ type_set: &'gen $crate::usage::IdentSet
+ ) -> $crate::usage::IdentRefSet<'gen> {
+ self.$accessor.uses_type_params(options, type_set)
+ }
+ }
+ };
+ ($impl_type:ty, $first:ident, $($field:ident),+) => {
+ impl $crate::usage::UsesTypeParams for $impl_type {
+ fn uses_type_params<'gen>(
+ &self,
+ options: &$crate::usage::Options,
+ type_set: &'gen $crate::usage::IdentSet
+ ) -> $crate::usage::IdentRefSet<'gen> {
+ let mut hits = self.$first.uses_type_params(options, type_set);
+ $(
+ hits.extend(self.$field.uses_type_params(options, type_set));
+ )*
+ hits
+ }
+ }
+ };
+}
+
+/// Generator for `UsesLifetimes` impls that unions the used lifetimes of the selected fields.
+///
+/// # Usage
+/// The macro takes the type implementing the trait as the first argument, then a comma-separated list of
+/// fields for the rest of its arguments.
+///
+/// The type of each passed-in field must implement `UsesLifetimes`, or the resulting code won't compile.
+#[macro_export]
+macro_rules! uses_lifetimes {
+ ($impl_type:ty, $accessor:ident) => {
+ impl $crate::usage::UsesLifetimes for $impl_type {
+ fn uses_lifetimes<'gen>(
+ &self,
+ options: &$crate::usage::Options,
+ type_set: &'gen $crate::usage::LifetimeSet
+ ) -> $crate::usage::LifetimeRefSet<'gen> {
+ self.$accessor.uses_lifetimes(options, type_set)
+ }
+ }
+ };
+ ($impl_type:ty, $first:ident, $($field:ident),+) => {
+ impl $crate::usage::UsesLifetimes for $impl_type {
+ fn uses_lifetimes<'gen>(
+ &self,
+ options: &$crate::usage::Options,
+ type_set: &'gen $crate::usage::LifetimeSet
+ ) -> $crate::usage::LifetimeRefSet<'gen> {
+ let mut hits = self.$first.uses_lifetimes(options, type_set);
+ $(
+ hits.extend(self.$field.uses_lifetimes(options, type_set));
+ )*
+ hits
+ }
+ }
+ };
+}
diff --git a/third_party/rust/darling/tests/accrue_errors.rs b/third_party/rust/darling/tests/accrue_errors.rs
new file mode 100644
index 0000000000..e8799c43cb
--- /dev/null
+++ b/third_party/rust/darling/tests/accrue_errors.rs
@@ -0,0 +1,102 @@
+#![allow(dead_code)]
+//! These tests verify that multiple errors will be collected up from throughout
+//! the parsing process and returned correctly to the caller.
+
+use darling::{ast, FromDeriveInput, FromField, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(accrue))]
+struct Lorem {
+ ipsum: String,
+ dolor: Dolor,
+ data: ast::Data<(), LoremField>,
+}
+
+#[derive(Debug, FromMeta)]
+struct Dolor {
+ sit: bool,
+}
+
+#[derive(Debug, FromField)]
+#[darling(attributes(accrue))]
+struct LoremField {
+ ident: Option<syn::Ident>,
+ aliased_as: syn::Ident,
+}
+
+#[test]
+fn bad_type_and_missing_fields() {
+ let input = parse_quote! {
+ #[accrue(ipsum = true, dolor(amet = "Hi"))]
+ pub struct NonConforming {
+ foo: ()
+ }
+ };
+
+ let s_result: ::darling::Error = Lorem::from_derive_input(&input).unwrap_err();
+ let err = s_result.flatten();
+ println!("{}", err);
+ assert_eq!(3, err.len());
+}
+
+#[test]
+fn body_only_issues() {
+ let input = parse_quote! {
+ #[accrue(ipsum = "Hello", dolor(sit))]
+ pub struct NonConforming {
+ foo: (),
+ bar: bool,
+ }
+ };
+
+ let s_err = Lorem::from_derive_input(&input).unwrap_err();
+ println!("{:?}", s_err);
+ assert_eq!(2, s_err.len());
+}
+
+#[derive(Debug, FromMeta)]
+enum Week {
+ Monday,
+ Tuesday { morning: bool, afternoon: String },
+ Wednesday(Dolor),
+}
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(accrue))]
+struct Month {
+ schedule: Week,
+}
+
+#[test]
+fn error_in_enum_fields() {
+ let input = parse_quote! {
+ #[accrue(schedule(tuesday(morning = "yes")))]
+ pub struct NonConforming {
+ foo: (),
+ bar: bool,
+ }
+ };
+
+ let s_err = Month::from_derive_input(&input).unwrap_err();
+ assert_eq!(2, s_err.len());
+ let err = s_err.flatten();
+ // TODO add tests to check location path is correct
+ println!("{}", err);
+}
+
+#[test]
+fn error_in_newtype_variant() {
+ let input = parse_quote! {
+ #[accrue(schedule(wednesday(sit = "yes")))]
+ pub struct NonConforming {
+ foo: (),
+ bar: bool,
+ }
+ };
+
+ let s_err = Month::from_derive_input(&input).unwrap_err();
+ assert_eq!(1, s_err.len());
+ println!("{}", s_err);
+ println!("{}", s_err.flatten());
+}
diff --git a/third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.rs b/third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.rs
new file mode 100644
index 0000000000..cd9a0fd1ee
--- /dev/null
+++ b/third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.rs
@@ -0,0 +1,12 @@
+use darling::FromMeta;
+
+#[derive(FromMeta)]
+struct Receiver {
+ #[darling(default = "usize::default")]
+ not_u32: String,
+
+ #[darling(multiple, default = "usize::default")]
+ also_not_u32: Vec<String>,
+}
+
+fn main() {}
diff --git a/third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.stderr b/third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.stderr
new file mode 100644
index 0000000000..a8b7c502bf
--- /dev/null
+++ b/third_party/rust/darling/tests/compile-fail/default_expr_wrong_type.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> tests/compile-fail/default_expr_wrong_type.rs:5:25
+ |
+5 | #[darling(default = "usize::default")]
+ | ^^^^^^^^^^^^^^^^ expected struct `String`, found `usize`
+ |
+help: try using a conversion method
+ |
+5 | #[darling(default = "usize::default".to_string())]
+ | ++++++++++++
+5 | #[darling(default = "usize::default".to_string())]
+ | ++++++++++++
+
+error[E0308]: mismatched types
+ --> tests/compile-fail/default_expr_wrong_type.rs:8:35
+ |
+8 | #[darling(multiple, default = "usize::default")]
+ | ^^^^^^^^^^^^^^^^ expected struct `Vec`, found `usize`
+ |
+ = note: expected struct `Vec<String>`
+ found type `usize`
diff --git a/third_party/rust/darling/tests/compile-fail/not_impl_from_meta.rs b/third_party/rust/darling/tests/compile-fail/not_impl_from_meta.rs
new file mode 100644
index 0000000000..f27d716391
--- /dev/null
+++ b/third_party/rust/darling/tests/compile-fail/not_impl_from_meta.rs
@@ -0,0 +1,16 @@
+use darling::FromMeta;
+
+struct NotImplFm;
+
+#[derive(FromMeta)]
+struct OuterFm {
+ inner: NotImplFm,
+}
+
+#[derive(darling::FromDeriveInput)]
+#[darling(attributes(hello))]
+struct OuterFdi {
+ inner: NotImplFm,
+}
+
+fn main() {}
diff --git a/third_party/rust/darling/tests/compile-fail/not_impl_from_meta.stderr b/third_party/rust/darling/tests/compile-fail/not_impl_from_meta.stderr
new file mode 100644
index 0000000000..a166a6fcff
--- /dev/null
+++ b/third_party/rust/darling/tests/compile-fail/not_impl_from_meta.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the trait bound `NotImplFm: FromMeta` is not satisfied
+ --> tests/compile-fail/not_impl_from_meta.rs:7:12
+ |
+7 | inner: NotImplFm,
+ | ^^^^^^^^^ the trait `FromMeta` is not implemented for `NotImplFm`
+ |
+ = help: the following other types implement trait `FromMeta`:
+ ()
+ Arc<T>
+ AtomicBool
+ ExprArray
+ ExprPath
+ Flag
+ HashMap<String, V, S>
+ HashMap<proc_macro2::Ident, V, S>
+ and $N others
+
+error[E0277]: the trait bound `NotImplFm: FromMeta` is not satisfied
+ --> tests/compile-fail/not_impl_from_meta.rs:13:12
+ |
+13 | inner: NotImplFm,
+ | ^^^^^^^^^ the trait `FromMeta` is not implemented for `NotImplFm`
+ |
+ = help: the following other types implement trait `FromMeta`:
+ ()
+ Arc<T>
+ AtomicBool
+ ExprArray
+ ExprPath
+ Flag
+ HashMap<String, V, S>
+ HashMap<proc_macro2::Ident, V, S>
+ and $N others
diff --git a/third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.rs b/third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.rs
new file mode 100644
index 0000000000..f0d44c7798
--- /dev/null
+++ b/third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.rs
@@ -0,0 +1,18 @@
+use darling::FromMeta;
+
+#[derive(FromMeta)]
+struct NoDefault(String);
+
+#[derive(FromMeta)]
+struct Recevier {
+ #[darling(skip)]
+ skipped: NoDefault,
+
+ #[darling(skip = true)]
+ explicitly_skipped: NoDefault,
+
+ #[darling(skip = false)]
+ not_skipped_no_problem: NoDefault,
+}
+
+fn main() {}
diff --git a/third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.stderr b/third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.stderr
new file mode 100644
index 0000000000..de46982c24
--- /dev/null
+++ b/third_party/rust/darling/tests/compile-fail/skip_field_not_impl_default.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the trait bound `NoDefault: std::default::Default` is not satisfied
+ --> tests/compile-fail/skip_field_not_impl_default.rs:8:15
+ |
+8 | #[darling(skip)]
+ | ^^^^ the trait `std::default::Default` is not implemented for `NoDefault`
+ |
+help: consider annotating `NoDefault` with `#[derive(Default)]`
+ |
+4 | #[derive(Default)]
+ |
+
+error[E0277]: the trait bound `NoDefault: std::default::Default` is not satisfied
+ --> tests/compile-fail/skip_field_not_impl_default.rs:11:22
+ |
+11 | #[darling(skip = true)]
+ | ^^^^ the trait `std::default::Default` is not implemented for `NoDefault`
+ |
+help: consider annotating `NoDefault` with `#[derive(Default)]`
+ |
+4 | #[derive(Default)]
+ |
diff --git a/third_party/rust/darling/tests/compiletests.rs b/third_party/rust/darling/tests/compiletests.rs
new file mode 100644
index 0000000000..00a5b3296f
--- /dev/null
+++ b/third_party/rust/darling/tests/compiletests.rs
@@ -0,0 +1,16 @@
+#![cfg(compiletests)]
+
+#[rustversion::stable(1.65)]
+#[test]
+fn compile_test() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/compile-fail/*.rs");
+}
+
+#[rustversion::not(stable(1.65))]
+#[test]
+fn wrong_rustc_version() {
+ panic!(
+ "This is not the expected version of rustc. Error messages vary across compiler versions so tests may produce spurious errors"
+ );
+}
diff --git a/third_party/rust/darling/tests/computed_bound.rs b/third_party/rust/darling/tests/computed_bound.rs
new file mode 100644
index 0000000000..abdb1022c1
--- /dev/null
+++ b/third_party/rust/darling/tests/computed_bound.rs
@@ -0,0 +1,42 @@
+use darling::{FromDeriveInput, FromMeta};
+
+fn parse<T: FromDeriveInput>(src: &str) -> T {
+ let ast = syn::parse_str(src).unwrap();
+ FromDeriveInput::from_derive_input(&ast).unwrap()
+}
+
+#[derive(FromMeta, PartialEq, Eq, Debug)]
+enum Volume {
+ Whisper,
+ Talk,
+ Shout,
+}
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(speak))]
+struct SpeakingOptions<T: Default, U> {
+ max_volume: U,
+ #[darling(skip)]
+ #[allow(dead_code)]
+ additional_data: T,
+}
+
+#[derive(Default)]
+struct Phoneme {
+ #[allow(dead_code)]
+ first: String,
+}
+
+#[test]
+fn skipped_field() {
+ let parsed: SpeakingOptions<Phoneme, Volume> = parse(
+ r#"
+ #[derive(Speak)]
+ #[speak(max_volume = "shout")]
+ enum HtmlElement {
+ Div(String)
+ }
+ "#,
+ );
+ assert_eq!(parsed.max_volume, Volume::Shout);
+}
diff --git a/third_party/rust/darling/tests/custom_bound.rs b/third_party/rust/darling/tests/custom_bound.rs
new file mode 100644
index 0000000000..312f147805
--- /dev/null
+++ b/third_party/rust/darling/tests/custom_bound.rs
@@ -0,0 +1,25 @@
+#![allow(dead_code)]
+
+use std::ops::Add;
+
+use darling::{FromDeriveInput, FromMeta};
+
+#[derive(Debug, Clone, FromMeta)]
+#[darling(bound = "T: FromMeta + Add")]
+struct Wrapper<T>(pub T);
+
+impl<T: Add> Add for Wrapper<T> {
+ type Output = Wrapper<<T as Add>::Output>;
+ fn add(self, rhs: Self) -> Wrapper<<T as Add>::Output> {
+ Wrapper(self.0 + rhs.0)
+ }
+}
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(hello), bound = "Wrapper<T>: Add, T: FromMeta")]
+struct Foo<T> {
+ lorem: Wrapper<T>,
+}
+
+#[test]
+fn expansion() {}
diff --git a/third_party/rust/darling/tests/defaults.rs b/third_party/rust/darling/tests/defaults.rs
new file mode 100644
index 0000000000..05ab1ed1db
--- /dev/null
+++ b/third_party/rust/darling/tests/defaults.rs
@@ -0,0 +1,189 @@
+use darling::FromDeriveInput;
+use syn::parse_quote;
+
+mod foo {
+ pub mod bar {
+ pub fn init() -> String {
+ String::from("hello")
+ }
+ }
+}
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(speak))]
+pub struct SpeakerOpts {
+ #[darling(default = "foo::bar::init")]
+ first_word: String,
+}
+
+#[test]
+fn path_default() {
+ let speaker: SpeakerOpts = FromDeriveInput::from_derive_input(&parse_quote! {
+ struct Foo;
+ })
+ .expect("Unit struct with no attrs should parse");
+
+ assert_eq!(speaker.first_word, "hello");
+}
+
+/// Tests in this module capture the somewhat-confusing behavior observed when defaults
+/// are set at both the field and container level.
+///
+/// The general rule is that more-specific declarations preempt less-specific ones; this is
+/// unsurprising and allows for granular control over what happens when parsing an AST.
+mod stacked_defaults {
+ use darling::{FromDeriveInput, FromMeta};
+ use syn::parse_quote;
+
+ fn jane() -> String {
+ "Jane".into()
+ }
+
+ #[derive(FromMeta)]
+ #[darling(default)]
+ struct PersonName {
+ #[darling(default = "jane")]
+ first: String,
+ #[darling(default)]
+ middle: String,
+ last: String,
+ }
+
+ impl Default for PersonName {
+ fn default() -> Self {
+ Self {
+ first: "John".into(),
+ middle: "T".into(),
+ last: "Doe".into(),
+ }
+ }
+ }
+
+ #[derive(FromDeriveInput)]
+ #[darling(attributes(person))]
+ struct Person {
+ #[darling(default)]
+ name: PersonName,
+ age: u8,
+ }
+
+ #[test]
+ fn name_first_only() {
+ let person = Person::from_derive_input(&parse_quote! {
+ #[person(name(first = "Bill"), age = 5)]
+ struct Foo;
+ })
+ .unwrap();
+
+ assert_eq!(person.name.first, "Bill");
+ assert_eq!(
+ person.name.middle, "",
+ "Explicit field-level default should preempt container-level default"
+ );
+ assert_eq!(
+ person.name.last, "Doe",
+ "Absence of a field-level default falls back to container-level default"
+ );
+ }
+
+ /// This is the most surprising case. The presence of `name()` means we invoke
+ /// `PersonName::from_list(&[])`. When that finishes parsing each of the zero nested
+ /// items it has received, it will then start filling in missing fields, using the
+ /// explicit field-level defaults for `first` and `middle`, while for `last` it will
+ /// use the `last` field from the container-level default.
+ #[test]
+ fn name_empty_list() {
+ let person = Person::from_derive_input(&parse_quote! {
+ #[person(name(), age = 5)]
+ struct Foo;
+ })
+ .unwrap();
+
+ assert_eq!(person.name.first, "Jane");
+ assert_eq!(person.name.middle, "");
+ assert_eq!(person.name.last, "Doe");
+ }
+
+ #[test]
+ fn no_name() {
+ let person = Person::from_derive_input(&parse_quote! {
+ #[person(age = 5)]
+ struct Foo;
+ })
+ .unwrap();
+
+ assert_eq!(person.age, 5);
+ assert_eq!(
+ person.name.first, "John",
+ "If `name` is not specified, `Person`'s field-level default should be used"
+ );
+ assert_eq!(person.name.middle, "T");
+ assert_eq!(person.name.last, "Doe");
+ }
+}
+
+mod implicit_default {
+ use darling::{util::Flag, FromDeriveInput};
+ use syn::parse_quote;
+
+ // No use of `darling(default)` here at all!
+ // This struct will fill in missing fields using FromMeta::from_none.
+ #[derive(FromDeriveInput)]
+ #[darling(attributes(person))]
+ struct Person {
+ first_name: String,
+ last_name: Option<String>,
+ lefty: Flag,
+ }
+
+ #[test]
+ fn missing_fields_fill() {
+ let person = Person::from_derive_input(&parse_quote! {
+ #[person(first_name = "James")]
+ struct Foo;
+ })
+ .unwrap();
+
+ assert_eq!(person.first_name, "James");
+ assert_eq!(person.last_name, None);
+ assert!(!person.lefty.is_present());
+ }
+}
+
+/// Test that a field-level implicit default using FromMeta::from_none is superseded
+/// by the parent declaring `#[darling(default)]`.
+mod overridden_implicit_default {
+ use darling::{util::Flag, FromDeriveInput};
+ use syn::parse_quote;
+
+ #[derive(FromDeriveInput)]
+ #[darling(default, attributes(person))]
+ struct Person {
+ first_name: String,
+ last_name: Option<String>,
+ lefty: Flag,
+ }
+
+ impl Default for Person {
+ fn default() -> Self {
+ Self {
+ first_name: "Jane".into(),
+ last_name: Some("Doe".into()),
+ lefty: Flag::default(),
+ }
+ }
+ }
+
+ #[test]
+ fn fill_missing() {
+ let person = Person::from_derive_input(&parse_quote!(
+ #[person(last_name = "Archer")]
+ struct Foo;
+ ))
+ .unwrap();
+
+ assert_eq!(person.first_name, "Jane");
+ assert_eq!(person.last_name, Some("Archer".into()));
+ assert!(!person.lefty.is_present());
+ }
+}
diff --git a/third_party/rust/darling/tests/enums_newtype.rs b/third_party/rust/darling/tests/enums_newtype.rs
new file mode 100644
index 0000000000..c2c4ec933f
--- /dev/null
+++ b/third_party/rust/darling/tests/enums_newtype.rs
@@ -0,0 +1,90 @@
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, Default, PartialEq, Eq, FromMeta)]
+#[darling(default)]
+pub struct Amet {
+ hello: bool,
+ world: String,
+}
+
+#[derive(Debug, PartialEq, Eq, FromMeta)]
+#[darling(rename_all = "snake_case")]
+pub enum Lorem {
+ Ipsum(bool),
+ Dolor(String),
+ Sit(Amet),
+}
+
+#[derive(Debug, PartialEq, Eq, FromDeriveInput)]
+#[darling(attributes(hello))]
+pub struct Holder {
+ lorem: Lorem,
+}
+
+impl PartialEq<Lorem> for Holder {
+ fn eq(&self, other: &Lorem) -> bool {
+ self.lorem == *other
+ }
+}
+
+#[test]
+fn bool_word() {
+ let di = parse_quote! {
+ #[hello(lorem(ipsum))]
+ pub struct Bar;
+ };
+
+ let pr = Holder::from_derive_input(&di).unwrap();
+ assert_eq!(pr, Lorem::Ipsum(true));
+}
+
+#[test]
+fn bool_literal() {
+ let di = parse_quote! {
+ #[hello(lorem(ipsum = false))]
+ pub struct Bar;
+ };
+
+ let pr = Holder::from_derive_input(&di).unwrap();
+ assert_eq!(pr, Lorem::Ipsum(false));
+}
+
+#[test]
+fn string_literal() {
+ let di = parse_quote! {
+ #[hello(lorem(dolor = "Hello"))]
+ pub struct Bar;
+ };
+
+ let pr = Holder::from_derive_input(&di).unwrap();
+ assert_eq!(pr, Lorem::Dolor("Hello".to_string()));
+}
+
+#[test]
+fn struct_nested() {
+ let di = parse_quote! {
+ #[hello(lorem(sit(world = "Hello", hello = false)))]
+ pub struct Bar;
+ };
+
+ let pr = Holder::from_derive_input(&di).unwrap();
+ assert_eq!(
+ pr,
+ Lorem::Sit(Amet {
+ hello: false,
+ world: "Hello".to_string(),
+ })
+ );
+}
+
+#[test]
+#[should_panic]
+fn format_mismatch() {
+ let di = parse_quote! {
+ #[hello(lorem(dolor(world = "Hello", hello = false)))]
+ pub struct Bar;
+ };
+
+ Holder::from_derive_input(&di).unwrap();
+}
diff --git a/third_party/rust/darling/tests/enums_struct.rs b/third_party/rust/darling/tests/enums_struct.rs
new file mode 100644
index 0000000000..cae4cd5cdc
--- /dev/null
+++ b/third_party/rust/darling/tests/enums_struct.rs
@@ -0,0 +1,15 @@
+#![allow(dead_code)]
+
+//! Test expansion of enums which have struct variants.
+
+use darling::FromMeta;
+#[derive(Debug, FromMeta)]
+#[darling(rename_all = "snake_case")]
+enum Message {
+ Hello { user: String, silent: bool },
+ Ping,
+ Goodbye { user: String },
+}
+
+#[test]
+fn expansion() {}
diff --git a/third_party/rust/darling/tests/enums_unit.rs b/third_party/rust/darling/tests/enums_unit.rs
new file mode 100644
index 0000000000..34e0135657
--- /dev/null
+++ b/third_party/rust/darling/tests/enums_unit.rs
@@ -0,0 +1,14 @@
+//! Test expansion of enum variants which have no associated data.
+
+use darling::FromMeta;
+
+#[derive(Debug, FromMeta)]
+#[darling(rename_all = "snake_case")]
+enum Pattern {
+ Owned,
+ Immutable,
+ Mutable,
+}
+
+#[test]
+fn expansion() {}
diff --git a/third_party/rust/darling/tests/error.rs b/third_party/rust/darling/tests/error.rs
new file mode 100644
index 0000000000..7274e40894
--- /dev/null
+++ b/third_party/rust/darling/tests/error.rs
@@ -0,0 +1,54 @@
+//! In case of bad input, parsing should fail. The error should have locations set in derived implementations.
+
+// The use of fields in debug print commands does not count as "used",
+// which causes the fields to trigger an unwanted dead code warning.
+#![allow(dead_code)]
+
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, FromMeta)]
+struct Dolor {
+ #[darling(rename = "amet")]
+ sit: bool,
+ world: bool,
+}
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(from_ident, attributes(hello))]
+struct Lorem {
+ ident: syn::Ident,
+ ipsum: Dolor,
+}
+
+impl From<syn::Ident> for Lorem {
+ fn from(ident: syn::Ident) -> Self {
+ Lorem {
+ ident,
+ ipsum: Dolor {
+ sit: false,
+ world: true,
+ },
+ }
+ }
+}
+
+#[test]
+fn parsing_fail() {
+ let di = parse_quote! {
+ #[hello(ipsum(amet = "yes", world = false))]
+ pub struct Foo;
+ };
+
+ println!("{}", Lorem::from_derive_input(&di).unwrap_err());
+}
+
+#[test]
+fn missing_field() {
+ let di = parse_quote! {
+ #[hello(ipsum(amet = true))]
+ pub struct Foo;
+ };
+
+ println!("{}", Lorem::from_derive_input(&di).unwrap_err());
+}
diff --git a/third_party/rust/darling/tests/from_generics.rs b/third_party/rust/darling/tests/from_generics.rs
new file mode 100644
index 0000000000..5cdd697d6e
--- /dev/null
+++ b/third_party/rust/darling/tests/from_generics.rs
@@ -0,0 +1,175 @@
+//! Tests for `FromGenerics`, and - indirectly - `FromGenericParam`.
+//! These tests assume `FromTypeParam` is working and only look at whether the wrappers for magic
+//! fields are working as expected.
+
+use darling::{
+ ast::{self, GenericParamExt},
+ util::{Ignored, WithOriginal},
+ FromDeriveInput, FromTypeParam, Result,
+};
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(lorem))]
+struct MyReceiver {
+ pub generics: ast::Generics<ast::GenericParam<MyTypeParam>>,
+}
+
+#[derive(FromTypeParam)]
+#[darling(attributes(lorem))]
+struct MyTypeParam {
+ pub ident: syn::Ident,
+ #[darling(default)]
+ pub foo: bool,
+ pub bar: Option<String>,
+}
+
+fn fdi<T: FromDeriveInput>(src: &str) -> Result<T> {
+ FromDeriveInput::from_derive_input(&syn::parse_str(src).expect("Source parses"))
+}
+
+/// Verify that `ast::Generics` is populated correctly when there is no generics declaration
+#[test]
+fn no_generics() {
+ let rec: MyReceiver = fdi("struct Baz;").expect("Input is well-formed");
+ assert!(rec.generics.where_clause.is_none());
+ assert_eq!(rec.generics.params.len(), 0);
+}
+
+#[test]
+#[allow(clippy::bool_assert_comparison)]
+fn expand_some() {
+ let rec: MyReceiver = fdi(r#"
+ struct Baz<
+ 'a,
+ #[lorem(foo)] T,
+ #[lorem(bar = "x")] U: Eq + ?Sized
+ >(&'a T, U);
+ "#)
+ .expect("Input is well-formed");
+ assert!(rec.generics.where_clause.is_none());
+
+ // Make sure we've preserved the lifetime def, though we don't do anything with it.
+ assert!(rec.generics.params[0].as_lifetime_def().is_some());
+
+ let mut ty_param_iter = rec.generics.type_params();
+
+ let first = ty_param_iter
+ .next()
+ .expect("type_params should not be empty");
+ assert!(first.bar.is_none());
+ assert!(first.foo);
+ assert_eq!(first.ident, "T");
+
+ let second = ty_param_iter
+ .next()
+ .expect("type_params should have a second value");
+ assert_eq!(
+ second
+ .bar
+ .as_ref()
+ .expect("Second type param should set bar"),
+ "x"
+ );
+ assert_eq!(second.foo, false);
+ assert_eq!(second.ident, "U");
+}
+
+/// Verify ≤0.4.1 behavior - where `generics` had to be `syn::Generics` - keeps working.
+#[test]
+fn passthrough() {
+ #[derive(FromDeriveInput)]
+ struct PassthroughReceiver {
+ pub generics: syn::Generics,
+ }
+
+ let rec: PassthroughReceiver = fdi(r#"
+ struct Baz<
+ 'a,
+ #[lorem(foo)] T,
+ #[lorem(bar = "x")] U: Eq + ?Sized
+ >(&'a T, U);
+ "#)
+ .expect("Input is well-formed");
+
+ let mut type_param_iter = rec.generics.type_params();
+ assert!(type_param_iter.next().is_some());
+}
+
+/// Verify that `where_clause` is passed through when it exists.
+/// As of 0.4.1, there is no `FromWhereClause` trait, so other types aren't supported
+/// for that field.
+#[test]
+fn where_clause() {
+ let rec: MyReceiver = fdi(r#"
+ struct Baz<
+ 'a,
+ #[lorem(foo)] T,
+ #[lorem(bar = "x")] U: Eq + ?Sized
+ >(&'a T, U) where T: Into<String>;
+ "#)
+ .expect("Input is well-formed");
+
+ assert!(rec.generics.where_clause.is_some());
+}
+
+/// Test that `WithOriginal` works for generics.
+#[test]
+fn with_original() {
+ #[derive(FromDeriveInput)]
+ struct WorigReceiver {
+ generics: WithOriginal<ast::Generics<ast::GenericParam<MyTypeParam>>, syn::Generics>,
+ }
+
+ let rec: WorigReceiver = fdi(r#"
+ struct Baz<
+ 'a,
+ #[lorem(foo)] T,
+ #[lorem(bar = "x")] U: Eq + ?Sized
+ >(&'a T, U) where T: Into<String>;
+ "#)
+ .expect("Input is well-formed");
+
+ // Make sure we haven't lost anything in the conversion
+ assert_eq!(rec.generics.parsed.params.len(), 3);
+ assert_eq!(rec.generics.original.params.len(), 3);
+
+ let parsed_t: &MyTypeParam = rec.generics.parsed.params[1]
+ .as_type_param()
+ .expect("Second argument should be type param");
+
+ // Make sure the first type param in each case is T
+ assert_eq!(parsed_t.ident, "T");
+ assert_eq!(
+ rec.generics
+ .original
+ .type_params()
+ .next()
+ .expect("First type param should exist")
+ .ident,
+ "T"
+ );
+
+ // Make sure we actually parsed the first type param
+ assert!(parsed_t.foo);
+ assert!(parsed_t.bar.is_none());
+}
+
+/// Make sure generics can be ignored
+#[test]
+fn ignored() {
+ #[derive(FromDeriveInput)]
+ struct IgnoredReceiver {
+ generics: Ignored,
+ }
+
+ let rec: IgnoredReceiver = fdi(r#"
+ struct Baz<
+ 'a,
+ #[lorem(foo)] T,
+ #[lorem(bar = "x")] U: Eq + ?Sized
+ >(&'a T, U) where T: Into<String>;
+ "#)
+ .expect("Input is well-formed");
+
+ assert_eq!(Ignored, rec.generics);
+}
diff --git a/third_party/rust/darling/tests/from_meta.rs b/third_party/rust/darling/tests/from_meta.rs
new file mode 100644
index 0000000000..3e7278cec8
--- /dev/null
+++ b/third_party/rust/darling/tests/from_meta.rs
@@ -0,0 +1,66 @@
+use darling::{Error, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, FromMeta)]
+struct Meta {
+ #[darling(default)]
+ meta1: Option<String>,
+ #[darling(default)]
+ meta2: bool,
+}
+
+#[test]
+fn nested_meta_meta_value() {
+ let meta = Meta::from_list(&[parse_quote! {
+ meta1 = "thefeature"
+ }])
+ .unwrap();
+ assert_eq!(meta.meta1, Some("thefeature".to_string()));
+ assert!(!meta.meta2);
+}
+
+#[test]
+fn nested_meta_meta_bool() {
+ let meta = Meta::from_list(&[parse_quote! {
+ meta2
+ }])
+ .unwrap();
+ assert_eq!(meta.meta1, None);
+ assert!(meta.meta2);
+}
+
+#[test]
+fn nested_meta_lit_string_errors() {
+ let err = Meta::from_list(&[parse_quote! {
+ "meta2"
+ }])
+ .unwrap_err();
+ assert_eq!(
+ err.to_string(),
+ Error::unsupported_format("literal").to_string()
+ );
+}
+
+#[test]
+fn nested_meta_lit_integer_errors() {
+ let err = Meta::from_list(&[parse_quote! {
+ 2
+ }])
+ .unwrap_err();
+ assert_eq!(
+ err.to_string(),
+ Error::unsupported_format("literal").to_string()
+ );
+}
+
+#[test]
+fn nested_meta_lit_bool_errors() {
+ let err = Meta::from_list(&[parse_quote! {
+ true
+ }])
+ .unwrap_err();
+ assert_eq!(
+ err.to_string(),
+ Error::unsupported_format("literal").to_string()
+ );
+}
diff --git a/third_party/rust/darling/tests/from_type_param.rs b/third_party/rust/darling/tests/from_type_param.rs
new file mode 100644
index 0000000000..50ec3061e9
--- /dev/null
+++ b/third_party/rust/darling/tests/from_type_param.rs
@@ -0,0 +1,59 @@
+use darling::FromTypeParam;
+use syn::{parse_quote, DeriveInput, GenericParam, Ident, TypeParam};
+
+#[derive(FromTypeParam)]
+#[darling(attributes(lorem), from_ident)]
+struct Lorem {
+ ident: Ident,
+ bounds: Vec<syn::TypeParamBound>,
+ foo: bool,
+ bar: Option<String>,
+}
+
+impl From<Ident> for Lorem {
+ fn from(ident: Ident) -> Self {
+ Lorem {
+ ident,
+ foo: false,
+ bar: None,
+ bounds: Default::default(),
+ }
+ }
+}
+
+fn extract_type(param: &GenericParam) -> &TypeParam {
+ match *param {
+ GenericParam::Type(ref ty) => ty,
+ _ => unreachable!("Not a type param"),
+ }
+}
+
+#[test]
+#[allow(clippy::bool_assert_comparison)]
+fn expand_many() {
+ let di: DeriveInput = parse_quote! {
+ struct Baz<
+ #[lorem(foo)] T,
+ #[lorem(bar = "x")] U: Eq + ?Sized
+ >(T, U);
+ };
+
+ let params = di.generics.params;
+
+ {
+ let ty = extract_type(&params[0]);
+ let lorem = Lorem::from_type_param(ty).unwrap();
+ assert_eq!(lorem.ident, "T");
+ assert_eq!(lorem.foo, true);
+ assert_eq!(lorem.bar, None);
+ }
+
+ {
+ let ty = extract_type(&params[1]);
+ let lorem = Lorem::from_type_param(ty).unwrap();
+ assert_eq!(lorem.ident, "U");
+ assert_eq!(lorem.foo, false);
+ assert_eq!(lorem.bar, Some("x".to_string()));
+ assert_eq!(lorem.bounds.len(), 2);
+ }
+}
diff --git a/third_party/rust/darling/tests/from_type_param_default.rs b/third_party/rust/darling/tests/from_type_param_default.rs
new file mode 100644
index 0000000000..9d65665bb9
--- /dev/null
+++ b/third_party/rust/darling/tests/from_type_param_default.rs
@@ -0,0 +1,53 @@
+use darling::FromTypeParam;
+use syn::{parse_quote, DeriveInput, GenericParam, TypeParam};
+
+#[derive(Default, FromTypeParam)]
+#[darling(attributes(lorem), default)]
+struct Lorem {
+ foo: bool,
+ bar: Option<String>,
+ default: Option<syn::Type>,
+}
+
+fn extract_type(param: &GenericParam) -> &TypeParam {
+ match *param {
+ GenericParam::Type(ref ty) => ty,
+ _ => unreachable!("Not a type param"),
+ }
+}
+
+#[test]
+#[allow(clippy::bool_assert_comparison)]
+fn expand_many() {
+ let di: DeriveInput = parse_quote! {
+ struct Baz<
+ #[lorem(foo)] T,
+ #[lorem(bar = "x")] U: Eq + ?Sized,
+ #[lorem(foo = false)] V = (),
+ >(T, U, V);
+ };
+ let params = di.generics.params;
+
+ {
+ let ty = extract_type(&params[0]);
+ let lorem = Lorem::from_type_param(ty).unwrap();
+ assert_eq!(lorem.foo, true);
+ assert_eq!(lorem.bar, None);
+ }
+
+ {
+ let ty = extract_type(&params[1]);
+ let lorem = Lorem::from_type_param(ty).unwrap();
+ assert_eq!(lorem.foo, false);
+ assert_eq!(lorem.bar, Some("x".to_string()));
+ assert!(lorem.default.is_none());
+ }
+
+ {
+ let ty = extract_type(&params[2]);
+ let lorem = Lorem::from_type_param(ty).unwrap();
+ assert_eq!(lorem.foo, false);
+ assert_eq!(lorem.bar, None);
+ assert!(lorem.default.is_some());
+ }
+}
diff --git a/third_party/rust/darling/tests/from_variant.rs b/third_party/rust/darling/tests/from_variant.rs
new file mode 100644
index 0000000000..e89b8ff7f5
--- /dev/null
+++ b/third_party/rust/darling/tests/from_variant.rs
@@ -0,0 +1,57 @@
+use darling::FromVariant;
+use syn::{spanned::Spanned, Expr, ExprLit, LitInt};
+
+#[derive(FromVariant)]
+#[darling(from_ident, attributes(hello))]
+#[allow(dead_code)]
+pub struct Lorem {
+ ident: syn::Ident,
+ into: Option<bool>,
+ skip: Option<bool>,
+ discriminant: Option<syn::Expr>,
+ fields: darling::ast::Fields<syn::Type>,
+}
+
+impl From<syn::Ident> for Lorem {
+ fn from(ident: syn::Ident) -> Self {
+ Lorem {
+ ident,
+ into: Default::default(),
+ skip: Default::default(),
+ discriminant: None,
+ fields: darling::ast::Style::Unit.into(),
+ }
+ }
+}
+
+#[test]
+fn discriminant() {
+ let input: syn::DeriveInput = syn::parse_str(
+ r#"
+ pub enum Test {
+ Works = 1,
+ AlsoWorks = 2,
+ }
+ "#,
+ )
+ .unwrap();
+
+ let span = input.span();
+ if let syn::Data::Enum(enm) = input.data {
+ let lorem = Lorem::from_variant(
+ enm.variants
+ .first()
+ .expect("Hardcoded input has one variant"),
+ )
+ .expect("FromVariant can process the discriminant");
+ assert_eq!(
+ lorem.discriminant,
+ Some(Expr::Lit(ExprLit {
+ attrs: vec![],
+ lit: LitInt::new("1", span).into(),
+ }))
+ )
+ } else {
+ panic!("Data should be enum");
+ }
+}
diff --git a/third_party/rust/darling/tests/generics.rs b/third_party/rust/darling/tests/generics.rs
new file mode 100644
index 0000000000..ba65781fe3
--- /dev/null
+++ b/third_party/rust/darling/tests/generics.rs
@@ -0,0 +1,23 @@
+#![allow(dead_code)]
+
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, Clone, FromMeta)]
+struct Wrapper<T>(pub T);
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(hello))]
+struct Foo<T> {
+ lorem: Wrapper<T>,
+}
+
+#[test]
+fn expansion() {
+ let di = parse_quote! {
+ #[hello(lorem = "Hello")]
+ pub struct Foo;
+ };
+
+ Foo::<String>::from_derive_input(&di).unwrap();
+}
diff --git a/third_party/rust/darling/tests/happy_path.rs b/third_party/rust/darling/tests/happy_path.rs
new file mode 100644
index 0000000000..a56aee75fc
--- /dev/null
+++ b/third_party/rust/darling/tests/happy_path.rs
@@ -0,0 +1,69 @@
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(Default, FromMeta, PartialEq, Debug)]
+#[darling(default)]
+struct Lorem {
+ ipsum: bool,
+ dolor: Option<String>,
+}
+
+#[derive(FromDeriveInput, PartialEq, Debug)]
+#[darling(attributes(darling_demo))]
+struct Core {
+ ident: syn::Ident,
+ vis: syn::Visibility,
+ generics: syn::Generics,
+ lorem: Lorem,
+}
+
+#[derive(FromDeriveInput, PartialEq, Debug)]
+#[darling(attributes(darling_demo))]
+struct TraitCore {
+ ident: syn::Ident,
+ generics: syn::Generics,
+ lorem: Lorem,
+}
+
+#[test]
+fn simple() {
+ let di = parse_quote! {
+ #[derive(Foo)]
+ #[darling_demo(lorem(ipsum))]
+ pub struct Bar;
+ };
+
+ assert_eq!(
+ Core::from_derive_input(&di).unwrap(),
+ Core {
+ ident: parse_quote!(Bar),
+ vis: parse_quote!(pub),
+ generics: Default::default(),
+ lorem: Lorem {
+ ipsum: true,
+ dolor: None,
+ },
+ }
+ );
+}
+
+#[test]
+fn trait_type() {
+ let di = parse_quote! {
+ #[derive(Foo)]
+ #[darling_demo(lorem(dolor = "hello"))]
+ pub struct Bar;
+ };
+
+ assert_eq!(
+ TraitCore::from_derive_input(&di).unwrap(),
+ TraitCore {
+ ident: parse_quote!(Bar),
+ generics: Default::default(),
+ lorem: Lorem {
+ ipsum: false,
+ dolor: Some("hello".to_owned()),
+ }
+ }
+ );
+}
diff --git a/third_party/rust/darling/tests/hash_map.rs b/third_party/rust/darling/tests/hash_map.rs
new file mode 100644
index 0000000000..5d9a0114ed
--- /dev/null
+++ b/third_party/rust/darling/tests/hash_map.rs
@@ -0,0 +1,42 @@
+use std::collections::HashMap;
+
+use darling::FromMeta;
+use syn::{parse_quote, Attribute, Path};
+
+#[derive(Debug, FromMeta, PartialEq, Eq)]
+struct MapValue {
+ name: String,
+ #[darling(default)]
+ option: bool,
+}
+
+#[test]
+fn parse_map() {
+ let attr: Attribute = parse_quote! {
+ #[foo(first(name = "Hello", option), the::second(name = "Second"))]
+ };
+
+ let meta = attr.parse_meta().unwrap();
+ let map: HashMap<Path, MapValue> = FromMeta::from_meta(&meta).unwrap();
+
+ let comparison: HashMap<Path, MapValue> = vec![
+ (
+ parse_quote!(first),
+ MapValue {
+ name: "Hello".into(),
+ option: true,
+ },
+ ),
+ (
+ parse_quote!(the::second),
+ MapValue {
+ name: "Second".into(),
+ option: false,
+ },
+ ),
+ ]
+ .into_iter()
+ .collect();
+
+ assert_eq!(comparison, map);
+}
diff --git a/third_party/rust/darling/tests/multiple.rs b/third_party/rust/darling/tests/multiple.rs
new file mode 100644
index 0000000000..b2243e62b6
--- /dev/null
+++ b/third_party/rust/darling/tests/multiple.rs
@@ -0,0 +1,30 @@
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(FromDeriveInput)]
+#[darling(attributes(hello))]
+#[allow(dead_code)]
+struct Lorem {
+ ident: syn::Ident,
+ ipsum: Ipsum,
+}
+
+#[derive(FromMeta)]
+struct Ipsum {
+ #[darling(multiple)]
+ dolor: Vec<String>,
+}
+
+#[test]
+fn expand_many() {
+ let di = parse_quote! {
+ #[hello(ipsum(dolor = "Hello", dolor = "World"))]
+ pub struct Baz;
+ };
+
+ let lorem: Lorem = Lorem::from_derive_input(&di).unwrap();
+ assert_eq!(
+ lorem.ipsum.dolor,
+ vec!["Hello".to_string(), "World".to_string()]
+ );
+}
diff --git a/third_party/rust/darling/tests/newtype.rs b/third_party/rust/darling/tests/newtype.rs
new file mode 100644
index 0000000000..10d0238882
--- /dev/null
+++ b/third_party/rust/darling/tests/newtype.rs
@@ -0,0 +1,26 @@
+//! A newtype struct should be able to derive `FromMeta` if its member implements it.
+
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, FromMeta, PartialEq, Eq)]
+struct Lorem(bool);
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(newtype))]
+struct DemoContainer {
+ lorem: Lorem,
+}
+
+#[test]
+fn generated() {
+ let di = parse_quote! {
+ #[derive(Baz)]
+ #[newtype(lorem = false)]
+ pub struct Foo;
+ };
+
+ let c = DemoContainer::from_derive_input(&di).unwrap();
+
+ assert_eq!(c.lorem, Lorem(false));
+}
diff --git a/third_party/rust/darling/tests/skip.rs b/third_party/rust/darling/tests/skip.rs
new file mode 100644
index 0000000000..f930ca5d31
--- /dev/null
+++ b/third_party/rust/darling/tests/skip.rs
@@ -0,0 +1,74 @@
+//! Test that skipped fields are not read into structs when they appear in input.
+
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, PartialEq, Eq, FromDeriveInput)]
+#[darling(attributes(skip_test))]
+pub struct Lorem {
+ ipsum: String,
+
+ #[darling(skip)]
+ dolor: u8,
+}
+
+/// Verify variant-level and field-level skip work correctly for enums.
+#[derive(Debug, FromMeta)]
+pub enum Sit {
+ Amet(bool),
+
+ #[darling(skip)]
+ Foo {
+ hello: bool,
+ },
+
+ Bar {
+ hello: bool,
+ #[darling(skip)]
+ world: u8,
+ },
+}
+
+#[test]
+fn verify_skipped_field_not_required() {
+ let di = parse_quote! {
+ #[skip_test(ipsum = "Hello")]
+ struct Baz;
+ };
+
+ assert_eq!(
+ Lorem::from_derive_input(&di).unwrap(),
+ Lorem {
+ ipsum: "Hello".to_string(),
+ dolor: 0,
+ }
+ );
+}
+
+/// This test verifies that a skipped field will still prefer an explicit default
+/// over the default that would come from its field type. It would be incorrect for
+/// `Defaulting::from_derive_input` to fail here, and it would be wrong for the value
+/// of `dolor` to be `None`.
+#[test]
+fn verify_default_supersedes_from_none() {
+ fn default_dolor() -> Option<u8> {
+ Some(2)
+ }
+
+ #[derive(Debug, PartialEq, Eq, FromDeriveInput)]
+ #[darling(attributes(skip_test))]
+ pub struct Defaulting {
+ #[darling(skip, default = "default_dolor")]
+ dolor: Option<u8>,
+ }
+
+ let di = parse_quote! {
+ #[skip_test]
+ struct Baz;
+ };
+
+ assert_eq!(
+ Defaulting::from_derive_input(&di).unwrap(),
+ Defaulting { dolor: Some(2) }
+ )
+}
diff --git a/third_party/rust/darling/tests/split_declaration.rs b/third_party/rust/darling/tests/split_declaration.rs
new file mode 100644
index 0000000000..8db11d0f03
--- /dev/null
+++ b/third_party/rust/darling/tests/split_declaration.rs
@@ -0,0 +1,67 @@
+//! When input is split across multiple attributes on one element,
+//! darling should collapse that into one struct.
+
+use darling::{Error, FromDeriveInput};
+use syn::parse_quote;
+
+#[derive(Debug, FromDeriveInput, PartialEq, Eq)]
+#[darling(attributes(split))]
+struct Lorem {
+ foo: String,
+ bar: bool,
+}
+
+#[test]
+fn split_attributes_accrue_to_instance() {
+ let di = parse_quote! {
+ #[split(foo = "Hello")]
+ #[split(bar)]
+ pub struct Foo;
+ };
+
+ let parsed = Lorem::from_derive_input(&di).unwrap();
+ assert_eq!(
+ parsed,
+ Lorem {
+ foo: "Hello".to_string(),
+ bar: true,
+ }
+ );
+}
+
+#[test]
+fn duplicates_across_split_attrs_error() {
+ let di = parse_quote! {
+ #[split(foo = "Hello")]
+ #[split(foo = "World", bar)]
+ pub struct Foo;
+ };
+
+ let pr = Lorem::from_derive_input(&di).unwrap_err();
+ assert!(pr.has_span());
+ assert_eq!(pr.to_string(), Error::duplicate_field("foo").to_string());
+}
+
+#[test]
+fn multiple_errors_accrue_to_instance() {
+ let di = parse_quote! {
+ #[split(foo = "Hello")]
+ #[split(foo = "World")]
+ pub struct Foo;
+ };
+
+ let pr = Lorem::from_derive_input(&di);
+ let err: Error = pr.unwrap_err();
+ assert_eq!(2, err.len());
+ let mut errs = err.into_iter().peekable();
+ assert_eq!(
+ errs.peek().unwrap().to_string(),
+ Error::duplicate_field("foo").to_string()
+ );
+ assert!(errs.next().unwrap().has_span());
+ assert_eq!(
+ errs.next().unwrap().to_string(),
+ Error::missing_field("bar").to_string()
+ );
+ assert!(errs.next().is_none());
+}
diff --git a/third_party/rust/darling/tests/suggestions.rs b/third_party/rust/darling/tests/suggestions.rs
new file mode 100644
index 0000000000..5baf76ca6c
--- /dev/null
+++ b/third_party/rust/darling/tests/suggestions.rs
@@ -0,0 +1,29 @@
+#![allow(dead_code)]
+#![cfg(feature = "suggestions")]
+
+use darling::{FromDeriveInput, FromMeta};
+use syn::parse_quote;
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(suggest))]
+struct Lorem {
+ ipsum: String,
+ dolor: Dolor,
+}
+
+#[derive(Debug, FromMeta)]
+struct Dolor {
+ sit: bool,
+}
+
+#[test]
+fn suggest_dolor() {
+ let input: syn::DeriveInput = parse_quote! {
+ #[suggest(ipsum = "Hello", dolorr(sit))]
+ pub struct Foo;
+ };
+
+ let result = Lorem::from_derive_input(&input).unwrap_err();
+ assert_eq!(2, result.len());
+ assert!(format!("{}", result).contains("Did you mean"));
+}
diff --git a/third_party/rust/darling/tests/supports.rs b/third_party/rust/darling/tests/supports.rs
new file mode 100644
index 0000000000..d6c7556722
--- /dev/null
+++ b/third_party/rust/darling/tests/supports.rs
@@ -0,0 +1,90 @@
+use darling::{ast, FromDeriveInput, FromVariant};
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(from_variants), supports(enum_any))]
+pub struct Container {
+ // The second type parameter can be anything that implements FromField, since
+ // FromDeriveInput will produce an error if given a struct.
+ data: ast::Data<Variant, ()>,
+}
+
+#[derive(Default, Debug, FromVariant)]
+#[darling(default, attributes(from_variants), supports(newtype, unit))]
+pub struct Variant {
+ into: Option<bool>,
+ skip: Option<bool>,
+}
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(attributes(from_struct), supports(struct_named))]
+pub struct StructContainer {
+ // The second type parameter can be anything that implements FromVariant, since
+ // FromDeriveInput will produce an error if given an enum.
+ data: ast::Data<(), syn::Field>,
+}
+
+mod source {
+ use syn::{parse_quote, DeriveInput};
+
+ pub fn newtype_enum() -> DeriveInput {
+ parse_quote! {
+ enum Hello {
+ World(bool),
+ String(String),
+ }
+ }
+ }
+
+ pub fn named_field_enum() -> DeriveInput {
+ parse_quote! {
+ enum Hello {
+ Foo(u16),
+ World {
+ name: String
+ },
+ }
+ }
+ }
+
+ pub fn empty_enum() -> DeriveInput {
+ parse_quote! {
+ enum Hello {}
+ }
+ }
+
+ pub fn named_struct() -> DeriveInput {
+ parse_quote! {
+ struct Hello {
+ world: bool,
+ }
+ }
+ }
+
+ pub fn tuple_struct() -> DeriveInput {
+ parse_quote! { struct Hello(String, bool); }
+ }
+}
+
+#[test]
+fn enum_newtype_or_unit() {
+ // Should pass
+ let container = Container::from_derive_input(&source::newtype_enum()).unwrap();
+ assert!(container.data.is_enum());
+
+ // Should error
+ Container::from_derive_input(&source::named_field_enum()).unwrap_err();
+ Container::from_derive_input(&source::named_struct()).unwrap_err();
+}
+
+#[test]
+fn struct_named() {
+ // Should pass
+ let container = StructContainer::from_derive_input(&source::named_struct()).unwrap();
+ assert!(container.data.is_struct());
+
+ // Should fail
+ StructContainer::from_derive_input(&source::tuple_struct()).unwrap_err();
+ StructContainer::from_derive_input(&source::named_field_enum()).unwrap_err();
+ StructContainer::from_derive_input(&source::newtype_enum()).unwrap_err();
+ StructContainer::from_derive_input(&source::empty_enum()).unwrap_err();
+}
diff --git a/third_party/rust/darling/tests/unsupported_attributes.rs b/third_party/rust/darling/tests/unsupported_attributes.rs
new file mode 100644
index 0000000000..14edf2c858
--- /dev/null
+++ b/third_party/rust/darling/tests/unsupported_attributes.rs
@@ -0,0 +1,49 @@
+use darling::FromDeriveInput;
+use syn::{parse_quote, Ident, LitStr, Path};
+
+#[derive(Debug, FromDeriveInput)]
+#[darling(supports(struct_unit), attributes(bar))]
+pub struct Bar {
+ pub ident: Ident,
+ pub st: Path,
+ pub file: LitStr,
+}
+
+/// Per [#96](https://github.com/TedDriggs/darling/issues/96), make sure that an
+/// attribute which isn't a valid meta gets an error.
+#[test]
+fn non_meta_attribute_gets_own_error() {
+ let di = parse_quote! {
+ #[derive(Bar)]
+ #[bar(file = "motors/example_6.csv", st = RocketEngine)]
+ pub struct EstesC6;
+ };
+
+ let errors: darling::Error = Bar::from_derive_input(&di).unwrap_err().flatten();
+ // The number of errors here is 1 for the bad attribute + 2 for the missing fields
+ assert_eq!(3, errors.len());
+ // Make sure one of the errors propagates the syn error
+ assert!(errors
+ .into_iter()
+ .any(|e| e.to_string().contains("expected lit")));
+}
+
+/// Properties can be split across multiple attributes; this test ensures that one
+/// non-meta attribute does not interfere with the parsing of other, well-formed attributes.
+#[test]
+fn non_meta_attribute_does_not_block_others() {
+ let di = parse_quote! {
+ #[derive(Bar)]
+ #[bar(st = RocketEngine)]
+ #[bar(file = "motors/example_6.csv")]
+ pub struct EstesC6;
+ };
+
+ let errors: darling::Error = Bar::from_derive_input(&di).unwrap_err().flatten();
+ // The number of errors here is 1 for the bad attribute + 1 for the missing "st" field
+ assert_eq!(2, errors.len());
+ // Make sure one of the errors propagates the syn error
+ assert!(errors
+ .into_iter()
+ .any(|e| e.to_string().contains("expected lit")));
+}