Snap for 10103804 from 385bce15785129cd36bb1c346d0380f19d0c3ab1 to mainline-tzdata5-release

Change-Id: Iefbe77f7faa497a1c12b5ebc51f694dda3ee7d8c
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 1f38b6d..5db9271 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "98044ba8b0f7d730b500fa3b4f2e96a5edcd926d"
+    "sha1": "c20a95029145c0eab249416f3d301c4bd21f33f6"
   },
   "path_in_vcs": "derive"
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 6e6ef8f..20506a1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@
     name: "libderive_arbitrary",
     crate_name: "derive_arbitrary",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.2.3",
+    cargo_pkg_version: "1.3.0",
     srcs: ["src/lib.rs"],
     edition: "2021",
     rustlibs: [
@@ -51,4 +51,6 @@
         "libquote",
         "libsyn",
     ],
+    product_available: true,
+    vendor_available: true,
 }
diff --git a/Cargo.toml b/Cargo.toml
index 977aa61..fc076e8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2021"
 rust-version = "1.63.0"
 name = "derive_arbitrary"
-version = "1.2.3"
+version = "1.3.0"
 authors = [
     "The Rust-Fuzz Project Developers",
     "Nick Fitzgerald <fitzgen@gmail.com>",
@@ -45,5 +45,8 @@
 version = "1.0"
 
 [dependencies.syn]
-version = "1.0"
-features = ["derive"]
+version = "1.0.56"
+features = [
+    "derive",
+    "parsing",
+]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 99f5538..570519f 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "derive_arbitrary"
-version = "1.2.3" # Make sure it matches the version of the arbitrary crate itself (not including the patch version)
+version = "1.3.0" # Make sure it matches the version of the arbitrary crate itself (not including the patch version)
 authors = [
     "The Rust-Fuzz Project Developers",
     "Nick Fitzgerald <fitzgen@gmail.com>",
@@ -21,7 +21,7 @@
 [dependencies]
 proc-macro2 = "1.0"
 quote = "1.0"
-syn = { version = "1.0", features = ['derive'] }
+syn = { version = "1.0.56", features = ['derive', 'parsing'] }
 
 [lib]
 proc_macro = true
diff --git a/METADATA b/METADATA
index b987604..c7c7071 100644
--- a/METADATA
+++ b/METADATA
@@ -11,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/derive_arbitrary/derive_arbitrary-1.2.3.crate"
+    value: "https://static.crates.io/crates/derive_arbitrary/derive_arbitrary-1.3.0.crate"
   }
-  version: "1.2.3"
+  version: "1.3.0"
   license_type: NOTICE
   last_upgrade_date {
     year: 2023
-    month: 2
-    day: 1
+    month: 4
+    day: 3
   }
 }
diff --git a/src/container_attributes.rs b/src/container_attributes.rs
new file mode 100644
index 0000000..9a91ac8
--- /dev/null
+++ b/src/container_attributes.rs
@@ -0,0 +1,72 @@
+use crate::ARBITRARY_ATTRIBUTE_NAME;
+use syn::{
+    parse::Error, punctuated::Punctuated, DeriveInput, Lit, Meta, MetaNameValue, NestedMeta, Token,
+    TypeParam,
+};
+
+pub struct ContainerAttributes {
+    /// Specify type bounds to be applied to the derived `Arbitrary` implementation instead of the
+    /// default inferred bounds.
+    ///
+    /// ```ignore
+    /// #[arbitrary(bound = "T: Default, U: Debug")]
+    /// ```
+    ///
+    /// Multiple attributes will be combined as long as they don't conflict, e.g.
+    ///
+    /// ```ignore
+    /// #[arbitrary(bound = "T: Default")]
+    /// #[arbitrary(bound = "U: Default")]
+    /// ```
+    pub bounds: Option<Vec<Punctuated<TypeParam, Token![,]>>>,
+}
+
+impl ContainerAttributes {
+    pub fn from_derive_input(derive_input: &DeriveInput) -> Result<Self, Error> {
+        let mut bounds = None;
+
+        for attr in &derive_input.attrs {
+            if !attr.path.is_ident(ARBITRARY_ATTRIBUTE_NAME) {
+                continue;
+            }
+
+            let meta_list = match attr.parse_meta()? {
+                Meta::List(l) => l,
+                _ => {
+                    return Err(Error::new_spanned(
+                        attr,
+                        format!(
+                            "invalid `{}` attribute. expected list",
+                            ARBITRARY_ATTRIBUTE_NAME
+                        ),
+                    ))
+                }
+            };
+
+            for nested_meta in meta_list.nested.iter() {
+                match nested_meta {
+                    NestedMeta::Meta(Meta::NameValue(MetaNameValue {
+                        path,
+                        lit: Lit::Str(bound_str_lit),
+                        ..
+                    })) if path.is_ident("bound") => {
+                        bounds
+                            .get_or_insert_with(Vec::new)
+                            .push(bound_str_lit.parse_with(Punctuated::parse_terminated)?);
+                    }
+                    _ => {
+                        return Err(Error::new_spanned(
+                            attr,
+                            format!(
+                                "invalid `{}` attribute. expected `bound = \"..\"`",
+                                ARBITRARY_ATTRIBUTE_NAME,
+                            ),
+                        ))
+                    }
+                }
+            }
+        }
+
+        Ok(Self { bounds })
+    }
+}
diff --git a/src/field_attributes.rs b/src/field_attributes.rs
index ccaba74..2ca0f1c 100644
--- a/src/field_attributes.rs
+++ b/src/field_attributes.rs
@@ -1,10 +1,8 @@
+use crate::ARBITRARY_ATTRIBUTE_NAME;
 use proc_macro2::{Group, Span, TokenStream, TokenTree};
 use quote::quote;
 use syn::{spanned::Spanned, *};
 
-/// Used to filter out necessary field attribute and within error messages.
-static ARBITRARY_ATTRIBUTE_NAME: &str = "arbitrary";
-
 /// Determines how a value for a field should be constructed.
 #[cfg_attr(test, derive(Debug))]
 pub enum FieldConstructor {
diff --git a/src/lib.rs b/src/lib.rs
index 4ed3817..5e05522 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,9 +4,12 @@
 use quote::quote;
 use syn::*;
 
+mod container_attributes;
 mod field_attributes;
+use container_attributes::ContainerAttributes;
 use field_attributes::{determine_field_constructor, FieldConstructor};
 
+static ARBITRARY_ATTRIBUTE_NAME: &str = "arbitrary";
 static ARBITRARY_LIFETIME_NAME: &str = "'arbitrary";
 
 #[proc_macro_derive(Arbitrary, attributes(arbitrary))]
@@ -18,6 +21,8 @@
 }
 
 fn expand_derive_arbitrary(input: syn::DeriveInput) -> Result<TokenStream> {
+    let container_attrs = ContainerAttributes::from_derive_input(&input)?;
+
     let (lifetime_without_bounds, lifetime_with_bounds) =
         build_arbitrary_lifetime(input.generics.clone());
 
@@ -30,8 +35,13 @@
         gen_arbitrary_method(&input, lifetime_without_bounds.clone(), &recursive_count)?;
     let size_hint_method = gen_size_hint_method(&input)?;
     let name = input.ident;
-    // Add a bound `T: Arbitrary` to every type parameter T.
-    let generics = add_trait_bounds(input.generics, lifetime_without_bounds.clone());
+
+    // Apply user-supplied bounds or automatic `T: ArbitraryBounds`.
+    let generics = apply_trait_bounds(
+        input.generics,
+        lifetime_without_bounds.clone(),
+        &container_attrs,
+    )?;
 
     // Build ImplGeneric with a lifetime (https://github.com/dtolnay/syn/issues/90)
     let mut generics_with_lifetime = generics.clone();
@@ -77,6 +87,51 @@
     (lifetime_without_bounds, lifetime_with_bounds)
 }
 
+fn apply_trait_bounds(
+    mut generics: Generics,
+    lifetime: LifetimeDef,
+    container_attrs: &ContainerAttributes,
+) -> Result<Generics> {
+    // If user-supplied bounds exist, apply them to their matching type parameters.
+    if let Some(config_bounds) = &container_attrs.bounds {
+        let mut config_bounds_applied = 0;
+        for param in generics.params.iter_mut() {
+            if let GenericParam::Type(type_param) = param {
+                if let Some(replacement) = config_bounds
+                    .iter()
+                    .flatten()
+                    .find(|p| p.ident == type_param.ident)
+                {
+                    *type_param = replacement.clone();
+                    config_bounds_applied += 1;
+                } else {
+                    // If no user-supplied bounds exist for this type, delete the original bounds.
+                    // This mimics serde.
+                    type_param.bounds = Default::default();
+                    type_param.default = None;
+                }
+            }
+        }
+        let config_bounds_supplied = config_bounds
+            .iter()
+            .map(|bounds| bounds.len())
+            .sum::<usize>();
+        if config_bounds_applied != config_bounds_supplied {
+            return Err(Error::new(
+                Span::call_site(),
+                format!(
+                    "invalid `{}` attribute. too many bounds, only {} out of {} are applicable",
+                    ARBITRARY_ATTRIBUTE_NAME, config_bounds_applied, config_bounds_supplied,
+                ),
+            ));
+        }
+        Ok(generics)
+    } else {
+        // Otherwise, inject a `T: Arbitrary` bound for every parameter.
+        Ok(add_trait_bounds(generics, lifetime))
+    }
+}
+
 // Add a bound `T: Arbitrary` to every type parameter T.
 fn add_trait_bounds(mut generics: Generics, lifetime: LifetimeDef) -> Generics {
     for param in generics.params.iter_mut() {